From fd3e05b6c82ebee06f888482975172028e89382d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:24 +0200 Subject: net-tun: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/net/tun.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net/tun.c') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 0ce07a339c7e..ce5af2aa8843 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -797,6 +798,7 @@ static int tun_chr_fasync(int fd, struct file *file, int on) static int tun_chr_open(struct inode *inode, struct file * file) { + cycle_kernel_lock(); DBG1(KERN_INFO "tunX: tun_chr_open\n"); file->private_data = NULL; return 0; -- cgit From 9d319522576ce0b2fd023a965445f9c3739ee6f1 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 19 Jun 2008 15:50:37 -0600 Subject: tun: fasync BKL pushdown Signed-off-by: Jonathan Corbet --- drivers/net/tun.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/net/tun.c') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index ce5af2aa8843..4c0c5972a489 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -782,18 +782,21 @@ static int tun_chr_fasync(int fd, struct file *file, int on) DBG(KERN_INFO "%s: tun_chr_fasync %d\n", tun->dev->name, on); + lock_kernel(); if ((ret = fasync_helper(fd, file, on, &tun->fasync)) < 0) - return ret; + goto out; if (on) { ret = __f_setown(file, task_pid(current), PIDTYPE_PID, 0); if (ret) - return ret; + goto out; tun->flags |= TUN_FASYNC; } else tun->flags &= ~TUN_FASYNC; - - return 0; + ret = 0; +out: + unlock_kernel(); + return ret; } static int tun_chr_open(struct inode *inode, struct file * file) -- cgit From e35259a95331ae4a9146cc03ab49aad641cab957 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 10 Jul 2008 16:59:11 -0700 Subject: tun: Persistent devices can get stuck in xoff state The scenario goes like this. App stops reading from tun/tap. TX queue gets full and driver does netif_stop_queue(). App closes fd and TX queue gets flushed as part of the cleanup. Next time the app opens tun/tap and starts reading from it but the xoff state is not cleared. We're stuck. Normally xoff state is cleared when netdev is brought up. But in the case of persistent devices this happens only during initial setup. The fix is trivial. If device is already up when an app opens it we clear xoff state and that gets things moving again. Signed-off-by: Max Krasnyansky Tested-by: Christian Borntraeger Signed-off-by: David S. Miller --- drivers/net/tun.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net/tun.c') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 7ab94c825b57..b9018bfa0a97 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -602,6 +602,12 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) tun->attached = 1; get_net(dev_net(tun->dev)); + /* Make sure persistent devices do not get stuck in + * xoff state. + */ + if (netif_running(tun->dev)) + netif_wake_queue(tun->dev); + strcpy(ifr->ifr_name, tun->dev->name); return 0; -- cgit