Skip to content

Commit d6144f3

Browse files
Ivan Vecerathangqn-ampere
Ivan Vecera
authored andcommitted
iavf: Detach device during reset task
[ Upstream commit aa626da ] iavf_reset_task() takes crit_lock at the beginning and holds it during whole call. The function subsequently calls iavf_init_interrupt_scheme() that grabs RTNL. Problem occurs when userspace initiates during the reset task any ndo callback that runs under RTNL like iavf_open() because some of that functions tries to take crit_lock. This leads to classic A-B B-A deadlock scenario. To resolve this situation the device should be detached in iavf_reset_task() prior taking crit_lock to avoid subsequent ndos running under RTNL and reattach the device at the end. Fixes: 62fe2a8 ("i40evf: add missing rtnl_lock() around i40evf_set_interrupt_capability") Cc: Jacob Keller <[email protected]> Cc: Patryk Piotrowski <[email protected]> Cc: SlawomirX Laba <[email protected]> Tested-by: Vitaly Grinberg <[email protected]> Signed-off-by: Ivan Vecera <[email protected]> Tested-by: Konrad Jankowski <[email protected]> Signed-off-by: Tony Nguyen <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 648ede0 commit d6144f3

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

drivers/net/ethernet/intel/iavf/iavf_main.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2222,14 +2222,19 @@ static void iavf_reset_task(struct work_struct *work)
22222222
int i = 0, err;
22232223
bool running;
22242224

2225+
/* Detach interface to avoid subsequent NDO callbacks */
2226+
rtnl_lock();
2227+
netif_device_detach(netdev);
2228+
rtnl_unlock();
2229+
22252230
/* When device is being removed it doesn't make sense to run the reset
22262231
* task, just return in such a case.
22272232
*/
22282233
if (!mutex_trylock(&adapter->crit_lock)) {
22292234
if (adapter->state != __IAVF_REMOVE)
22302235
queue_work(iavf_wq, &adapter->reset_task);
22312236

2232-
return;
2237+
goto reset_finish;
22332238
}
22342239

22352240
while (!mutex_trylock(&adapter->client_lock))
@@ -2299,7 +2304,6 @@ static void iavf_reset_task(struct work_struct *work)
22992304

23002305
if (running) {
23012306
netif_carrier_off(netdev);
2302-
netif_tx_stop_all_queues(netdev);
23032307
adapter->link_up = false;
23042308
iavf_napi_disable_all(adapter);
23052309
}
@@ -2412,7 +2416,7 @@ static void iavf_reset_task(struct work_struct *work)
24122416
mutex_unlock(&adapter->client_lock);
24132417
mutex_unlock(&adapter->crit_lock);
24142418

2415-
return;
2419+
goto reset_finish;
24162420
reset_err:
24172421
if (running) {
24182422
set_bit(__IAVF_VSI_DOWN, adapter->vsi.state);
@@ -2423,6 +2427,10 @@ static void iavf_reset_task(struct work_struct *work)
24232427
mutex_unlock(&adapter->client_lock);
24242428
mutex_unlock(&adapter->crit_lock);
24252429
dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n");
2430+
reset_finish:
2431+
rtnl_lock();
2432+
netif_device_attach(netdev);
2433+
rtnl_unlock();
24262434
}
24272435

24282436
/**

0 commit comments

Comments
 (0)