Skip to content

Commit 9f78bf3

Browse files
fengidridavem330
authored andcommitted
xsk: support use vaddr as ring
When we try to start AF_XDP on some machines with long running time, due to the machine's memory fragmentation problem, there is no sufficient contiguous physical memory that will cause the start failure. If the size of the queue is 8 * 1024, then the size of the desc[] is 8 * 1024 * 8 = 16 * PAGE, but we also add struct xdp_ring size, so it is 16page+. This is necessary to apply for a 4-order memory. If there are a lot of queues, it is difficult to these machine with long running time. Here, that we actually waste 15 pages. 4-Order memory is 32 pages, but we only use 17 pages. This patch replaces __get_free_pages() by vmalloc() to allocate memory to solve these problems. Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Acked-by: Magnus Karlsson <magnus.karlsson@intel.com> Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent b148d40 commit 9f78bf3

File tree

3 files changed

+8
-13
lines changed

3 files changed

+8
-13
lines changed

net/xdp/xsk.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,8 +1294,6 @@ static int xsk_mmap(struct file *file, struct socket *sock,
12941294
unsigned long size = vma->vm_end - vma->vm_start;
12951295
struct xdp_sock *xs = xdp_sk(sock->sk);
12961296
struct xsk_queue *q = NULL;
1297-
unsigned long pfn;
1298-
struct page *qpg;
12991297

13001298
if (READ_ONCE(xs->state) != XSK_READY)
13011299
return -EBUSY;
@@ -1318,13 +1316,10 @@ static int xsk_mmap(struct file *file, struct socket *sock,
13181316

13191317
/* Matches the smp_wmb() in xsk_init_queue */
13201318
smp_rmb();
1321-
qpg = virt_to_head_page(q->ring);
1322-
if (size > page_size(qpg))
1319+
if (size > q->ring_vmalloc_size)
13231320
return -EINVAL;
13241321

1325-
pfn = virt_to_phys(q->ring) >> PAGE_SHIFT;
1326-
return remap_pfn_range(vma, vma->vm_start, pfn,
1327-
size, vma->vm_page_prot);
1322+
return remap_vmalloc_range(vma, q->ring, 0);
13281323
}
13291324

13301325
static int xsk_notifier(struct notifier_block *this,

net/xdp/xsk_queue.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <linux/log2.h>
77
#include <linux/slab.h>
88
#include <linux/overflow.h>
9+
#include <linux/vmalloc.h>
910
#include <net/xdp_sock_drv.h>
1011

1112
#include "xsk_queue.h"
@@ -23,7 +24,6 @@ static size_t xskq_get_ring_size(struct xsk_queue *q, bool umem_queue)
2324
struct xsk_queue *xskq_create(u32 nentries, bool umem_queue)
2425
{
2526
struct xsk_queue *q;
26-
gfp_t gfp_flags;
2727
size_t size;
2828

2929
q = kzalloc(sizeof(*q), GFP_KERNEL);
@@ -33,17 +33,16 @@ struct xsk_queue *xskq_create(u32 nentries, bool umem_queue)
3333
q->nentries = nentries;
3434
q->ring_mask = nentries - 1;
3535

36-
gfp_flags = GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN |
37-
__GFP_COMP | __GFP_NORETRY;
3836
size = xskq_get_ring_size(q, umem_queue);
37+
size = PAGE_ALIGN(size);
3938

40-
q->ring = (struct xdp_ring *)__get_free_pages(gfp_flags,
41-
get_order(size));
39+
q->ring = vmalloc_user(size);
4240
if (!q->ring) {
4341
kfree(q);
4442
return NULL;
4543
}
4644

45+
q->ring_vmalloc_size = size;
4746
return q;
4847
}
4948

@@ -52,6 +51,6 @@ void xskq_destroy(struct xsk_queue *q)
5251
if (!q)
5352
return;
5453

55-
page_frag_free(q->ring);
54+
vfree(q->ring);
5655
kfree(q);
5756
}

net/xdp/xsk_queue.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct xsk_queue {
4545
struct xdp_ring *ring;
4646
u64 invalid_descs;
4747
u64 queue_empty_descs;
48+
size_t ring_vmalloc_size;
4849
};
4950

5051
/* The structure of the shared state of the rings are a simple

0 commit comments

Comments
 (0)