[PATCH] tuntap: synchronize through tfiles instead of numqueues

From: Jason Wang
Date: Sun Apr 28 2019 - 22:21:06 EST


Signed-off-by: Jason Wang <jasowang@xxxxxxxxxx>
---
drivers/net/tun.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 80bff1b4ec17..03715f605fb5 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -698,6 +698,7 @@ static void __tun_detach(struct tun_file *tfile, bool clean)

rcu_assign_pointer(tun->tfiles[index],
tun->tfiles[tun->numqueues - 1]);
+ rcu_assign_pointer(tun->tfiles[tun->numqueues], NULL);
ntfile = rtnl_dereference(tun->tfiles[index]);
ntfile->queue_index = index;

@@ -1082,7 +1083,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
tfile = rcu_dereference(tun->tfiles[txq]);

/* Drop packet if interface is not attached */
- if (txq >= tun->numqueues)
+ if (!tfile)
goto drop;

if (!rcu_dereference(tun->steering_prog))
@@ -1305,15 +1306,13 @@ static int tun_xdp_xmit(struct net_device *dev, int n,

rcu_read_lock();

- numqueues = READ_ONCE(tun->numqueues);
- if (!numqueues) {
+ tfile = rcu_dereference(tun->tfiles[smp_processor_id() %
+ tun->numqueues]);
+ if (!tfile) {
rcu_read_unlock();
return -ENXIO; /* Caller will free/return all frames */
}

- tfile = rcu_dereference(tun->tfiles[smp_processor_id() %
- numqueues]);
-
spin_lock(&tfile->tx_ring.producer_lock);
for (i = 0; i < n; i++) {
struct xdp_frame *xdp = frames[i];
--
2.19.1