Skip to content

Commit fe23083

Browse files
magnus-karlssonAlexei Starovoitov
authored andcommitted
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. Signed-off-by: Magnus Karlsson <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 02671e2 commit fe23083

File tree

4 files changed

+15
-2
lines changed

4 files changed

+15
-2
lines changed

include/uapi/linux/if_xdp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ struct sockaddr_xdp {
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 {
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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ static void xdp_umem_release(struct xdp_umem *umem)
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 @@ int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
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,
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,
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,
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
}

0 commit comments

Comments
 (0)