History

xsk: add umem completion queue support and mmap

Here, we add another setsockopt for registered user memory (umem) called XDP_UMEM_COMPLETION_QUEUE. Using this socket option, the process can ask the kernel to allocate a queue (ring buffer) and also mmap it (XDP_UMEM_PGOFF_COMPLETION_QUEUE) into the process. The queue is used to explicitly pass ownership of umem frames from the kernel to user process. This will be used by the TX path to tell user space that a certain frame has been transmitted and user space can use it for something else, if it wishes.

Magnus Karlsson committed 8 years ago

Commit fe230831 parent 02671e24 files · +15 −2Browse files

Unified · Split

4 files
  1. include/uapi/linux/if_xdp.h +2 −0
  2. net/xdp/xdp_umem.c +6 −1
  3. net/xdp/xdp_umem.h +1 −0
  4. net/xdp/xsk.c +6 −1
include/uapi/linux/if_xdp.h+2−0
@@ -36,6 +36,7 @@ struct sockaddr_xdp { · 35 unmodified lines
3636 #define XDP_RX_RING 1
3737 #define XDP_UMEM_REG 3
3838 #define XDP_UMEM_FILL_RING 4
39+#define XDP_UMEM_COMPLETION_RING 5
3940
4041 struct xdp_umem_reg {
4142 __u64 addr; /* Start of packet data area */
@@ -47,6 +48,7 @@ struct xdp_umem_reg { · 5 unmodified lines
4748 /* Pgoff for mmaping the rings */
4849 #define XDP_PGOFF_RX_RING 0
4950 #define XDP_UMEM_PGOFF_FILL_RING 0x100000000
51+#define XDP_UMEM_PGOFF_COMPLETION_RING 0x180000000
5052
5153 struct xdp_desc {
5254 __u32 idx;
net/xdp/xdp_umem.c+6−1
@@ -70,6 +70,11 @@ static void xdp_umem_release(struct xdp_umem *umem) · 69 unmodified lines
7070 umem->fq = NULL;
7171 }
7272
73+ if (umem->cq) {
74+ xskq_destroy(umem->cq);
75+ umem->cq = NULL;
76+ }
77+
7378 if (umem->pgs) {
7479 xdp_umem_unpin_pages(umem);
7580
@@ -251,5 +256,5 @@ out: · 175 unmodified lines
251256
252257 bool xdp_umem_validate_queues(struct xdp_umem *umem)
253258 {
254− return umem->fq;
259+ return (umem->fq && umem->cq);
255260 }
net/xdp/xdp_umem.h+1−0
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424
2525 struct xdp_umem {
2626 struct xsk_queue *fq;
27+ struct xsk_queue *cq;
2728 struct page **pgs;
2829 struct xdp_umem_props props;
2930 u32 npgs;
net/xdp/xsk.c+6−1
@@ -255,6 +255,7 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len) · 254 unmodified lines
255255 } else {
256256 /* This xsk has its own umem. */
257257 xskq_set_umem(xs->umem->fq, &xs->umem->props);
258+ xskq_set_umem(xs->umem->cq, &xs->umem->props);
258259 }
259260
260261 /* Rebind? */
@@ -334,6 +335,7 @@ static int xsk_setsockopt(struct socket *sock, int level, int optname, · 73 unmodified lines
334335 return 0;
335336 }
336337 case XDP_UMEM_FILL_RING:
338+ case XDP_UMEM_COMPLETION_RING:
337339 {
338340 struct xsk_queue **q;
339341 int entries;
@@ -345,7 +347,8 @@ static int xsk_setsockopt(struct socket *sock, int level, int optname, · 5 unmodified lines
345347 return -EFAULT;
346348
347349 mutex_lock(&xs->mutex);
348− q = &xs->umem->fq;
350+ q = (optname == XDP_UMEM_FILL_RING) ? &xs->umem->fq :
351+ &xs->umem->cq;
349352 err = xsk_init_queue(entries, q, true);
350353 mutex_unlock(&xs->mutex);
351354 return err;
@@ -375,6 +378,8 @@ static int xsk_mmap(struct file *file, struct socket *sock, · 23 unmodified lines
375378
376379 if (offset == XDP_UMEM_PGOFF_FILL_RING)
377380 q = xs->umem->fq;
381+ else if (offset == XDP_UMEM_PGOFF_COMPLETION_RING)
382+ q = xs->umem->cq;
378383 else
379384 return -EINVAL;
380385 }