diff options
Diffstat (limited to 'drivers/net/tun.c')
| -rw-r--r-- | drivers/net/tun.c | 15 | 
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 87a635aac008..259b2b84b2b3 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -273,6 +273,12 @@ static void tun_napi_init(struct tun_struct *tun, struct tun_file *tfile,  	}  } +static void tun_napi_enable(struct tun_file *tfile) +{ +	if (tfile->napi_enabled) +		napi_enable(&tfile->napi); +} +  static void tun_napi_disable(struct tun_file *tfile)  {  	if (tfile->napi_enabled) @@ -634,7 +640,8 @@ static void __tun_detach(struct tun_file *tfile, bool clean)  	tun = rtnl_dereference(tfile->tun);  	if (tun && clean) { -		tun_napi_disable(tfile); +		if (!tfile->detached) +			tun_napi_disable(tfile);  		tun_napi_del(tfile);  	} @@ -653,8 +660,10 @@ static void __tun_detach(struct tun_file *tfile, bool clean)  		if (clean) {  			RCU_INIT_POINTER(tfile->tun, NULL);  			sock_put(&tfile->sk); -		} else +		} else {  			tun_disable_queue(tun, tfile); +			tun_napi_disable(tfile); +		}  		synchronize_net();  		tun_flow_delete_by_queue(tun, tun->numqueues + 1); @@ -727,6 +736,7 @@ static void tun_detach_all(struct net_device *dev)  		sock_put(&tfile->sk);  	}  	list_for_each_entry_safe(tfile, tmp, &tun->disabled, next) { +		tun_napi_del(tfile);  		tun_enable_queue(tfile);  		tun_queue_purge(tfile);  		xdp_rxq_info_unreg(&tfile->xdp_rxq); @@ -807,6 +817,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file,  	if (tfile->detached) {  		tun_enable_queue(tfile); +		tun_napi_enable(tfile);  	} else {  		sock_hold(&tfile->sk);  		tun_napi_init(tun, tfile, napi, napi_frags);  | 
