drivers/net/ethernet/google/gve/gve_rx.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/google/gve/gve_rx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/google/gve/gve_rx.c- Extension
.c- Size
- 28709 bytes
- Lines
- 1095
- 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/etherdevice.hlinux/filter.hnet/xdp.hnet/xdp_sock_drv.h
Detected Declarations
function Copyrightfunction gve_rx_unfill_pagesfunction gve_rx_ctx_clearfunction gve_rx_init_ring_state_gqifunction gve_rx_reset_ring_gqifunction gve_rx_stop_ring_gqifunction gve_rx_free_ring_gqifunction gve_setup_rx_bufferfunction gve_rx_alloc_bufferfunction gve_rx_prefill_pagesfunction gve_rx_start_ring_gqifunction gve_rx_alloc_ring_gqifunction gve_rx_alloc_rings_gqifunction gve_rx_free_rings_gqifunction gve_rx_write_doorbellfunction gve_rss_typefunction gve_rx_flip_bufffunction gve_rx_can_recycle_bufferfunction gve_rx_raw_addressingfunction gve_rx_qplfunction gve_xsk_pool_redirectfunction gve_xdp_redirectfunction gve_xdp_donefunction gve_rxfunction gve_rx_work_pendingfunction gve_rx_refill_buffersfunction gve_clean_rx_donefunction gve_rx_poll
Annotated Snippet
if (!rx->data.raw_addressing) {
struct page *page = rx->data.qpl->pages[i];
dma_addr_t addr = i * PAGE_SIZE;
gve_setup_rx_buffer(rx, &rx->data.page_info[i], addr,
page,
&rx->data.data_ring[i].qpl_offset);
continue;
}
err = gve_rx_alloc_buffer(priv, &priv->pdev->dev,
&rx->data.page_info[i],
&rx->data.data_ring[i], rx);
if (err)
goto alloc_err_rda;
}
if (!rx->data.raw_addressing) {
for (j = 0; j < rx->qpl_copy_pool_mask + 1; j++) {
struct page *page = alloc_pages_node(priv->numa_node,
GFP_KERNEL, 0);
if (!page) {
err = -ENOMEM;
goto alloc_err_qpl;
}
rx->qpl_copy_pool[j].page = page;
rx->qpl_copy_pool[j].page_offset = 0;
rx->qpl_copy_pool[j].page_address = page_address(page);
rx->qpl_copy_pool[j].buf_size = rx->packet_buffer_size;
/* The page already has 1 ref. */
page_ref_add(page, INT_MAX - 1);
rx->qpl_copy_pool[j].pagecnt_bias = INT_MAX;
}
}
return slots;
alloc_err_qpl:
/* Fully free the copy pool pages. */
while (j--) {
page_ref_sub(rx->qpl_copy_pool[j].page,
rx->qpl_copy_pool[j].pagecnt_bias - 1);
put_page(rx->qpl_copy_pool[j].page);
}
/* Do not fully free QPL pages - only remove the bias added in this
* function with gve_setup_rx_buffer.
*/
while (i--)
page_ref_sub(rx->data.page_info[i].page,
rx->data.page_info[i].pagecnt_bias - 1);
return err;
alloc_err_rda:
while (i--)
gve_rx_free_buffer(&priv->pdev->dev,
&rx->data.page_info[i],
&rx->data.data_ring[i]);
return err;
}
void gve_rx_start_ring_gqi(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);
}
int gve_rx_alloc_ring_gqi(struct gve_priv *priv,
struct gve_rx_alloc_rings_cfg *cfg,
struct gve_rx_ring *rx,
int idx)
{
struct device *hdev = &priv->pdev->dev;
u32 slots = cfg->ring_size;
int filled_pages;
u32 qpl_id = 0;
size_t bytes;
int err;
netif_dbg(priv, drv, priv->dev, "allocating rx ring\n");
/* Make sure everything is zeroed to start with */
memset(rx, 0, sizeof(*rx));
rx->gve = priv;
rx->q_num = idx;
Annotation
- Immediate include surface: `gve.h`, `gve_adminq.h`, `gve_utils.h`, `linux/etherdevice.h`, `linux/filter.h`, `net/xdp.h`, `net/xdp_sock_drv.h`.
- Detected declarations: `function Copyright`, `function gve_rx_unfill_pages`, `function gve_rx_ctx_clear`, `function gve_rx_init_ring_state_gqi`, `function gve_rx_reset_ring_gqi`, `function gve_rx_stop_ring_gqi`, `function gve_rx_free_ring_gqi`, `function gve_setup_rx_buffer`, `function gve_rx_alloc_buffer`, `function gve_rx_prefill_pages`.
- 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.