Skip to content

Commit

Permalink
cxgb4: fix IRQ free race during driver unload
Browse files Browse the repository at this point in the history
[ Upstream commit 015fe6f ]

IRQs are requested during driver's ndo_open() and then later
freed up in disable_interrupts() during driver unload.
A race exists where driver can set the CXGB4_FULL_INIT_DONE
flag in ndo_open() after the disable_interrupts() in driver
unload path checks it, and hence misses calling free_irq().

Fix by unregistering netdevice first and sync with driver's
ndo_open(). This ensures disable_interrupts() checks the flag
correctly and frees up the IRQs properly.

Fixes: b37987e ("cxgb4: Disable interrupts and napi before unregistering netdev")
Signed-off-by: Shahjada Abul Husain <shahjada@chelsio.com>
Signed-off-by: Raju Rangoju <rajur@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Shahjada Abul Husain authored and gregkh committed Jul 28, 2021
1 parent d92337b commit 3714e0b
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 8 deletions.
18 changes: 10 additions & 8 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
Expand Up @@ -2643,6 +2643,9 @@ static void detach_ulds(struct adapter *adap)
{
unsigned int i;

if (!is_uld(adap))
return;

mutex_lock(&uld_mutex);
list_del(&adap->list_node);

Expand Down Expand Up @@ -7145,21 +7148,20 @@ static void remove_one(struct pci_dev *pdev)
*/
destroy_workqueue(adapter->workq);

if (is_uld(adapter)) {
detach_ulds(adapter);
t4_uld_clean_up(adapter);
}
detach_ulds(adapter);

for_each_port(adapter, i)
if (adapter->port[i]->reg_state == NETREG_REGISTERED)
unregister_netdev(adapter->port[i]);

t4_uld_clean_up(adapter);

adap_free_hma_mem(adapter);

disable_interrupts(adapter);

cxgb4_free_mps_ref_entries(adapter);

for_each_port(adapter, i)
if (adapter->port[i]->reg_state == NETREG_REGISTERED)
unregister_netdev(adapter->port[i]);

debugfs_remove_recursive(adapter->debugfs_root);

if (!is_t4(adapter->params.chip))
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c
Expand Up @@ -581,6 +581,9 @@ void t4_uld_clean_up(struct adapter *adap)
{
unsigned int i;

if (!is_uld(adap))
return;

mutex_lock(&uld_mutex);
for (i = 0; i < CXGB4_ULD_MAX; i++) {
if (!adap->uld[i].handle)
Expand Down

0 comments on commit 3714e0b

Please sign in to comment.