Skip to content

Commit 5990a30

Browse files
jasowangdavem330
authored andcommitted
tun/tap: use ptr_ring instead of skb_array
This patch switches to use ptr_ring instead of skb_array. This will be used to enqueue different types of pointers by encoding type into lower bits. Signed-off-by: Jason Wang <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a0ce093 commit 5990a30

File tree

5 files changed

+68
-64
lines changed

5 files changed

+68
-64
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);

drivers/net/tun.c

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ struct tun_file {
179179
struct mutex napi_mutex; /* Protects access to the above napi */
180180
struct list_head next;
181181
struct tun_struct *detached;
182-
struct skb_array tx_array;
182+
struct ptr_ring tx_ring;
183183
struct xdp_rxq_info xdp_rxq;
184184
};
185185

@@ -635,7 +635,7 @@ static void tun_queue_purge(struct tun_file *tfile)
635635
{
636636
struct sk_buff *skb;
637637

638-
while ((skb = skb_array_consume(&tfile->tx_array)) != NULL)
638+
while ((skb = ptr_ring_consume(&tfile->tx_ring)) != NULL)
639639
kfree_skb(skb);
640640

641641
skb_queue_purge(&tfile->sk.sk_write_queue);
@@ -689,7 +689,8 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
689689
unregister_netdevice(tun->dev);
690690
}
691691
if (tun) {
692-
skb_array_cleanup(&tfile->tx_array);
692+
ptr_ring_cleanup(&tfile->tx_ring,
693+
__skb_array_destroy_skb);
693694
xdp_rxq_info_unreg(&tfile->xdp_rxq);
694695
}
695696
sock_put(&tfile->sk);
@@ -782,7 +783,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file,
782783
}
783784

784785
if (!tfile->detached &&
785-
skb_array_init(&tfile->tx_array, dev->tx_queue_len, GFP_KERNEL)) {
786+
ptr_ring_init(&tfile->tx_ring, dev->tx_queue_len, GFP_KERNEL)) {
786787
err = -ENOMEM;
787788
goto out;
788789
}
@@ -1048,7 +1049,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
10481049

10491050
nf_reset(skb);
10501051

1051-
if (skb_array_produce(&tfile->tx_array, skb))
1052+
if (ptr_ring_produce(&tfile->tx_ring, skb))
10521053
goto drop;
10531054

10541055
/* Notify and wake up reader process */
@@ -1316,7 +1317,7 @@ static unsigned int tun_chr_poll(struct file *file, poll_table *wait)
13161317

13171318
poll_wait(file, sk_sleep(sk), wait);
13181319

1319-
if (!skb_array_empty(&tfile->tx_array))
1320+
if (!ptr_ring_empty(&tfile->tx_ring))
13201321
mask |= POLLIN | POLLRDNORM;
13211322

