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 <jasowang@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
a0ce093180
commit
5990a30510
@@ -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);
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) ||
|
||||
@@ -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) {
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
Reference in New Issue
Block a user