drivers/infiniband/ulp/ipoib/ipoib_ib.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/ulp/ipoib/ipoib_ib.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/ulp/ipoib/ipoib_ib.c- Extension
.c- Size
- 35430 bytes
- Lines
- 1357
- Domain
- Driver Families
- Bucket
- drivers/infiniband
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/delay.hlinux/moduleparam.hlinux/dma-mapping.hlinux/slab.hlinux/ip.hlinux/tcp.hnet/netdev_lock.hrdma/ib_cache.hipoib.h
Detected Declarations
function ipoib_free_ahfunction ipoib_ud_dma_unmap_rxfunction ipoib_ib_post_receivefunction ipoib_ib_post_receivesfunction ipoib_ib_handle_rx_wcfunction ipoib_dma_map_txfunction ipoib_dma_unmap_txfunction thefunction ipoib_ib_handle_tx_wcfunction poll_txfunction ipoib_rx_pollfunction ipoib_tx_pollfunction ipoib_ib_rx_completionfunction ipoib_napi_schedule_workfunction ipoib_ib_tx_completionfunction post_sendfunction ipoib_sendfunction ipoib_reap_dead_ahsfunction list_for_each_entry_safefunction ipoib_reap_ahfunction ipoib_start_ah_reaperfunction ipoib_stop_ah_reaperfunction ipoib_stop_ah_reaperfunction check_qp_movement_and_printfunction ipoib_napi_enablefunction ipoib_napi_disablefunction ipoib_ib_dev_stop_defaultfunction ipoib_ib_dev_open_defaultfunction ipoib_ib_dev_openfunction ipoib_ib_dev_stopfunction ipoib_pkey_dev_check_presencefunction ipoib_ib_dev_upfunction ipoib_ib_dev_downfunction ipoib_drain_cqfunction update_parent_pkeyfunction update_child_pkeyfunction onefunction __ipoib_ib_dev_flushfunction ipoib_ib_dev_flush_lightfunction ipoib_ib_dev_flush_normalfunction ipoib_ib_dev_flush_heavyfunction ipoib_queue_workfunction ipoib_ib_dev_cleanup
Annotated Snippet
if (!ipoib_alloc_rx_skb(dev, i)) {
ipoib_warn(priv, "failed to allocate receive buffer %d\n", i);
return -ENOMEM;
}
if (ipoib_ib_post_receive(dev, i)) {
ipoib_warn(priv, "ipoib_ib_post_receive failed for buf %d\n", i);
return -EIO;
}
}
return 0;
}
static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
{
struct ipoib_dev_priv *priv = ipoib_priv(dev);
unsigned int wr_id = wc->wr_id & ~IPOIB_OP_RECV;
struct sk_buff *skb;
u64 mapping[IPOIB_UD_RX_SG];
union ib_gid *dgid;
union ib_gid *sgid;
ipoib_dbg_data(priv, "recv completion: id %d, status: %d\n",
wr_id, wc->status);
if (unlikely(wr_id >= ipoib_recvq_size)) {
ipoib_warn(priv, "recv completion event with wrid %d (> %d)\n",
wr_id, ipoib_recvq_size);
return;
}
skb = priv->rx_ring[wr_id].skb;
if (unlikely(wc->status != IB_WC_SUCCESS)) {
if (wc->status != IB_WC_WR_FLUSH_ERR)
ipoib_warn(priv,
"failed recv event (status=%d, wrid=%d vend_err %#x)\n",
wc->status, wr_id, wc->vendor_err);
ipoib_ud_dma_unmap_rx(priv, priv->rx_ring[wr_id].mapping);
dev_kfree_skb_any(skb);
priv->rx_ring[wr_id].skb = NULL;
return;
}
memcpy(mapping, priv->rx_ring[wr_id].mapping,
IPOIB_UD_RX_SG * sizeof(*mapping));
/*
* If we can't allocate a new RX buffer, dump
* this packet and reuse the old buffer.
*/
if (unlikely(!ipoib_alloc_rx_skb(dev, wr_id))) {
++dev->stats.rx_dropped;
goto repost;
}
ipoib_dbg_data(priv, "received %d bytes, SLID 0x%04x\n",
wc->byte_len, wc->slid);
ipoib_ud_dma_unmap_rx(priv, mapping);
skb_put(skb, wc->byte_len);
/* First byte of dgid signals multicast when 0xff */
dgid = &((struct ib_grh *)skb->data)->dgid;
if (!(wc->wc_flags & IB_WC_GRH) || dgid->raw[0] != 0xff)
skb->pkt_type = PACKET_HOST;
else if (memcmp(dgid, dev->broadcast + 4, sizeof(union ib_gid)) == 0)
skb->pkt_type = PACKET_BROADCAST;
else
skb->pkt_type = PACKET_MULTICAST;
sgid = &((struct ib_grh *)skb->data)->sgid;
/*
* Drop packets that this interface sent, ie multicast packets
* that the HCA has replicated.
*/
if (wc->slid == priv->local_lid && wc->src_qp == priv->qp->qp_num) {
int need_repost = 1;
if ((wc->wc_flags & IB_WC_GRH) &&
sgid->global.interface_id != priv->local_gid.global.interface_id)
need_repost = 0;
if (need_repost) {
dev_kfree_skb_any(skb);
goto repost;
}
Annotation
- Immediate include surface: `linux/delay.h`, `linux/moduleparam.h`, `linux/dma-mapping.h`, `linux/slab.h`, `linux/ip.h`, `linux/tcp.h`, `net/netdev_lock.h`, `rdma/ib_cache.h`.
- Detected declarations: `function ipoib_free_ah`, `function ipoib_ud_dma_unmap_rx`, `function ipoib_ib_post_receive`, `function ipoib_ib_post_receives`, `function ipoib_ib_handle_rx_wc`, `function ipoib_dma_map_tx`, `function ipoib_dma_unmap_tx`, `function the`, `function ipoib_ib_handle_tx_wc`, `function poll_tx`.
- Atlas domain: Driver Families / drivers/infiniband.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.