13221323
if (tun->dev->flags & IFF_UP &&
@@ -1966,7 +1967,7 @@ static struct sk_buff *tun_ring_recv(struct tun_file *tfile, int noblock,
19661967
struct sk_buff *skb = NULL;
19671968
int error = 0;
19681969

1969-
skb = skb_array_consume(&tfile->tx_array);
1970+
skb = ptr_ring_consume(&tfile->tx_ring);
19701971
if (skb)
19711972
goto out;
19721973
if (noblock) {
@@ -1978,7 +1979,7 @@ static struct sk_buff *tun_ring_recv(struct tun_file *tfile, int noblock,
19781979
current->state = TASK_INTERRUPTIBLE;
19791980

19801981
while (1) {
1981-
skb = skb_array_consume(&tfile->tx_array);
1982+
skb = ptr_ring_consume(&tfile->tx_ring);
19821983
if (skb)
19831984
break;
19841985
if (signal_pending(current)) {
@@ -2208,7 +2209,7 @@ static int tun_peek_len(struct socket *sock)
22082209
if (!tun)
22092210
return 0;
22102211

2211-
ret = skb_array_peek_len(&tfile->tx_array);
2212+
ret = PTR_RING_PEEK_CALL(&tfile->tx_ring, __skb_array_len_with_tag);
22122213
tun_put(tun);
22132214

22142215
return ret;
@@ -3114,25 +3115,26 @@ static int tun_queue_resize(struct tun_struct *tun)
31143115
{
31153116
struct net_device *dev = tun->dev;
31163117
struct tun_file *tfile;
3117-
struct skb_array **arrays;
3118+
struct ptr_ring **rings;
31183119
int n = tun->numqueues + tun->numdisabled;
31193120
int ret, i;
31203121

3121-
arrays = kmalloc_array(n, sizeof(*arrays), GFP_KERNEL);
3122-
if (!arrays)
3122+
rings = kmalloc_array(n, sizeof(*rings), GFP_KERNEL);
3123+
if (!rings)
31233124
return -ENOMEM;
31243125

31253126
for (i = 0; i < tun->numqueues; i++) {
31263127
tfile = rtnl_dereference(tun->tfiles[i]);
3127-
arrays[i] = &tfile->tx_array;
3128+
rings[i] = &tfile->tx_ring;
31283129
}
31293130
list_for_each_entry(tfile, &tun->disabled, next)
3130-
arrays[i++] = &tfile->tx_array;
3131+
rings[i++] = &tfile->tx_ring;
31313132

3132-
ret = skb_array_resize_multiple(arrays, n,
3133-
dev->tx_queue_len, GFP_KERNEL);
3133+
ret = ptr_ring_resize_multiple(rings, n,
3134+
dev->tx_queue_len, GFP_KERNEL,
3135+
__skb_array_destroy_skb);
31343136

3135-
kfree(arrays);
3137+
kfree(rings);
31363138
return ret;
31373139
}
31383140

@@ -3218,7 +3220,7 @@ struct socket *tun_get_socket(struct file *file)
32183220
}
32193221
EXPORT_SYMBOL_GPL(tun_get_socket);
32203222

3221-
struct skb_array *tun_get_skb_array(struct file *file)
3223+
struct ptr_ring *tun_get_tx_ring(struct file *file)
32223224
{
32233225
struct tun_file *tfile;
32243226

@@ -3227,9 +3229,9 @@ struct skb_array *tun_get_skb_array(struct file *file)
32273229
tfile = file->private_data;
32283230
if (!tfile)
32293231
return ERR_PTR(-EBADFD);
3230-
return &tfile->tx_array;
3232+
return &tfile->tx_ring;
32313233
}
3232-
EXPORT_SYMBOL_GPL(tun_get_skb_array);
3234+
EXPORT_SYMBOL_GPL(tun_get_tx_ring);
32333235

32343236
module_init(tun_init);
32353237
module_exit(tun_cleanup);

drivers/vhost/net.c

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ struct vhost_net_ubuf_ref {
8989

9090
#define VHOST_RX_BATCH 64
9191
struct vhost_net_buf {
92-
struct sk_buff **queue;
92+
void **queue;
9393
int tail;
9494
int head;
9595
};
@@ -108,7 +108,7 @@ struct vhost_net_virtqueue {
108108
/* Reference counting for outstanding ubufs.
109109
* Protected by vq mutex. Writers must also take device mutex. */
110110
struct vhost_net_ubuf_ref *ubufs;
111-
struct skb_array *rx_array;
111+
struct ptr_ring *rx_ring;
112112
struct vhost_net_buf rxq;
113113
};
114114

@@ -158,7 +158,7 @@ static int vhost_net_buf_produce(struct vhost_net_virtqueue *nvq)
158158
struct vhost_net_buf *rxq = &nvq->rxq;
159159

160160
rxq->head = 0;
161-
rxq->tail = skb_array_consume_batched(nvq->rx_array, rxq->queue,
161+
rxq->tail = ptr_ring_consume_batched(nvq->rx_ring, rxq->queue,
162162
VHOST_RX_BATCH);
163163
return rxq->tail;
164164
}
@@ -167,9 +167,10 @@ static void vhost_net_buf_unproduce(struct vhost_net_virtqueue *nvq)
167167
{
168168
struct vhost_net_buf *rxq = &nvq->rxq;
169169

170-
if (nvq->rx_array && !vhost_net_buf_is_empty(rxq)) {
171-
skb_array_unconsume(nvq->rx_array, rxq->queue + rxq->head,
172-
vhost_net_buf_get_size(rxq));
170+
if (nvq->rx_ring && !vhost_net_buf_is_empty(rxq)) {
171+
ptr_ring_unconsume(nvq->rx_ring, rxq->queue + rxq->head,
172+
vhost_net_buf_get_size(rxq),
173+
__skb_array_destroy_skb);
173174
rxq->head = rxq->tail = 0;
174175
}
175176
}
@@ -583,7 +584,7 @@ static int peek_head_len(struct vhost_net_virtqueue *rvq, struct sock *sk)
583584
int len = 0;
584585
unsigned long flags;
585586

586-
if (rvq->rx_array)
587+
if (rvq->rx_ring)
587588
return vhost_net_buf_peek(rvq);
588589

589590
spin_lock_irqsave(&sk->sk_receive_queue.lock, flags);
@@ -790,7 +791,7 @@ static void handle_rx(struct vhost_net *net)
790791
* they refilled. */
791792
goto out;
792793
}
793-
if (nvq->rx_array)
794+
if (nvq->rx_ring)
794795
msg.msg_control = vhost_net_buf_consume(&nvq->rxq);
795796
/* On overrun, truncate and discard */
796797
if (unlikely(headcount > UIO_MAXIOV)) {
@@ -896,7 +897,7 @@ static int vhost_net_open(struct inode *inode, struct file *f)
896897
struct vhost_net *n;
897898
struct vhost_dev *dev;
898899
struct vhost_virtqueue **vqs;
899-
struct sk_buff **queue;
900+
void **queue;
900901
int i;
901902

902903
n = kvmalloc(sizeof *n, GFP_KERNEL | __GFP_RETRY_MAYFAIL);
@@ -908,7 +909,7 @@ static int vhost_net_open(struct inode *inode, struct file *f)
908909
return -ENOMEM;
909910
}
910911

911-
queue = kmalloc_array(VHOST_RX_BATCH, sizeof(struct sk_buff *),
912+
queue = kmalloc_array(VHOST_RX_BATCH, sizeof(void *),
912913
GFP_KERNEL);
913914
if (!queue) {
914915
kfree(vqs);
@@ -1046,23 +1047,23 @@ static struct socket *get_raw_socket(int fd)
10461047
return ERR_PTR(r);
10471048
}
10481049

1049-
static struct skb_array *get_tap_skb_array(int fd)
1050+
static struct ptr_ring *get_tap_ptr_ring(int fd)
10501051
{
1051-
struct skb_array *array;
1052+
struct ptr_ring *ring;
10521053
struct file *file = fget(fd);
10531054

10541055
if (!file)
10551056
return NULL;
1056-
array = tun_get_skb_array(file);
1057-
if (!IS_ERR(array))
1057+
ring = tun_get_tx_ring(file);
1058+
if (!IS_ERR(ring))
10581059
goto out;
1059-
array = tap_get_skb_array(file);
1060-
if (!IS_ERR(array))
1060+
ring = tap_get_ptr_ring(file);
1061+
if (!IS_ERR(ring))
10611062
goto out;
1062-
array = NULL;
1063+
ring = NULL;
10631064
out:
10641065
fput(file);
1065-
return array;
1066+
return ring;
10661067
}
10671068

10681069
static struct socket *get_tap_socket(int fd)
@@ -1143,7 +1144,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
11431144
vq->private_data = sock;
11441145
vhost_net_buf_unproduce(nvq);
11451146
if (index == VHOST_NET_VQ_RX)
1146-
nvq->rx_array = get_tap_skb_array(fd);
1147+
nvq->rx_ring = get_tap_ptr_ring(fd);
11471148
r = vhost_vq_init_access(vq);
11481149
if (r)
11491150
goto err_used;

0 commit comments

Comments
 (0)