From 4d79002e962466d455ae4933cd404cf5a1164894 Mon Sep 17 00:00:00 2001 From: Tim Sell Date: Fri, 24 Jul 2015 12:00:22 -0400 Subject: [PATCH] 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 Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visornic/visornic_main.c | 9 +++++++++ 1 file changed, 9 insertions(+) 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(); } /** -- 2.30.2