drivers/net/ethernet/google/gve/gve_tx.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/google/gve/gve_tx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/google/gve/gve_tx.c- Extension
.c- Size
- 28134 bytes
- Lines
- 1039
- Domain
- Driver Families
- Bucket
- drivers/net
- 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
gve.hgve_adminq.hgve_utils.hlinux/ip.hlinux/tcp.hlinux/vmalloc.hlinux/skbuff.hnet/xdp_sock_drv.h
Detected Declarations
function Copyrightfunction gve_xdp_tx_flushfunction gve_tx_fifo_initfunction gve_tx_fifo_releasefunction gve_tx_fifo_pad_alloc_one_fragfunction gve_tx_fifo_can_allocfunction gve_tx_alloc_fifofunction gve_tx_free_fifofunction gve_tx_clear_buffer_statefunction gve_clean_xdp_donefunction gve_tx_stop_ring_gqifunction gve_tx_free_ring_gqifunction gve_tx_start_ring_gqifunction gve_tx_alloc_ring_gqifunction gve_tx_alloc_rings_gqifunction gve_tx_free_rings_gqifunction gve_tx_availfunction gve_skb_fifo_bytes_requiredfunction gve_tx_unmap_buffunction gve_can_txfunction gve_maybe_stop_txfunction gve_tx_fill_pkt_descfunction gve_tx_fill_mtd_descfunction gve_tx_fill_seg_descfunction gve_dma_sync_for_devicefunction gve_tx_add_skb_copyfunction gve_tx_add_skb_no_copyfunction gve_txfunction gve_tx_fill_xdpfunction gve_xdp_xmit_gqifunction gve_xdp_xmit_onefunction gve_clean_tx_donefunction likelyfunction gve_tx_load_event_counterfunction gve_xsk_txfunction gve_xsk_tx_pollfunction gve_xdp_pollfunction gve_tx_pollfunction gve_tx_clean_pending
Annotated Snippet
if (info->xdp_frame) {
xdp_return_frame(info->xdp_frame);
info->xdp_frame = NULL;
}
space_freed += gve_tx_clear_buffer_state(info);
}
gve_tx_free_fifo(&tx->tx_fifo, space_freed);
if (xsk_complete > 0 && tx->xsk_pool)
xsk_tx_completed(tx->xsk_pool, xsk_complete);
u64_stats_update_begin(&tx->statss);
tx->bytes_done += bytes;
tx->pkt_done += pkts;
u64_stats_update_end(&tx->statss);
return pkts;
}
static int gve_clean_tx_done(struct gve_priv *priv, struct gve_tx_ring *tx,
u32 to_do, bool try_to_wake);
void gve_tx_stop_ring_gqi(struct gve_priv *priv, int idx)
{
int ntfy_idx = gve_tx_idx_to_ntfy(priv, idx);
struct gve_tx_ring *tx = &priv->tx[idx];
if (!gve_tx_was_added_to_block(priv, idx))
return;
gve_remove_napi(priv, ntfy_idx);
if (tx->q_num < priv->tx_cfg.num_queues)
gve_clean_tx_done(priv, tx, priv->tx_desc_cnt, false);
else
gve_clean_xdp_done(priv, tx, priv->tx_desc_cnt);
netdev_tx_reset_queue(tx->netdev_txq);
gve_tx_remove_from_block(priv, idx);
}
static void gve_tx_free_ring_gqi(struct gve_priv *priv, struct gve_tx_ring *tx,
struct gve_tx_alloc_rings_cfg *cfg)
{
struct device *hdev = &priv->pdev->dev;
int idx = tx->q_num;
size_t bytes;
u32 qpl_id;
u32 slots;
slots = tx->mask + 1;
dma_free_coherent(hdev, sizeof(*tx->q_resources),
tx->q_resources, tx->q_resources_bus);
tx->q_resources = NULL;
if (tx->tx_fifo.qpl) {
if (tx->tx_fifo.base)
gve_tx_fifo_release(priv, &tx->tx_fifo);
qpl_id = gve_tx_qpl_id(priv, tx->q_num);
gve_free_queue_page_list(priv, tx->tx_fifo.qpl, qpl_id);
tx->tx_fifo.qpl = NULL;
}
bytes = sizeof(*tx->desc) * slots;
dma_free_coherent(hdev, bytes, tx->desc, tx->bus);
tx->desc = NULL;
vfree(tx->info);
tx->info = NULL;
netif_dbg(priv, drv, priv->dev, "freed tx queue %d\n", idx);
}
void gve_tx_start_ring_gqi(struct gve_priv *priv, int idx)
{
int ntfy_idx = gve_tx_idx_to_ntfy(priv, idx);
struct gve_tx_ring *tx = &priv->tx[idx];
gve_tx_add_to_block(priv, idx);
tx->netdev_txq = netdev_get_tx_queue(priv->dev, idx);
gve_add_napi(priv, ntfy_idx, gve_napi_poll);
}
static int gve_tx_alloc_ring_gqi(struct gve_priv *priv,
struct gve_tx_alloc_rings_cfg *cfg,
struct gve_tx_ring *tx,
int idx)
{
struct device *hdev = &priv->pdev->dev;
u32 qpl_id = 0;
size_t bytes;
Annotation
- Immediate include surface: `gve.h`, `gve_adminq.h`, `gve_utils.h`, `linux/ip.h`, `linux/tcp.h`, `linux/vmalloc.h`, `linux/skbuff.h`, `net/xdp_sock_drv.h`.
- Detected declarations: `function Copyright`, `function gve_xdp_tx_flush`, `function gve_tx_fifo_init`, `function gve_tx_fifo_release`, `function gve_tx_fifo_pad_alloc_one_frag`, `function gve_tx_fifo_can_alloc`, `function gve_tx_alloc_fifo`, `function gve_tx_free_fifo`, `function gve_tx_clear_buffer_state`, `function gve_clean_xdp_done`.
- Atlas domain: Driver Families / drivers/net.
- 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.