net/core/devmem.c
Source file repositories/reference/linux-study-clean/net/core/devmem.c
File Facts
- System
- Linux kernel
- Corpus path
net/core/devmem.c- Extension
.c- Size
- 13715 bytes
- Lines
- 546
- Domain
- Networking Core
- Bucket
- Sockets, Protocols, Packet Path, And Network Policy
- Inferred role
- Networking Core: implementation source
- Status
- source 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.
- 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/dma-buf.hlinux/genalloc.hlinux/mm.hlinux/netdevice.hlinux/types.hnet/netdev_queues.hnet/netdev_rx_queue.hnet/page_pool/helpers.hnet/page_pool/memory_provider.hnet/sock.hnet/tcp.htrace/events/page_pool.hdevmem.hmp_dmabuf_devmem.hpage_pool_priv.h
Detected Declarations
function net_devmem_dmabuf_free_chunk_ownerfunction net_devmem_get_dma_addrfunction net_devmem_dmabuf_binding_releasefunction __net_devmem_dmabuf_binding_freefunction net_devmem_alloc_dmabuffunction net_devmem_free_dmabuffunction net_devmem_unbind_dmabuffunction xa_for_eachfunction net_devmem_bind_dmabuf_to_queuefunction net_devmem_bind_dmabuffunction net_devmem_get_net_iovfunction net_devmem_put_net_iovfunction unlikelyfunction net_devmem_get_niov_atfunction mp_dmabuf_devmem_initfunction mp_dmabuf_devmem_alloc_netmemsfunction mp_dmabuf_devmem_destroyfunction mp_dmabuf_devmem_release_pagefunction mp_dmabuf_devmem_nl_fillfunction mp_dmabuf_devmem_uninstallfunction xa_for_each
Annotated Snippet
if (!IS_ALIGNED(dmabuf->size, PAGE_SIZE)) {
err = -EINVAL;
NL_SET_ERR_MSG(extack, "TX dma-buf size must be a multiple of PAGE_SIZE");
goto err_unmap;
}
binding->tx_vec = kvmalloc_objs(struct net_iov *,
dmabuf->size / PAGE_SIZE);
if (!binding->tx_vec) {
err = -ENOMEM;
goto err_unmap;
}
}
/* For simplicity we expect to make PAGE_SIZE allocations, but the
* binding can be much more flexible than that. We may be able to
* allocate MTU sized chunks here. Leave that for future work...
*/
binding->chunk_pool = gen_pool_create(PAGE_SHIFT,
dev_to_node(&dev->dev));
if (!binding->chunk_pool) {
err = -ENOMEM;
goto err_tx_vec;
}
virtual = 0;
for_each_sgtable_dma_sg(binding->sgt, sg, sg_idx) {
dma_addr_t dma_addr = sg_dma_address(sg);
struct dmabuf_genpool_chunk_owner *owner;
size_t len = sg_dma_len(sg);
struct net_iov *niov;
if (!IS_ALIGNED(len, PAGE_SIZE)) {
err = -EINVAL;
NL_SET_ERR_MSG(extack, "dma-buf SG length must be PAGE_SIZE aligned");
goto err_free_chunks;
}
owner = kzalloc_node(sizeof(*owner), GFP_KERNEL,
dev_to_node(&dev->dev));
if (!owner) {
err = -ENOMEM;
goto err_free_chunks;
}
owner->area.base_virtual = virtual;
owner->base_dma_addr = dma_addr;
owner->area.num_niovs = len / PAGE_SIZE;
owner->binding = binding;
err = gen_pool_add_owner(binding->chunk_pool, dma_addr,
dma_addr, len, dev_to_node(&dev->dev),
owner);
if (err) {
kfree(owner);
err = -EINVAL;
goto err_free_chunks;
}
owner->area.niovs = kvmalloc_objs(*owner->area.niovs,
owner->area.num_niovs);
if (!owner->area.niovs) {
err = -ENOMEM;
goto err_free_chunks;
}
for (i = 0; i < owner->area.num_niovs; i++) {
niov = &owner->area.niovs[i];
net_iov_init(niov, &owner->area, NET_IOV_DMABUF);
page_pool_set_dma_addr_netmem(net_iov_to_netmem(niov),
net_devmem_get_dma_addr(niov));
if (direction == DMA_TO_DEVICE)
binding->tx_vec[owner->area.base_virtual / PAGE_SIZE + i] = niov;
}
virtual += len;
}
err = xa_alloc_cyclic(&net_devmem_dmabuf_bindings, &binding->id,
binding, xa_limit_32b, &id_alloc_next,
GFP_KERNEL);
if (err < 0)
goto err_free_chunks;
list_add(&binding->list, &priv->bindings);
return binding;
err_free_chunks:
gen_pool_for_each_chunk(binding->chunk_pool,
net_devmem_dmabuf_free_chunk_owner, NULL);
Annotation
- Immediate include surface: `linux/dma-buf.h`, `linux/genalloc.h`, `linux/mm.h`, `linux/netdevice.h`, `linux/types.h`, `net/netdev_queues.h`, `net/netdev_rx_queue.h`, `net/page_pool/helpers.h`.
- Detected declarations: `function net_devmem_dmabuf_free_chunk_owner`, `function net_devmem_get_dma_addr`, `function net_devmem_dmabuf_binding_release`, `function __net_devmem_dmabuf_binding_free`, `function net_devmem_alloc_dmabuf`, `function net_devmem_free_dmabuf`, `function net_devmem_unbind_dmabuf`, `function xa_for_each`, `function net_devmem_bind_dmabuf_to_queue`, `function net_devmem_bind_dmabuf`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- 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.