Commit f6145903 authored by Magnus Karlsson's avatar Magnus Karlsson Committed by Alexei Starovoitov

xsk: add Tx queue setup and mmap support

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: default avatarMagnus Karlsson <magnus.karlsson@intel.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent fe230832
...@@ -30,6 +30,7 @@ struct xdp_sock { ...@@ -30,6 +30,7 @@ struct xdp_sock {
struct xdp_umem *umem; struct xdp_umem *umem;
struct list_head flush_node; struct list_head flush_node;
u16 queue_id; u16 queue_id;
struct xsk_queue *tx ____cacheline_aligned_in_smp;
/* Protects multiple processes in the control path */ /* Protects multiple processes in the control path */
struct mutex mutex; struct mutex mutex;
u64 rx_dropped; u64 rx_dropped;
......
...@@ -34,6 +34,7 @@ struct sockaddr_xdp { ...@@ -34,6 +34,7 @@ struct sockaddr_xdp {
/* XDP socket options */ /* XDP socket options */
#define XDP_RX_RING 1 #define XDP_RX_RING 1
#define XDP_TX_RING 2
#define XDP_UMEM_REG 3 #define XDP_UMEM_REG 3
#define XDP_UMEM_FILL_RING 4 #define XDP_UMEM_FILL_RING 4
#define XDP_UMEM_COMPLETION_RING 5 #define XDP_UMEM_COMPLETION_RING 5
...@@ -47,6 +48,7 @@ struct xdp_umem_reg { ...@@ -47,6 +48,7 @@ struct xdp_umem_reg {
/* Pgoff for mmaping the rings */ /* Pgoff for mmaping the rings */
#define XDP_PGOFF_RX_RING 0 #define XDP_PGOFF_RX_RING 0
#define XDP_PGOFF_TX_RING 0x80000000
#define XDP_UMEM_PGOFF_FILL_RING 0x100000000 #define XDP_UMEM_PGOFF_FILL_RING 0x100000000
#define XDP_UMEM_PGOFF_COMPLETION_RING 0x180000000 #define XDP_UMEM_PGOFF_COMPLETION_RING 0x180000000
......
...@@ -206,7 +206,7 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len) ...@@ -206,7 +206,7 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
goto out_release; goto out_release;
} }
if (!xs->rx) { if (!xs->rx && !xs->tx) {
err = -EINVAL; err = -EINVAL;
goto out_unlock; goto out_unlock;
} }
...@@ -291,6 +291,7 @@ static int xsk_setsockopt(struct socket *sock, int level, int optname, ...@@ -291,6 +291,7 @@ static int xsk_setsockopt(struct socket *sock, int level, int optname,
switch (optname) { switch (optname) {
case XDP_RX_RING: case XDP_RX_RING:
case XDP_TX_RING:
{ {
struct xsk_queue **q; struct xsk_queue **q;
int entries; int entries;
...@@ -301,7 +302,7 @@ static int xsk_setsockopt(struct socket *sock, int level, int optname, ...@@ -301,7 +302,7 @@ static int xsk_setsockopt(struct socket *sock, int level, int optname,
return -EFAULT; return -EFAULT;
mutex_lock(&xs->mutex); mutex_lock(&xs->mutex);
q = &xs->rx; q = (optname == XDP_TX_RING) ? &xs->tx : &xs->rx;
err = xsk_init_queue(entries, q, false); err = xsk_init_queue(entries, q, false);
mutex_unlock(&xs->mutex); mutex_unlock(&xs->mutex);
return err; return err;
...@@ -372,6 +373,8 @@ static int xsk_mmap(struct file *file, struct socket *sock, ...@@ -372,6 +373,8 @@ static int xsk_mmap(struct file *file, struct socket *sock,
if (offset == XDP_PGOFF_RX_RING) { if (offset == XDP_PGOFF_RX_RING) {
q = xs->rx; q = xs->rx;
} else if (offset == XDP_PGOFF_TX_RING) {
q = xs->tx;
} else { } else {
if (!xs->umem) if (!xs->umem)
return -EINVAL; return -EINVAL;
...@@ -431,6 +434,7 @@ static void xsk_destruct(struct sock *sk) ...@@ -431,6 +434,7 @@ static void xsk_destruct(struct sock *sk)
return; return;
xskq_destroy(xs->rx); xskq_destroy(xs->rx);
xskq_destroy(xs->tx);
xdp_put_umem(xs->umem); xdp_put_umem(xs->umem);
sk_refcnt_debug_dec(sk); sk_refcnt_debug_dec(sk);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment