Skip to content

Commit e8b18af

Browse files
committed
Merge branch 'XDP-transmission-for-tuntap'
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 <[email protected]>
2 parents a0ce093 + fc72d1d commit e8b18af

File tree

5 files changed

+269
-90
lines changed

5 files changed

+269
-90
lines changed

drivers/net/tap.c

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ rx_handler_result_t tap_handle_frame(struct sk_buff **pskb)
330330
if (!q)
331331
return RX_HANDLER_PASS;
332332

333-
if (__skb_array_full(&q->skb_array))
333+
if (__ptr_ring_full(&q->ring))
334334
goto drop;
335335

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

350350
if (!segs) {
351-
if (skb_array_produce(&q->skb_array, skb))
351+
if (ptr_ring_produce(&q->ring, skb))
352352
goto drop;
353353
goto wake_up;
354354
}
@@ -358,7 +358,7 @@ rx_handler_result_t tap_handle_frame(struct sk_buff **pskb)
358358
struct sk_buff *nskb = segs->next;
359359

360360
segs->next = NULL;
361-
if (skb_array_produce(&q->skb_array, segs)) {
361+
if (ptr_ring_produce(&q->ring, segs)) {
362362
kfree_skb(segs);
363363
kfree_skb_list(nskb);
364364
break;
@@ -375,7 +375,7 @@ rx_handler_result_t tap_handle_frame(struct sk_buff **pskb)
375375
!(features & NETIF_F_CSUM_MASK) &&
376376
skb_checksum_help(skb))
377377
goto drop;
378-
if (skb_array_produce(&q->skb_array, skb))
378+
if (ptr_ring_produce(&q->ring, skb))
379379
goto drop;
380380
}
381381

@@ -497,7 +497,7 @@ static void tap_sock_destruct(struct sock *sk)
497497
{
498498
struct tap_queue *q = container_of(sk, struct tap_queue, sk);
499499

500-
skb_array_cleanup(&q->skb_array);
500+
ptr_ring_cleanup(&q->ring, __skb_array_destroy_skb);
501501
}
502502

503503
static int tap_open(struct inode *inode, struct file *file)
@@ -517,7 +517,7 @@ static int tap_open(struct inode *inode, struct file *file)
517517
&tap_proto, 0);
518518
if (!q)
519519
goto err;
520-
if (skb_array_init(&q->skb_array, tap->dev->tx_queue_len, GFP_KERNEL)) {
520+
if (ptr_ring_init(&q->ring, tap->dev->tx_queue_len, GFP_KERNEL)) {
521521
sk_free(&q->sk);
522522
goto err;
523523
}
@@ -546,7 +546,7 @@ static int tap_open(struct inode *inode, struct file *file)
546546

547547
err = tap_set_queue(tap, file, q);
548548
if (err) {
549-
/* tap_sock_destruct() will take care of freeing skb_array */
549+
/* tap_sock_destruct() will take care of freeing ptr_ring */
550550
goto err_put;
551551
}
552552

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

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

589589
if (sock_writeable(&q->sk) ||
@@ -844,7 +844,7 @@ static ssize_t tap_do_read(struct tap_queue *q,
844844
TASK_INTERRUPTIBLE);
845845

846846
/* Read frames from the queue */
847-
skb = skb_array_consume(&q->skb_array);
847+
skb = ptr_ring_consume(&q->ring);
848848
if (skb)
849849
break;
850850
if (noblock) {
@@ -1176,7 +1176,7 @@ static int tap_peek_len(struct socket *sock)
11761176
{
11771177
struct tap_queue *q = container_of(sock, struct tap_queue,
11781178
sock);
1179-
return skb_array_peek_len(&q->skb_array);
1179+
return PTR_RING_PEEK_CALL(&q->ring, __skb_array_len_with_tag);
11801180
}
11811181

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

1205-
struct skb_array *tap_get_skb_array(struct file *file)
1205+
struct ptr_ring *tap_get_ptr_ring(struct file *file)
12061206
{
12071207
struct tap_queue *q;
12081208

@@ -1211,29 +1211,30 @@ struct skb_array *tap_get_skb_array(struct file *file)
12111211
q = file->private_data;
12121212
if (!q)
12131213
return ERR_PTR(-EBADFD);
1214-
return &q->skb_array;
1214+
return &q->ring;
12151215
}
1216-
EXPORT_SYMBOL_GPL(tap_get_skb_array);
1216+
EXPORT_SYMBOL_GPL(tap_get_ptr_ring);
12171217

12181218
int tap_queue_resize(struct tap_dev *tap)
12191219
{
12201220
struct net_device *dev = tap->dev;
12211221
struct tap_queue *q;
1222-
struct skb_array **arrays;
1222+
struct ptr_ring **rings;
12231223
int n = tap->numqueues;
12241224
int ret, i = 0;
12251225

1226-
arrays = kmalloc_array(n, sizeof(*arrays), GFP_KERNEL);
1227-
if (!arrays)
1226+
rings = kmalloc_array(n, sizeof(*rings), GFP_KERNEL);
1227+
if (!rings)
12281228
return -ENOMEM;
12291229

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

1233-
ret = skb_array_resize_multiple(arrays, n,
1234-
dev->tx_queue_len, GFP_KERNEL);
1233+
ret = ptr_ring_resize_multiple(rings, n,
1234+
dev->tx_queue_len, GFP_KERNEL,
1235+
__skb_array_destroy_skb);
12351236

1236-
kfree(arrays);
1237+
kfree(rings);
12371238
return ret;
12381239
}
12391240
EXPORT_SYMBOL_GPL(tap_queue_resize);

0 commit comments

Comments
 (0)