aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/unisys/visornic
diff options
context:
space:
mode:
authorTim Sell <Timothy.Sell@unisys.com>2015-07-24 12:00:22 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-07-24 13:43:37 -0700
commit4d79002e962466d455ae4933cd404cf5a1164894 (patch)
tree690fc2d5bf0299cb2c100b116df464970577d531 /drivers/staging/unisys/visornic
parentstaging: unisys: Process more than one response per check (diff)
downloadlinux-dev-4d79002e962466d455ae4933cd404cf5a1164894.tar.xz
linux-dev-4d79002e962466d455ae4933cd404cf5a1164894.zip
staging: unisys: visornic - ensure proper net locking in tx reset logic
visornic tx reset handling is done asynchronously via a workqueue in visornic_timeout_reset(). As a result, it needs to use rtnl_lock() / rtnl_unlock() to lock against possible simultaneous close() of the network device. (I consulted the bnx2 driver as a model here, as that driver also does its tx reset handling asynchronously, just like visornic does. See bnx2_tx_timeout() and bnx2_reset_task().) Signed-off-by: Tim Sell <Timothy.Sell@unisys.com> Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/unisys/visornic')
-rw-r--r--drivers/staging/unisys/visornic/visornic_main.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c
index 9d10b85ac7eb..ec38b51eca01 100644
--- a/drivers/staging/unisys/visornic/visornic_main.c
+++ b/drivers/staging/unisys/visornic/visornic_main.c
@@ -731,6 +731,12 @@ visornic_timeout_reset(struct work_struct *work)
devdata = container_of(work, struct visornic_devdata, timeout_reset);
netdev = devdata->netdev;
+ rtnl_lock();
+ if (!netif_running(netdev)) {
+ rtnl_unlock();
+ return;
+ }
+
response = visornic_disable_with_timeout(netdev,
VISORNIC_INFINITE_RSP_WAIT);
if (response)
@@ -741,10 +747,13 @@ visornic_timeout_reset(struct work_struct *work)
if (response)
goto call_serverdown;
+ rtnl_unlock();
+
return;
call_serverdown:
visornic_serverdown(devdata, NULL);
+ rtnl_unlock();
}
/**