drivers/net/ethernet/google/gve/gve_rx_dqo.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/google/gve/gve_rx_dqo.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/google/gve/gve_rx_dqo.c- Extension
.c- Size
- 29959 bytes
- Lines
- 1144
- 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_dqo.hgve_adminq.hgve_utils.hlinux/bpf.hlinux/ip.hlinux/ipv6.hlinux/skbuff.hlinux/slab.hnet/ip6_checksum.hnet/ipv6.hnet/tcp.hnet/xdp_sock_drv.h
Detected Declarations
function Copyrightfunction gve_rx_init_ring_state_dqofunction gve_rx_reset_ring_dqofunction gve_rx_stop_ring_dqofunction gve_rx_free_ring_dqofunction gve_rx_alloc_hdr_bufsfunction gve_rx_start_ring_dqofunction gve_rx_alloc_ring_dqofunction gve_rx_write_doorbell_dqofunction gve_rx_alloc_rings_dqofunction gve_rx_free_rings_dqofunction gve_rx_post_buffers_dqofunction gve_rx_skb_csumfunction gve_rx_skb_hashfunction gve_rx_get_hwtstampfunction gve_rx_skb_hwtstampfunction gve_xdp_rx_timestampfunction gve_rx_free_skbfunction gve_rx_should_trigger_copy_ondemandfunction gve_rx_copy_ondemandfunction gve_skb_add_rx_fragfunction gve_rx_append_fragsfunction gve_xdp_tx_dqofunction gve_xsk_done_dqofunction gve_xdp_done_dqofunction gve_rx_xsk_dqofunction gve_dma_syncfunction gve_rx_dqofunction netmem_is_net_iovfunction gve_rx_complete_rscfunction gve_rx_complete_skbfunction gve_rx_poll_dqo
Annotated Snippet
if (gve_buf_state_is_allocated(rx, bs) && bs->xsk_buff) {
xsk_buff_free(bs->xsk_buff);
bs->xsk_buff = NULL;
}
}
if (rx->dqo.qpl) {
qpl_id = gve_get_rx_qpl_id(cfg->qcfg_tx, rx->q_num);
gve_free_queue_page_list(priv, rx->dqo.qpl, qpl_id);
rx->dqo.qpl = NULL;
}
if (rx->dqo.bufq.desc_ring) {
size = sizeof(rx->dqo.bufq.desc_ring[0]) * buffer_queue_slots;
dma_free_coherent(hdev, size, rx->dqo.bufq.desc_ring,
rx->dqo.bufq.bus);
rx->dqo.bufq.desc_ring = NULL;
}
if (rx->dqo.complq.desc_ring) {
size = sizeof(rx->dqo.complq.desc_ring[0]) *
completion_queue_slots;
dma_free_coherent(hdev, size, rx->dqo.complq.desc_ring,
rx->dqo.complq.bus);
rx->dqo.complq.desc_ring = NULL;
}
kvfree(rx->dqo.buf_states);
rx->dqo.buf_states = NULL;
if (rx->dqo.page_pool) {
page_pool_destroy(rx->dqo.page_pool);
rx->dqo.page_pool = NULL;
}
gve_rx_free_hdr_bufs(priv, rx);
netif_dbg(priv, drv, priv->dev, "freed rx ring %d\n", idx);
}
static int gve_rx_alloc_hdr_bufs(struct gve_priv *priv, struct gve_rx_ring *rx,
const u32 buf_count)
{
struct device *hdev = &priv->pdev->dev;
rx->dqo.hdr_bufs.data = dma_alloc_coherent(hdev, priv->header_buf_size * buf_count,
&rx->dqo.hdr_bufs.addr, GFP_KERNEL);
if (!rx->dqo.hdr_bufs.data)
return -ENOMEM;
return 0;
}
void gve_rx_start_ring_dqo(struct gve_priv *priv, int idx)
{
int ntfy_idx = gve_rx_idx_to_ntfy(priv, idx);
gve_rx_add_to_block(priv, idx);
gve_add_napi(priv, ntfy_idx, gve_napi_poll_dqo);
}
int gve_rx_alloc_ring_dqo(struct gve_priv *priv,
struct gve_rx_alloc_rings_cfg *cfg,
struct gve_rx_ring *rx,
int idx)
{
struct device *hdev = &priv->pdev->dev;
struct page_pool *pool;
size_t size;
u32 qpl_id;
const u32 buffer_queue_slots = cfg->ring_size;
const u32 completion_queue_slots = cfg->ring_size;
netif_dbg(priv, drv, priv->dev, "allocating rx ring DQO\n");
memset(rx, 0, sizeof(*rx));
rx->gve = priv;
rx->q_num = idx;
rx->packet_buffer_size = cfg->packet_buffer_size;
if (cfg->xdp) {
rx->packet_buffer_truesize = GVE_XDP_RX_BUFFER_SIZE_DQO;
rx->rx_headroom = XDP_PACKET_HEADROOM;
} else {
rx->packet_buffer_truesize = rx->packet_buffer_size;
rx->rx_headroom = 0;
}
/* struct gve_xdp_buff is overlaid on struct xdp_buff_xsk and utilizes
Annotation
- Immediate include surface: `gve.h`, `gve_dqo.h`, `gve_adminq.h`, `gve_utils.h`, `linux/bpf.h`, `linux/ip.h`, `linux/ipv6.h`, `linux/skbuff.h`.
- Detected declarations: `function Copyright`, `function gve_rx_init_ring_state_dqo`, `function gve_rx_reset_ring_dqo`, `function gve_rx_stop_ring_dqo`, `function gve_rx_free_ring_dqo`, `function gve_rx_alloc_hdr_bufs`, `function gve_rx_start_ring_dqo`, `function gve_rx_alloc_ring_dqo`, `function gve_rx_write_doorbell_dqo`, `function gve_rx_alloc_rings_dqo`.
- 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.