From: Magnus Karlsson <magnus.karlsson@intel.com>
Date: Wed, 2 May 2018 13:01:32 +0200
Subject: xsk: add Tx queue setup and mmap support
Patch-mainline: v4.18-rc1
Git-commit: f61459030ec7fffdaa3c462cc0f728eef11b4d05
References: bsc#1109837
Another setsockopt (XDP_TX_QUEUE) is added to let the process allocate
a queue, where the user process can pass frames to be transmitted by
the kernel.
The mmapping of the queue is done using the XDP_PGOFF_TX_QUEUE offset.
Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
include/net/xdp_sock.h | 1 +
include/uapi/linux/if_xdp.h | 2 ++
net/xdp/xsk.c | 8 ++++++--
3 files changed, 9 insertions(+), 2 deletions(-)
--- a/include/net/xdp_sock.h
+++ b/include/net/xdp_sock.h
@@ -30,6 +30,7 @@ struct xdp_sock {
struct xdp_umem *umem;
struct list_head flush_node;
u16 queue_id;
+ struct xsk_queue *tx ____cacheline_aligned_in_smp;
/* Protects multiple processes in the control path */
struct mutex mutex;
u64 rx_dropped;
--- a/include/uapi/linux/if_xdp.h
+++ b/include/uapi/linux/if_xdp.h
@@ -34,6 +34,7 @@ struct sockaddr_xdp {
/* XDP socket options */
#define XDP_RX_RING 1
+#define XDP_TX_RING 2
#define XDP_UMEM_REG 3
#define XDP_UMEM_FILL_RING 4
#define XDP_UMEM_COMPLETION_RING 5
@@ -47,6 +48,7 @@ struct xdp_umem_reg {
/* Pgoff for mmaping the rings */
#define XDP_PGOFF_RX_RING 0
+#define XDP_PGOFF_TX_RING 0x80000000
#define XDP_UMEM_PGOFF_FILL_RING 0x100000000
#define XDP_UMEM_PGOFF_COMPLETION_RING 0x180000000
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -206,7 +206,7 @@ static int xsk_bind(struct socket *sock,
goto out_release;
}
- if (!xs->rx) {
+ if (!xs->rx && !xs->tx) {
err = -EINVAL;
goto out_unlock;
}
@@ -291,6 +291,7 @@ static int xsk_setsockopt(struct socket
switch (optname) {
case XDP_RX_RING:
+ case XDP_TX_RING:
{
struct xsk_queue **q;
int entries;
@@ -301,7 +302,7 @@ static int xsk_setsockopt(struct socket
return -EFAULT;
mutex_lock(&xs->mutex);
- q = &xs->rx;
+ q = (optname == XDP_TX_RING) ? &xs->tx : &xs->rx;
err = xsk_init_queue(entries, q, false);
mutex_unlock(&xs->mutex);
return err;
@@ -372,6 +373,8 @@ static int xsk_mmap(struct file *file, s
if (offset == XDP_PGOFF_RX_RING) {
q = xs->rx;
+ } else if (offset == XDP_PGOFF_TX_RING) {
+ q = xs->tx;
} else {
if (!xs->umem)
return -EINVAL;
@@ -431,6 +434,7 @@ static void xsk_destruct(struct sock *sk
return;
xskq_destroy(xs->rx);
+ xskq_destroy(xs->tx);
xdp_put_umem(xs->umem);
sk_refcnt_debug_dec(sk);