drivers/infiniband/hw/hfi1/ud.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/hfi1/ud.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/hw/hfi1/ud.c- Extension
.c- Size
- 28695 bytes
- Lines
- 1024
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/net.hrdma/ib_smi.hhfi.hmad.hverbs_txreq.htrace_ibhdrs.hqp.h
Detected Declarations
function hfi1_make_ud_reqfunction matchesfunction hfi1_make_bth_dethfunction hfi1_make_ud_req_9Bfunction hfi1_make_ud_req_16Bfunction hfi1_make_ud_reqfunction hfi1_lookup_pkey_idxfunction return_cnp_16Bfunction return_cnpfunction opa_smp_checkfunction knowfunction fourfunction qp_rcvfunction matches
Annotated Snippet
if (ret < 0) {
rvt_rc_error(qp, IB_WC_LOC_QP_OP_ERR);
goto bail_unlock;
}
if (!ret) {
if (qp->ibqp.qp_num == 0)
ibp->rvp.n_vl15_dropped++;
goto bail_unlock;
}
}
/* Silently drop packets which are too big. */
if (unlikely(wc.byte_len > qp->r_len)) {
qp->r_flags |= RVT_R_REUSE_SGE;
ibp->rvp.n_pkt_drops++;
goto bail_unlock;
}
if (rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH) {
struct ib_grh grh;
struct ib_global_route grd = *(rdma_ah_read_grh(ah_attr));
/*
* For loopback packets with extended LIDs, the
* sgid_index in the GRH is 0 and the dgid is
* OPA GID of the sender. While creating a response
* to the loopback packet, IB core creates the new
* sgid_index from the DGID and that will be the
* OPA_GID_INDEX. The new dgid is from the sgid
* index and that will be in the IB GID format.
*
* We now have a case where the sent packet had a
* different sgid_index and dgid compared to the
* one that was received in response.
*
* Fix this inconsistency.
*/
if (priv->hdr_type == HFI1_PKT_TYPE_16B) {
if (grd.sgid_index == 0)
grd.sgid_index = OPA_GID_INDEX;
if (ib_is_opa_gid(&grd.dgid))
grd.dgid.global.interface_id =
cpu_to_be64(ppd->guids[HFI1_PORT_GUID_INDEX]);
}
hfi1_make_grh(ibp, &grh, &grd, 0, 0);
rvt_copy_sge(qp, &qp->r_sge, &grh,
sizeof(grh), true, false);
wc.wc_flags |= IB_WC_GRH;
} else {
rvt_skip_sge(&qp->r_sge, sizeof(struct ib_grh), true);
}
ssge.sg_list = swqe->sg_list + 1;
ssge.sge = *swqe->sg_list;
ssge.num_sge = swqe->wr.num_sge;
sge = &ssge.sge;
while (length) {
u32 len = rvt_get_sge_length(sge, length);
WARN_ON_ONCE(len == 0);
rvt_copy_sge(qp, &qp->r_sge, sge->vaddr, len, true, false);
rvt_update_sge(&ssge, len, false);
length -= len;
}
rvt_put_ss(&qp->r_sge);
if (!test_and_clear_bit(RVT_R_WRID_VALID, &qp->r_aflags))
goto bail_unlock;
wc.wr_id = qp->r_wr_id;
wc.status = IB_WC_SUCCESS;
wc.opcode = IB_WC_RECV;
wc.qp = &qp->ibqp;
wc.src_qp = sqp->ibqp.qp_num;
if (qp->ibqp.qp_type == IB_QPT_GSI || qp->ibqp.qp_type == IB_QPT_SMI) {
if (sqp->ibqp.qp_type == IB_QPT_GSI ||
sqp->ibqp.qp_type == IB_QPT_SMI)
wc.pkey_index = rvt_get_swqe_pkey_index(swqe);
else
wc.pkey_index = sqp->s_pkey_index;
} else {
wc.pkey_index = 0;
}
wc.slid = (ppd->lid | (rdma_ah_get_path_bits(ah_attr) &
((1 << ppd->lmc) - 1))) & U16_MAX;
/* Check for loopback when the port lid is not set */
if (wc.slid == 0 && sqp->ibqp.qp_type == IB_QPT_GSI)
wc.slid = be16_to_cpu(IB_LID_PERMISSIVE);
wc.sl = rdma_ah_get_sl(ah_attr);
wc.dlid_path_bits = rdma_ah_get_dlid(ah_attr) & ((1 << ppd->lmc) - 1);
wc.port_num = qp->port_num;
/* Signal completion event if the solicited bit is set. */
Annotation
- Immediate include surface: `linux/net.h`, `rdma/ib_smi.h`, `hfi.h`, `mad.h`, `verbs_txreq.h`, `trace_ibhdrs.h`, `qp.h`.
- Detected declarations: `function hfi1_make_ud_req`, `function matches`, `function hfi1_make_bth_deth`, `function hfi1_make_ud_req_9B`, `function hfi1_make_ud_req_16B`, `function hfi1_make_ud_req`, `function hfi1_lookup_pkey_idx`, `function return_cnp_16B`, `function return_cnp`, `function opa_smp_check`.
- 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.