drivers/infiniband/ulp/ipoib/ipoib_cm.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/ulp/ipoib/ipoib_cm.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/ulp/ipoib/ipoib_cm.c- Extension
.c- Size
- 44349 bytes
- Lines
- 1662
- 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
rdma/ib_cm.hnet/dst.hnet/icmp.hlinux/icmpv6.hlinux/delay.hlinux/slab.hlinux/vmalloc.hlinux/moduleparam.hlinux/sched/signal.hlinux/sched/mm.hipoib.h
Detected Declarations
function ipoib_cm_dma_unmap_rxfunction ipoib_cm_post_receive_srqfunction ipoib_cm_post_receive_nonsrqfunction ipoib_cm_free_rx_ringfunction ipoib_cm_start_rx_drainfunction ipoib_cm_rx_event_handlerfunction ipoib_cm_modify_rx_qpfunction ipoib_cm_init_rx_wrfunction ipoib_cm_nonsrq_init_rxfunction ipoib_cm_send_repfunction ipoib_cm_req_handlerfunction ipoib_cm_rx_handlerfunction skb_put_fragsfunction ipoib_cm_handle_rx_wcfunction post_sendfunction ipoib_cm_sendfunction ipoib_cm_handle_tx_wcfunction ipoib_cm_dev_openfunction ipoib_cm_free_rx_reap_listfunction list_for_each_entry_safefunction ipoib_cm_dev_stopfunction ipoib_cm_rep_handlerfunction ipoib_cm_send_reqfunction ipoib_cm_modify_tx_initfunction ipoib_cm_tx_initfunction ipoib_cm_tx_destroyfunction ipoib_cm_tx_handlerfunction ipoib_cm_destroy_txfunction ipoib_cm_tx_startfunction ipoib_cm_tx_reapfunction ipoib_cm_skb_reapfunction ipoib_cm_skb_too_longfunction ipoib_cm_rx_reapfunction ipoib_cm_stale_taskfunction mode_showfunction mode_storefunction ipoib_cm_add_mode_attrfunction ipoib_cm_create_srqfunction ipoib_cm_dev_initfunction ipoib_cm_dev_cleanup
Annotated Snippet
if (rx_ring[i].skb) {
ipoib_cm_dma_unmap_rx(priv, IPOIB_CM_RX_SG - 1,
rx_ring[i].mapping);
dev_kfree_skb_any(rx_ring[i].skb);
}
vfree(rx_ring);
}
static void ipoib_cm_start_rx_drain(struct ipoib_dev_priv *priv)
{
struct ipoib_cm_rx *p;
/* We only reserved 1 extra slot in CQ for drain WRs, so
* make sure we have at most 1 outstanding WR. */
if (list_empty(&priv->cm.rx_flush_list) ||
!list_empty(&priv->cm.rx_drain_list))
return;
/*
* QPs on flush list are error state. This way, a "flush
* error" WC will be immediately generated for each WR we post.
*/
p = list_entry(priv->cm.rx_flush_list.next, typeof(*p), list);
ipoib_cm_rx_drain_wr.wr_id = IPOIB_CM_RX_DRAIN_WRID;
if (ib_post_send(p->qp, &ipoib_cm_rx_drain_wr, NULL))
ipoib_warn(priv, "failed to post drain wr\n");
list_splice_init(&priv->cm.rx_flush_list, &priv->cm.rx_drain_list);
}
static void ipoib_cm_rx_event_handler(struct ib_event *event, void *ctx)
{
struct ipoib_cm_rx *p = ctx;
struct ipoib_dev_priv *priv = ipoib_priv(p->dev);
unsigned long flags;
if (event->event != IB_EVENT_QP_LAST_WQE_REACHED)
return;
spin_lock_irqsave(&priv->lock, flags);
list_move(&p->list, &priv->cm.rx_flush_list);
p->state = IPOIB_CM_RX_FLUSH;
ipoib_cm_start_rx_drain(priv);
spin_unlock_irqrestore(&priv->lock, flags);
}
static struct ib_qp *ipoib_cm_create_rx_qp(struct net_device *dev,
struct ipoib_cm_rx *p)
{
struct ipoib_dev_priv *priv = ipoib_priv(dev);
struct ib_qp_init_attr attr = {
.event_handler = ipoib_cm_rx_event_handler,
.send_cq = priv->recv_cq, /* For drain WR */
.recv_cq = priv->recv_cq,
.srq = priv->cm.srq,
.cap.max_send_wr = 1, /* For drain WR */
.cap.max_send_sge = 1, /* FIXME: 0 Seems not to work */
.sq_sig_type = IB_SIGNAL_ALL_WR,
.qp_type = IB_QPT_RC,
.qp_context = p,
};
if (!ipoib_cm_has_srq(dev)) {
attr.cap.max_recv_wr = ipoib_recvq_size;
attr.cap.max_recv_sge = IPOIB_CM_RX_SG;
}
return ib_create_qp(priv->pd, &attr);
}
static int ipoib_cm_modify_rx_qp(struct net_device *dev,
struct ib_cm_id *cm_id, struct ib_qp *qp,
unsigned int psn)
{
struct ipoib_dev_priv *priv = ipoib_priv(dev);
struct ib_qp_attr qp_attr;
int qp_attr_mask, ret;
qp_attr.qp_state = IB_QPS_INIT;
ret = ib_cm_init_qp_attr(cm_id, &qp_attr, &qp_attr_mask);
if (ret) {
ipoib_warn(priv, "failed to init QP attr for INIT: %d\n", ret);
return ret;
}
ret = ib_modify_qp(qp, &qp_attr, qp_attr_mask);
if (ret) {
ipoib_warn(priv, "failed to modify QP to INIT: %d\n", ret);
return ret;
}
Annotation
- Immediate include surface: `rdma/ib_cm.h`, `net/dst.h`, `net/icmp.h`, `linux/icmpv6.h`, `linux/delay.h`, `linux/slab.h`, `linux/vmalloc.h`, `linux/moduleparam.h`.
- Detected declarations: `function ipoib_cm_dma_unmap_rx`, `function ipoib_cm_post_receive_srq`, `function ipoib_cm_post_receive_nonsrq`, `function ipoib_cm_free_rx_ring`, `function ipoib_cm_start_rx_drain`, `function ipoib_cm_rx_event_handler`, `function ipoib_cm_modify_rx_qp`, `function ipoib_cm_init_rx_wr`, `function ipoib_cm_nonsrq_init_rx`, `function ipoib_cm_send_rep`.
- 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.