[PATCH net v3 1/1] xsk: account ring allocations to memcg
Zihan Xi <[email protected]>
| Newsgroups | org.kernel.vger.bpf,org.kernel.vger.netdev |
|---|---|
| Message-ID | <[email protected]> |
AF_XDP rings are allocated from setsockopt() and can be mapped into user
space. The shared xskq_create() helper allocates the ring backing memory,
but the user-controlled and long-lived allocation is not charged as kmem
to the allocating memory cgroup.
The current implementation uses vmalloc_user(), which allocates the
backing pages with GFP_KERNEL | __GFP_ZERO. Use the same VM_USERMAP
vmalloc path, but pass GFP_KERNEL_ACCOUNT so the ring backing pages are
attributed to memcg/kmem and can be constrained by existing cgroup memory
limits. This keeps the existing zeroing and mmap semantics while avoiding
AF_XDP-specific optmem or RLIMIT_MEMLOCK accounting.
Fixes: 423f38329d26 ("xsk: add umem fill queue support and mmap")
Cc: [email protected]
Reported-by: Vega <[email protected]>
Assisted-by: Codex:gpt-5.4
Signed-off-by: Zihan Xi <[email protected]>
---
changes in v3:
- drop the v2 RLIMIT_MEMLOCK / user->locked_vm accounting approach
after review feedback
- switch the AF_XDP ring backing allocation to the memcg/kmem model by
using a VM_USERMAP vmalloc path with GFP_KERNEL_ACCOUNT
- include <asm/shmparam.h> explicitly for SHMLBA, matching the
vmalloc implementation's dependency
- retarget Fixes to 423f38329d26, the original mmapable queue
allocation that introduced the missing accounting root-cause fact
- v2 Link: https://lore.kernel.org/all/[email protected]/
changes in v2:
- replace the socket optmem limit proposal with RLIMIT_MEMLOCK /
user->locked_vm accounting via mm_account_pinned_pages()
- drop the earlier socket/pool lifetime coupling changes and keep the
final code diff limited to xsk_queue.c and xsk_queue.h
- retarget Fixes to 423f38329d26, the original mmapable queue
allocation that introduced the missing resource boundary
- v1 Link: https://lore.kernel.org/all/[email protected]/
net/xdp/xsk_queue.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/net/xdp/xsk_queue.c b/net/xdp/xsk_queue.c
index 4dd01b7d858e..d95b6d0d94aa 100644
--- a/net/xdp/xsk_queue.c
+++ b/net/xdp/xsk_queue.c
@@ -9,6 +9,8 @@
#include <linux/vmalloc.h>
#include <net/xdp_sock_drv.h>
+#include <asm/shmparam.h>
+
#include "xsk_queue.h"
static size_t xskq_get_ring_size(struct xsk_queue *q, bool umem_queue)
@@ -21,6 +23,14 @@ static size_t xskq_get_ring_size(struct xsk_queue *q, bool umem_queue)
return struct_size(rxtx_ring, desc, q->nentries);
}
+static void *xskq_vmalloc_user(unsigned long size)
+{
+ return __vmalloc_node_range(size, SHMLBA, VMALLOC_START, VMALLOC_END,
+ GFP_KERNEL_ACCOUNT | __GFP_ZERO, PAGE_KERNEL,
+ VM_USERMAP, NUMA_NO_NODE,
+ __builtin_return_address(0));
+}
+
struct xsk_queue *xskq_create(u32 nentries, bool umem_queue)
{
struct xsk_queue *q;
@@ -46,7 +56,7 @@ struct xsk_queue *xskq_create(u32 nentries, bool umem_queue)
size = PAGE_ALIGN(size);
- q->ring = vmalloc_user(size);
+ q->ring = xskq_vmalloc_user(size);
if (!q->ring) {
kfree(q);
return NULL;
--
2.43.0