Skip to content

Commit

Permalink
Merge branch 'XDP-transmission-for-tuntap'
Browse files Browse the repository at this point in the history
Jason Wang says:

====================
XDP transmission for tuntap

This series tries to implement XDP transmission (ndo_xdp_xmit) for
tuntap. Pointer ring was used for queuing both XDP buffers and
sk_buff, this is done by encoding the type into lowest bit of the
pointer and storin XDP metadata in the headroom of XDP buff.

Tests gets 3.05 Mpps when doing xdp_redirect_map from ixgbe to VM
(testpmd + virtio-net in guest). This gives us ~20% improvments
compared to use skb during redirect.

Please review.

Changes from V1:

- slient warnings
- fix typos
- add skb mode number in the commit log
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jan 9, 2018
2 parents a0ce093 + fc72d1d commit e8b18af
Show file tree
Hide file tree
Showing 5 changed files with 269 additions and 90 deletions.
41 changes: 21 additions & 20 deletions drivers/net/tap.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ rx_handler_result_t tap_handle_frame(struct sk_buff **pskb)
if (!q)
return RX_HANDLER_PASS;

if (__skb_array_full(&q->skb_array))
if (__ptr_ring_full(&q->ring))
goto drop;

skb_push(skb, ETH_HLEN);
Expand All @@ -348,7 +348,7 @@ rx_handler_result_t tap_handle_frame(struct sk_buff **pskb)
goto drop;

if (!segs) {
if (skb_array_produce(&q->skb_array, skb))
if (ptr_ring_produce(&q->ring, skb))
goto drop;
goto wake_up;
}
Expand All @@ -358,7 +358,7 @@ rx_handler_result_t tap_handle_frame(struct sk_buff **pskb)
struct sk_buff *nskb = segs->next;

segs->next = NULL;
if (skb_array_produce(&q->skb_array, segs)) {
if (ptr_ring_produce(&q->ring, segs)) {
kfree_skb(segs);
kfree_skb_list(nskb);
break;
Expand All @@ -375,7 +375,7 @@ rx_handler_result_t tap_handle_frame(struct sk_buff **pskb)
!(features & NETIF_F_CSUM_MASK) &&
skb_checksum_help(skb))
goto drop;
if (skb_array_produce(&q->skb_array, skb))
if (ptr_ring_produce(&q->ring, skb))
goto drop;
}

Expand Down Expand Up @@ -497,7 +497,7 @@ static void tap_sock_destruct(struct sock *sk)
{
struct tap_queue *q = container_of(sk, struct tap_queue, sk);

skb_array_cleanup(&q->skb_array);
ptr_ring_cleanup(&q->ring, __skb_array_destroy_skb);
}

static int tap_open(struct inode *inode, struct file *file)
Expand All @@ -517,7 +517,7 @@ static int tap_open(struct inode *inode, struct file *file)
&tap_proto, 0);
if (!q)
goto err;
if (skb_array_init(&q->skb_array, tap->dev->tx_queue_len, GFP_KERNEL)) {
if (ptr_ring_init(&q->ring, tap->dev->tx_queue_len, GFP_KERNEL)) {
sk_free(&q->sk);
goto err;
}
Expand Down Expand Up @@ -546,7 +546,7 @@ static int tap_open(struct inode *inode, struct file *file)

err = tap_set_queue(tap, file, q);
if (err) {
/* tap_sock_destruct() will take care of freeing skb_array */
/* tap_sock_destruct() will take care of freeing ptr_ring */
goto err_put;
}

Expand Down Expand Up @@ -583,7 +583,7 @@ static unsigned int tap_poll(struct file *file, poll_table *wait)
mask = 0;
poll_wait(file, &q->wq.wait, wait);

if (!skb_array_empty(&q->skb_array))
if (!ptr_ring_empty(&q->ring))
mask |= POLLIN | POLLRDNORM;

if (sock_writeable(&q->sk) ||
Expand Down Expand Up @@ -844,7 +844,7 @@ static ssize_t tap_do_read(struct tap_queue *q,
TASK_INTERRUPTIBLE);

/* Read frames from the queue */
skb = skb_array_consume(&q->skb_array);
skb = ptr_ring_consume(&q->ring);
if (skb)
break;
if (noblock) {
Expand Down Expand Up @@ -1176,7 +1176,7 @@ static int tap_peek_len(struct socket *sock)
{
struct tap_queue *q = container_of(sock, struct tap_queue,
sock);
return skb_array_peek_len(&q->skb_array);
return PTR_RING_PEEK_CALL(&q->ring, __skb_array_len_with_tag);
}

/* Ops structure to mimic raw sockets with tun */
Expand All @@ -1202,7 +1202,7 @@ struct socket *tap_get_socket(struct file *file)
}
EXPORT_SYMBOL_GPL(tap_get_socket);

struct skb_array *tap_get_skb_array(struct file *file)
struct ptr_ring *tap_get_ptr_ring(struct file *file)
{
struct tap_queue *q;

Expand All @@ -1211,29 +1211,30 @@ struct skb_array *tap_get_skb_array(struct file *file)
q = file->private_data;
if (!q)
return ERR_PTR(-EBADFD);
return &q->skb_array;
return &q->ring;
}
EXPORT_SYMBOL_GPL(tap_get_skb_array);
EXPORT_SYMBOL_GPL(tap_get_ptr_ring);

int tap_queue_resize(struct tap_dev *tap)
{
struct net_device *dev = tap->dev;
struct tap_queue *q;
struct skb_array **arrays;
struct ptr_ring **rings;
int n = tap->numqueues;
int ret, i = 0;

arrays = kmalloc_array(n, sizeof(*arrays), GFP_KERNEL);
if (!arrays)
rings = kmalloc_array(n, sizeof(*rings), GFP_KERNEL);
if (!rings)
return -ENOMEM;

list_for_each_entry(q, &tap->queue_list, next)
arrays[i++] = &q->skb_array;
rings[i++] = &q->ring;

ret = skb_array_resize_multiple(arrays, n,
dev->tx_queue_len, GFP_KERNEL);
ret = ptr_ring_resize_multiple(rings, n,
dev->tx_queue_len, GFP_KERNEL,
__skb_array_destroy_skb);

kfree(arrays);
kfree(rings);
return ret;
}
EXPORT_SYMBOL_GPL(tap_queue_resize);
Expand Down
Loading

0 comments on commit e8b18af

Please sign in to comment.