Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 349626
b: refs/heads/master
c: 9e85722
h: refs/heads/master
v: v3
  • Loading branch information
Jason Wang authored and David S. Miller committed Jan 29, 2013
1 parent 71b4df7 commit 72262a2
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2b8b328b61c799957a456a5a8dab8cc7dea68575
refs/heads/master: 9e85722d58ca9d49d718929184492a1180bced3c
25 changes: 16 additions & 9 deletions trunk/drivers/net/tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,11 +298,12 @@ static void tun_flow_cleanup(unsigned long data)
}

static void tun_flow_update(struct tun_struct *tun, u32 rxhash,
u16 queue_index)
struct tun_file *tfile)
{
struct hlist_head *head;
struct tun_flow_entry *e;
unsigned long delay = tun->ageing_time;
u16 queue_index = tfile->queue_index;

if (!rxhash)
return;
Expand All @@ -311,7 +312,9 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash,

rcu_read_lock();

if (tun->numqueues == 1)
/* We may get a very small possibility of OOO during switching, not
* worth to optimize.*/
if (tun->numqueues == 1 || tfile->detached)
goto unlock;

e = tun_flow_find(head, rxhash);
Expand Down Expand Up @@ -411,21 +414,21 @@ static void __tun_detach(struct tun_file *tfile, bool clean)

tun = rtnl_dereference(tfile->tun);

if (tun) {
if (tun && !tfile->detached) {
u16 index = tfile->queue_index;
BUG_ON(index >= tun->numqueues);
dev = tun->dev;

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

--tun->numqueues;
if (clean)
if (clean) {
rcu_assign_pointer(tfile->tun, NULL);
sock_put(&tfile->sk);
else
} else
tun_disable_queue(tun, tfile);

synchronize_net();
Expand Down Expand Up @@ -473,6 +476,10 @@ static void tun_detach_all(struct net_device *dev)
rcu_assign_pointer(tfile->tun, NULL);
--tun->numqueues;
}
list_for_each_entry(tfile, &tun->disabled, next) {
wake_up_all(&tfile->wq.wait);
rcu_assign_pointer(tfile->tun, NULL);
}
BUG_ON(tun->numqueues != 0);

synchronize_net();
Expand Down Expand Up @@ -503,7 +510,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
goto out;

err = -EINVAL;
if (rtnl_dereference(tfile->tun))
if (rtnl_dereference(tfile->tun) && !tfile->detached)
goto out;

err = -EBUSY;
Expand Down Expand Up @@ -1202,7 +1209,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
tun->dev->stats.rx_packets++;
tun->dev->stats.rx_bytes += len;

tun_flow_update(tun, rxhash, tfile->queue_index);
tun_flow_update(tun, rxhash, tfile);
return total_len;
}

Expand Down Expand Up @@ -1816,7 +1823,7 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
ret = tun_attach(tun, file);
} else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {
tun = rtnl_dereference(tfile->tun);
if (!tun || !(tun->flags & TUN_TAP_MQ))
if (!tun || !(tun->flags & TUN_TAP_MQ) || tfile->detached)
ret = -EINVAL;
else
__tun_detach(tfile, false);
Expand Down

0 comments on commit 72262a2

Please sign in to comment.