net/core/xdp.c
Source file repositories/reference/linux-study-clean/net/core/xdp.c
File Facts
- System
- Linux kernel
- Corpus path
net/core/xdp.c- Extension
.c- Size
- 27958 bytes
- Lines
- 1056
- Domain
- Networking Core
- Bucket
- Sockets, Protocols, Packet Path, And Network Policy
- Inferred role
- Networking Core: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/bpf.hlinux/btf.hlinux/btf_ids.hlinux/filter.hlinux/types.hlinux/mm.hlinux/netdevice.hlinux/slab.hlinux/idr.hlinux/rhashtable.hlinux/bug.hnet/page_pool/helpers.hnet/hotdata.hnet/netdev_lock.hnet/xdp.hnet/xdp_priv.htrace/events/xdp.hnet/xdp_sock_drv.h
Detected Declarations
function xdp_mem_id_hashfnfunction xdp_mem_id_cmpfunction __xdp_mem_allocator_rcu_freefunction mem_xa_removefunction mem_allocator_disconnectfunction xdp_unreg_mem_modelfunction xdp_rxq_info_unreg_mem_modelfunction xdp_rxq_info_unregfunction xdp_rxq_info_initfunction __xdp_rxq_info_regfunction xdp_rxq_info_unusedfunction xdp_rxq_info_is_regfunction __mem_id_init_hash_tablefunction __mem_id_cyclic_getfunction __is_supported_mem_typefunction xdp_reg_mem_modelfunction xdp_rxq_info_reg_mem_modelfunction xdp_rxq_info_attach_page_poolfunction xdp_unreg_page_poolfunction xdp_rxq_info_reg_mem_modelfunction scenariosfunction xdp_return_framefunction xdp_return_frame_rx_napifunction xdp_return_frame_bulkfunction xdp_return_fragfunction xdp_return_bufffunction xdp_attachment_setupfunction xdp_warnfunction xdp_copy_frags_from_zcfunction xdp_build_skb_from_bufffunction bpf_xdp_metadata_rx_timestampfunction typefunction orderfunction bpf_xdp_metadata_kfunc_idfunction bpf_dev_bound_kfunc_idfunction xdp_metadata_initfunction xdp_set_features_flag_lockedfunction xdp_set_features_flagfunction xdp_features_set_redirect_target_lockedfunction xdp_features_set_redirect_targetfunction xdp_features_clear_redirect_target_lockedfunction xdp_features_clear_redirect_targetexport xdp_unreg_mem_modelexport xdp_rxq_info_unreg_mem_modelexport xdp_rxq_info_unregexport __xdp_rxq_info_regexport xdp_rxq_info_unusedexport xdp_rxq_info_is_reg
Annotated Snippet
while ((xa = rhashtable_walk_next(&iter)) && !IS_ERR(xa)) {
if (xa->allocator == allocator)
mem_xa_remove(xa);
}
rhashtable_walk_stop(&iter);
} while (xa == ERR_PTR(-EAGAIN));
rhashtable_walk_exit(&iter);
mutex_unlock(&mem_id_lock);
}
void xdp_unreg_mem_model(struct xdp_mem_info *mem)
{
struct xdp_mem_allocator *xa;
int type = mem->type;
int id = mem->id;
/* Reset mem info to defaults */
mem->id = 0;
mem->type = 0;
if (id == 0)
return;
if (type == MEM_TYPE_PAGE_POOL) {
xa = rhashtable_lookup_fast(mem_id_ht, &id, mem_id_rht_params);
page_pool_destroy(xa->page_pool);
}
}
EXPORT_SYMBOL_GPL(xdp_unreg_mem_model);
void xdp_rxq_info_unreg_mem_model(struct xdp_rxq_info *xdp_rxq)
{
if (xdp_rxq->reg_state != REG_STATE_REGISTERED) {
WARN(1, "Missing register, driver bug");
return;
}
xdp_unreg_mem_model(&xdp_rxq->mem);
}
EXPORT_SYMBOL_GPL(xdp_rxq_info_unreg_mem_model);
void xdp_rxq_info_unreg(struct xdp_rxq_info *xdp_rxq)
{
/* Simplify driver cleanup code paths, allow unreg "unused" */
if (xdp_rxq->reg_state == REG_STATE_UNUSED)
return;
xdp_rxq_info_unreg_mem_model(xdp_rxq);
xdp_rxq->reg_state = REG_STATE_UNREGISTERED;
xdp_rxq->dev = NULL;
}
EXPORT_SYMBOL_GPL(xdp_rxq_info_unreg);
static void xdp_rxq_info_init(struct xdp_rxq_info *xdp_rxq)
{
memset(xdp_rxq, 0, sizeof(*xdp_rxq));
}
/* Returns 0 on success, negative on failure */
int __xdp_rxq_info_reg(struct xdp_rxq_info *xdp_rxq,
struct net_device *dev, u32 queue_index,
unsigned int napi_id, u32 frag_size)
{
if (!dev) {
WARN(1, "Missing net_device from driver");
return -ENODEV;
}
if (xdp_rxq->reg_state == REG_STATE_UNUSED) {
WARN(1, "Driver promised not to register this");
return -EINVAL;
}
if (xdp_rxq->reg_state == REG_STATE_REGISTERED) {
WARN(1, "Missing unregister, handled but fix driver");
xdp_rxq_info_unreg(xdp_rxq);
}
/* State either UNREGISTERED or NEW */
xdp_rxq_info_init(xdp_rxq);
xdp_rxq->dev = dev;
xdp_rxq->queue_index = queue_index;
xdp_rxq->frag_size = frag_size;
xdp_rxq->reg_state = REG_STATE_REGISTERED;
return 0;
Annotation
- Immediate include surface: `linux/bpf.h`, `linux/btf.h`, `linux/btf_ids.h`, `linux/filter.h`, `linux/types.h`, `linux/mm.h`, `linux/netdevice.h`, `linux/slab.h`.
- Detected declarations: `function xdp_mem_id_hashfn`, `function xdp_mem_id_cmp`, `function __xdp_mem_allocator_rcu_free`, `function mem_xa_remove`, `function mem_allocator_disconnect`, `function xdp_unreg_mem_model`, `function xdp_rxq_info_unreg_mem_model`, `function xdp_rxq_info_unreg`, `function xdp_rxq_info_init`, `function __xdp_rxq_info_reg`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: integration 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.