| From foo@baz Thu Sep 14 23:20:08 PDT 2017 |
| From: stephen hemminger <stephen@networkplumber.org> |
| Date: Thu, 24 Aug 2017 16:49:16 -0700 |
| Subject: netvsc: fix deadlock betwen link status and removal |
| |
| From: stephen hemminger <stephen@networkplumber.org> |
| |
| |
| [ Upstream commit 9b4e946ce14e20d7addbfb7d9139e604f9fda107 ] |
| |
| There is a deadlock possible when canceling the link status |
| delayed work queue. The removal process is run with RTNL held, |
| and the link status callback is acquring RTNL. |
| |
| Resolve the issue by using trylock and rescheduling. |
| If cancel is in process, that block it from happening. |
| |
| Fixes: 122a5f6410f4 ("staging: hv: use delayed_work for netvsc_send_garp()") |
| Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/hyperv/netvsc_drv.c | 7 ++++++- |
| 1 file changed, 6 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/net/hyperv/netvsc_drv.c |
| +++ b/drivers/net/hyperv/netvsc_drv.c |
| @@ -1084,7 +1084,12 @@ static void netvsc_link_change(struct wo |
| bool notify = false, reschedule = false; |
| unsigned long flags, next_reconfig, delay; |
| |
| - rtnl_lock(); |
| + /* if changes are happening, comeback later */ |
| + if (!rtnl_trylock()) { |
| + schedule_delayed_work(&ndev_ctx->dwork, LINKCHANGE_INT); |
| + return; |
| + } |
| + |
| if (ndev_ctx->start_remove) |
| goto out_unlock; |
| |