drivers/infiniband/hw/hfi1/ipoib_tx.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/hfi1/ipoib_tx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/hw/hfi1/ipoib_tx.c- Extension
.c- Size
- 22826 bytes
- Lines
- 869
- 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/log2.hlinux/circ_buf.hsdma.hverbs.htrace_ibhdrs.hipoib.htrace_tx.h
Detected Declarations
struct ipoib_txparmsfunction hfi1_txreq_from_idxfunction hfi1_ipoib_txreqsfunction hfi1_ipoib_usedfunction hfi1_ipoib_stop_txqfunction hfi1_ipoib_wake_txqfunction hfi1_ipoib_ring_hwatfunction hfi1_ipoib_ring_lwatfunction hfi1_ipoib_check_queue_depthfunction hfi1_ipoib_check_queue_stoppedfunction atomic_xchgfunction hfi1_ipoib_free_txfunction hfi1_ipoib_drain_tx_ringfunction hfi1_ipoib_poll_tx_ringfunction hfi1_ipoib_sdma_completefunction hfi1_ipoib_build_ulp_payloadfunction hfi1_ipoib_build_tx_descfunction hfi1_ipoib_build_ib_tx_headersfunction hfi1_ipoib_submit_tx_listfunction hfi1_ipoib_flush_tx_listfunction hfi1_ipoib_submit_txfunction hfi1_ipoib_send_dma_singlefunction hfi1_ipoib_send_dma_listfunction hfi1_ipoib_calc_entropyfunction hfi1_ipoib_sendfunction sdma_send_txreqfunction hfi1_ipoib_sdma_wakeupfunction hfi1_ipoib_flush_txqfunction hfi1_ipoib_txreq_initfunction hfi1_ipoib_drain_tx_listfunction list_for_each_entry_safefunction hfi1_ipoib_txreq_deinitfunction hfi1_ipoib_napi_tx_enablefunction hfi1_ipoib_napi_tx_disablefunction hfi1_ipoib_tx_timeout
Annotated Snippet
struct ipoib_txparms {
struct hfi1_devdata *dd;
struct rdma_ah_attr *ah_attr;
struct hfi1_ibport *ibp;
struct hfi1_ipoib_txq *txq;
union hfi1_ipoib_flow flow;
u32 dqpn;
u8 hdr_dwords;
u8 entropy;
};
static struct ipoib_txreq *
hfi1_txreq_from_idx(struct hfi1_ipoib_circ_buf *r, u32 idx)
{
return (struct ipoib_txreq *)(r->items + (idx << r->shift));
}
static u32 hfi1_ipoib_txreqs(const u64 sent, const u64 completed)
{
return sent - completed;
}
static u64 hfi1_ipoib_used(struct hfi1_ipoib_txq *txq)
{
return hfi1_ipoib_txreqs(txq->tx_ring.sent_txreqs,
txq->tx_ring.complete_txreqs);
}
static void hfi1_ipoib_stop_txq(struct hfi1_ipoib_txq *txq)
{
trace_hfi1_txq_stop(txq);
if (atomic_inc_return(&txq->tx_ring.stops) == 1)
netif_stop_subqueue(txq->priv->netdev, txq->q_idx);
}
static void hfi1_ipoib_wake_txq(struct hfi1_ipoib_txq *txq)
{
trace_hfi1_txq_wake(txq);
if (atomic_dec_and_test(&txq->tx_ring.stops))
netif_wake_subqueue(txq->priv->netdev, txq->q_idx);
}
static uint hfi1_ipoib_ring_hwat(struct hfi1_ipoib_txq *txq)
{
return min_t(uint, txq->priv->netdev->tx_queue_len,
txq->tx_ring.max_items - 1);
}
static uint hfi1_ipoib_ring_lwat(struct hfi1_ipoib_txq *txq)
{
return min_t(uint, txq->priv->netdev->tx_queue_len,
txq->tx_ring.max_items) >> 1;
}
static void hfi1_ipoib_check_queue_depth(struct hfi1_ipoib_txq *txq)
{
++txq->tx_ring.sent_txreqs;
if (hfi1_ipoib_used(txq) >= hfi1_ipoib_ring_hwat(txq) &&
!atomic_xchg(&txq->tx_ring.ring_full, 1)) {
trace_hfi1_txq_full(txq);
hfi1_ipoib_stop_txq(txq);
}
}
static void hfi1_ipoib_check_queue_stopped(struct hfi1_ipoib_txq *txq)
{
struct net_device *dev = txq->priv->netdev;
/* If shutting down just return as queue state is irrelevant */
if (unlikely(dev->reg_state != NETREG_REGISTERED))
return;
/*
* When the queue has been drained to less than half full it will be
* restarted.
* The size of the txreq ring is fixed at initialization.
* The tx queue len can be adjusted upward while the interface is
* running.
* The tx queue len can be large enough to overflow the txreq_ring.
* Use the minimum of the current tx_queue_len or the rings max txreqs
* to protect against ring overflow.
*/
if (hfi1_ipoib_used(txq) < hfi1_ipoib_ring_lwat(txq) &&
atomic_xchg(&txq->tx_ring.ring_full, 0)) {
trace_hfi1_txq_xmit_unstopped(txq);
hfi1_ipoib_wake_txq(txq);
}
}
static void hfi1_ipoib_free_tx(struct ipoib_txreq *tx, int budget)
Annotation
- Immediate include surface: `linux/log2.h`, `linux/circ_buf.h`, `sdma.h`, `verbs.h`, `trace_ibhdrs.h`, `ipoib.h`, `trace_tx.h`.
- Detected declarations: `struct ipoib_txparms`, `function hfi1_txreq_from_idx`, `function hfi1_ipoib_txreqs`, `function hfi1_ipoib_used`, `function hfi1_ipoib_stop_txq`, `function hfi1_ipoib_wake_txq`, `function hfi1_ipoib_ring_hwat`, `function hfi1_ipoib_ring_lwat`, `function hfi1_ipoib_check_queue_depth`, `function hfi1_ipoib_check_queue_stopped`.
- 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.