drivers/infiniband/hw/hfi1/qp.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/hfi1/qp.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/hw/hfi1/qp.c- Extension
.c- Size
- 23838 bytes
- Lines
- 925
- 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.
- 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/err.hlinux/vmalloc.hlinux/hash.hlinux/module.hlinux/seq_file.hrdma/rdma_vt.hrdma/rdmavt_qp.hrdma/ib_verbs.hhfi.hqp.htrace.hverbs_txreq.h
Detected Declarations
function flush_list_headfunction flush_tx_listfunction flush_iowaitfunction verbs_mtu_enum_to_intfunction hfi1_check_modify_qpfunction qp_set_16bfunction hfi1_modify_qpfunction hfi1_setup_wqefunction _hfi1_schedule_sendfunction qp_pio_drainfunction hfi1_schedule_sendfunction hfi1_qp_schedulefunction hfi1_qp_wakeupfunction hfi1_qp_unbusyfunction hfi1_verbs_sendfunction iowait_sleepfunction iowait_wakeupfunction iowait_sdma_drainedfunction hfi1_init_priorityfunction qp_idlefunction qp_iter_printfunction qp_priv_freefunction free_all_qpsfunction flush_qp_waitersfunction stop_send_queuefunction quiesce_qpfunction notify_qp_resetfunction hfi1_migrate_qpfunction mtu_to_path_mtufunction mtu_from_qpfunction get_pmtu_from_attrfunction notify_error_qpfunction hfi1_qp_iter_cbfunction hfi1_error_port_qps
Annotated Snippet
if (priv->s_flags & HFI1_S_TID_BUSY_SET) {
priv->s_flags &= ~(HFI1_S_TID_BUSY_SET |
RVT_S_BUSY);
iowait_set_flag(&priv->s_iowait, IOWAIT_PENDING_TID);
}
} else {
priv->s_flags &= ~RVT_S_BUSY;
}
}
static int iowait_sleep(
struct sdma_engine *sde,
struct iowait_work *wait,
struct sdma_txreq *stx,
uint seq,
bool pkts_sent)
{
struct verbs_txreq *tx = container_of(stx, struct verbs_txreq, txreq);
struct rvt_qp *qp;
struct hfi1_qp_priv *priv;
unsigned long flags;
int ret = 0;
qp = tx->qp;
priv = qp->priv;
spin_lock_irqsave(&qp->s_lock, flags);
if (ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK) {
/*
* If we couldn't queue the DMA request, save the info
* and try again later rather than destroying the
* buffer and undoing the side effects of the copy.
*/
/* Make a common routine? */
list_add_tail(&stx->list, &wait->tx_head);
write_seqlock(&sde->waitlock);
if (sdma_progress(sde, seq, stx))
goto eagain;
if (list_empty(&priv->s_iowait.list)) {
struct hfi1_ibport *ibp =
to_iport(qp->ibqp.device, qp->port_num);
ibp->rvp.n_dmawait++;
qp->s_flags |= RVT_S_WAIT_DMA_DESC;
iowait_get_priority(&priv->s_iowait);
iowait_queue(pkts_sent, &priv->s_iowait,
&sde->dmawait);
priv->s_iowait.lock = &sde->waitlock;
trace_hfi1_qpsleep(qp, RVT_S_WAIT_DMA_DESC);
rvt_get_qp(qp);
}
write_sequnlock(&sde->waitlock);
hfi1_qp_unbusy(qp, wait);
spin_unlock_irqrestore(&qp->s_lock, flags);
ret = -EBUSY;
} else {
spin_unlock_irqrestore(&qp->s_lock, flags);
hfi1_put_txreq(tx);
}
return ret;
eagain:
write_sequnlock(&sde->waitlock);
spin_unlock_irqrestore(&qp->s_lock, flags);
list_del_init(&stx->list);
return -EAGAIN;
}
static void iowait_wakeup(struct iowait *wait, int reason)
{
struct rvt_qp *qp = iowait_to_qp(wait);
WARN_ON(reason != SDMA_AVAIL_REASON);
hfi1_qp_wakeup(qp, RVT_S_WAIT_DMA_DESC);
}
static void iowait_sdma_drained(struct iowait *wait)
{
struct rvt_qp *qp = iowait_to_qp(wait);
unsigned long flags;
/*
* This happens when the send engine notes
* a QP in the error state and cannot
* do the flush work until that QP's
* sdma work has finished.
*/
spin_lock_irqsave(&qp->s_lock, flags);
if (qp->s_flags & RVT_S_WAIT_DMA) {
qp->s_flags &= ~RVT_S_WAIT_DMA;
hfi1_schedule_send(qp);
Annotation
- Immediate include surface: `linux/err.h`, `linux/vmalloc.h`, `linux/hash.h`, `linux/module.h`, `linux/seq_file.h`, `rdma/rdma_vt.h`, `rdma/rdmavt_qp.h`, `rdma/ib_verbs.h`.
- Detected declarations: `function flush_list_head`, `function flush_tx_list`, `function flush_iowait`, `function verbs_mtu_enum_to_int`, `function hfi1_check_modify_qp`, `function qp_set_16b`, `function hfi1_modify_qp`, `function hfi1_setup_wqe`, `function _hfi1_schedule_send`, `function qp_pio_drain`.
- 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.
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.