diff options
author | David S. Miller <davem@davemloft.net> | 2018-03-09 12:03:00 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-09 12:03:00 -0500 |
commit | bcf34adc105d946437da3a575df3b390493e9078 (patch) | |
tree | c0d48a1da4ce356c2ce2037ba1b4fc210abba7e6 | |
parent | d06cbe9cbb8905df21b11d1cf789c9b2947688e9 (diff) | |
parent | 3a4030761ea88ff439030ca98e3094b9900e96b7 (diff) |
Merge branch 'vhost_net-ptr_ring-fixes'
Jason Wang says:
====================
Several fixes for vhost_net ptr_ring usage
This small series try to fix several bugs of ptr_ring usage in
vhost_net. Please review.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/tun.c | 3 | ||||
-rw-r--r-- | drivers/vhost/net.c | 8 | ||||
-rw-r--r-- | include/linux/if_tun.h | 4 |
3 files changed, 11 insertions, 4 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 7433bb2e4451..28cfa642e39a 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -655,7 +655,7 @@ static struct tun_struct *tun_enable_queue(struct tun_file *tfile) | |||
655 | return tun; | 655 | return tun; |
656 | } | 656 | } |
657 | 657 | ||
658 | static void tun_ptr_free(void *ptr) | 658 | void tun_ptr_free(void *ptr) |
659 | { | 659 | { |
660 | if (!ptr) | 660 | if (!ptr) |
661 | return; | 661 | return; |
@@ -667,6 +667,7 @@ static void tun_ptr_free(void *ptr) | |||
667 | __skb_array_destroy_skb(ptr); | 667 | __skb_array_destroy_skb(ptr); |
668 | } | 668 | } |
669 | } | 669 | } |
670 | EXPORT_SYMBOL_GPL(tun_ptr_free); | ||
670 | 671 | ||
671 | static void tun_queue_purge(struct tun_file *tfile) | 672 | static void tun_queue_purge(struct tun_file *tfile) |
672 | { | 673 | { |
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 610cba276d47..8139bc70ad7d 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -170,7 +170,7 @@ static void vhost_net_buf_unproduce(struct vhost_net_virtqueue *nvq) | |||
170 | if (nvq->rx_ring && !vhost_net_buf_is_empty(rxq)) { | 170 | if (nvq->rx_ring && !vhost_net_buf_is_empty(rxq)) { |
171 | ptr_ring_unconsume(nvq->rx_ring, rxq->queue + rxq->head, | 171 | ptr_ring_unconsume(nvq->rx_ring, rxq->queue + rxq->head, |
172 | vhost_net_buf_get_size(rxq), | 172 | vhost_net_buf_get_size(rxq), |
173 | __skb_array_destroy_skb); | 173 | tun_ptr_free); |
174 | rxq->head = rxq->tail = 0; | 174 | rxq->head = rxq->tail = 0; |
175 | } | 175 | } |
176 | } | 176 | } |
@@ -948,6 +948,7 @@ static int vhost_net_open(struct inode *inode, struct file *f) | |||
948 | n->vqs[i].done_idx = 0; | 948 | n->vqs[i].done_idx = 0; |
949 | n->vqs[i].vhost_hlen = 0; | 949 | n->vqs[i].vhost_hlen = 0; |
950 | n->vqs[i].sock_hlen = 0; | 950 | n->vqs[i].sock_hlen = 0; |
951 | n->vqs[i].rx_ring = NULL; | ||
951 | vhost_net_buf_init(&n->vqs[i].rxq); | 952 | vhost_net_buf_init(&n->vqs[i].rxq); |
952 | } | 953 | } |
953 | vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX); | 954 | vhost_dev_init(dev, vqs, VHOST_NET_VQ_MAX); |
@@ -972,6 +973,7 @@ static struct socket *vhost_net_stop_vq(struct vhost_net *n, | |||
972 | vhost_net_disable_vq(n, vq); | 973 | vhost_net_disable_vq(n, vq); |
973 | vq->private_data = NULL; | 974 | vq->private_data = NULL; |
974 | vhost_net_buf_unproduce(nvq); | 975 | vhost_net_buf_unproduce(nvq); |
976 | nvq->rx_ring = NULL; | ||
975 | mutex_unlock(&vq->mutex); | 977 | mutex_unlock(&vq->mutex); |
976 | return sock; | 978 | return sock; |
977 | } | 979 | } |
@@ -1161,14 +1163,14 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) | |||
1161 | vhost_net_disable_vq(n, vq); | 1163 | vhost_net_disable_vq(n, vq); |
1162 | vq->private_data = sock; | 1164 | vq->private_data = sock; |
1163 | vhost_net_buf_unproduce(nvq); | 1165 | vhost_net_buf_unproduce(nvq); |
1164 | if (index == VHOST_NET_VQ_RX) | ||
1165 | nvq->rx_ring = get_tap_ptr_ring(fd); | ||
1166 | r = vhost_vq_init_access(vq); | 1166 | r = vhost_vq_init_access(vq); |
1167 | if (r) | 1167 | if (r) |
1168 | goto err_used; | 1168 | goto err_used; |
1169 | r = vhost_net_enable_vq(n, vq); | 1169 | r = vhost_net_enable_vq(n, vq); |
1170 | if (r) | 1170 | if (r) |
1171 | goto err_used; | 1171 | goto err_used; |
1172 | if (index == VHOST_NET_VQ_RX) | ||
1173 | nvq->rx_ring = get_tap_ptr_ring(fd); | ||
1172 | 1174 | ||
1173 | oldubufs = nvq->ubufs; | 1175 | oldubufs = nvq->ubufs; |
1174 | nvq->ubufs = ubufs; | 1176 | nvq->ubufs = ubufs; |
diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h index c5b0a75a7812..fd00170b494f 100644 --- a/include/linux/if_tun.h +++ b/include/linux/if_tun.h | |||
@@ -25,6 +25,7 @@ struct ptr_ring *tun_get_tx_ring(struct file *file); | |||
25 | bool tun_is_xdp_buff(void *ptr); | 25 | bool tun_is_xdp_buff(void *ptr); |
26 | void *tun_xdp_to_ptr(void *ptr); | 26 | void *tun_xdp_to_ptr(void *ptr); |
27 | void *tun_ptr_to_xdp(void *ptr); | 27 | void *tun_ptr_to_xdp(void *ptr); |
28 | void tun_ptr_free(void *ptr); | ||
28 | #else | 29 | #else |
29 | #include <linux/err.h> | 30 | #include <linux/err.h> |
30 | #include <linux/errno.h> | 31 | #include <linux/errno.h> |
@@ -50,5 +51,8 @@ static inline void *tun_ptr_to_xdp(void *ptr) | |||
50 | { | 51 | { |
51 | return NULL; | 52 | return NULL; |
52 | } | 53 | } |
54 | static inline void tun_ptr_free(void *ptr) | ||
55 | { | ||
56 | } | ||
53 | #endif /* CONFIG_TUN */ | 57 | #endif /* CONFIG_TUN */ |
54 | #endif /* __IF_TUN_H */ | 58 | #endif /* __IF_TUN_H */ |