Skip to content

Commit

Permalink
xsk: Support allocations of large umems
Browse files Browse the repository at this point in the history
When registering a umem area that is sufficiently large (>1G on an
x86), kmalloc cannot be used to allocate one of the internal data
structures, as the size requested gets too large. Use kvmalloc instead
that falls back on vmalloc if the allocation is too large for kmalloc.

Also add accounting for this structure as it is triggered by a user
space action (the XDP_UMEM_REG setsockopt) and it is by far the
largest structure of kernel allocated memory in xsk.

Reported-by: Ryan Goodfellow <[email protected]>
Signed-off-by: Magnus Karlsson <[email protected]>
Signed-off-by: Alexei Starovoitov <[email protected]>
Acked-by: Jonathan Lemon <[email protected]>
Link: https://lore.kernel.org/bpf/[email protected]
  • Loading branch information
magnus-karlsson authored and Alexei Starovoitov committed Jan 15, 2020
1 parent 0a29275 commit d3a5693
Showing 1 changed file with 4 additions and 3 deletions.
7 changes: 4 additions & 3 deletions net/xdp/xdp_umem.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ static void xdp_umem_release(struct xdp_umem *umem)
xdp_umem_unmap_pages(umem);
xdp_umem_unpin_pages(umem);

kfree(umem->pages);
kvfree(umem->pages);
umem->pages = NULL;

xdp_umem_unaccount_pages(umem);
Expand Down Expand Up @@ -409,7 +409,8 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
if (err)
goto out_account;

umem->pages = kcalloc(umem->npgs, sizeof(*umem->pages), GFP_KERNEL);
umem->pages = kvcalloc(umem->npgs, sizeof(*umem->pages),
GFP_KERNEL_ACCOUNT);
if (!umem->pages) {
err = -ENOMEM;
goto out_pin;
Expand All @@ -419,7 +420,7 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
if (!err)
return 0;

kfree(umem->pages);
kvfree(umem->pages);

out_pin:
xdp_umem_unpin_pages(umem);
Expand Down

0 comments on commit d3a5693

Please sign in to comment.