Skip to content

Commit 29900bf

Browse files
selvintxavierrleon
authored andcommitted
RDMA/bnxt_re: Fix hang during driver unload
Driver unload hits a hang during stress testing of load/unload. stack trace snippet - tasklet_kill at ffffffff9aabb8b2 bnxt_qplib_nq_stop_irq at ffffffffc0a805fb [bnxt_re] bnxt_qplib_disable_nq at ffffffffc0a80c5b [bnxt_re] bnxt_re_dev_uninit at ffffffffc0a67d15 [bnxt_re] bnxt_re_remove_device at ffffffffc0a6af1d [bnxt_re] tasklet_kill can hang if the tasklet is scheduled after it is disabled. Modified the sequences to disable the interrupt first and synchronize irq before disabling the tasklet. Fixes: 1ac5a40 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Signed-off-by: Kashyap Desai <[email protected]> Signed-off-by: Selvin Xavier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Leon Romanovsky <[email protected]>
1 parent b5bbc65 commit 29900bf

File tree

2 files changed

+9
-10
lines changed

2 files changed

+9
-10
lines changed

drivers/infiniband/hw/bnxt_re/qplib_fp.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -420,19 +420,19 @@ void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill)
420420
if (!nq->requested)
421421
return;
422422

423-
tasklet_disable(&nq->nq_tasklet);
423+
nq->requested = false;
424424
/* Mask h/w interrupt */
425425
bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, false);
426426
/* Sync with last running IRQ handler */
427427
synchronize_irq(nq->msix_vec);
428-
if (kill)
429-
tasklet_kill(&nq->nq_tasklet);
430-
431428
irq_set_affinity_hint(nq->msix_vec, NULL);
432429
free_irq(nq->msix_vec, nq);
433430
kfree(nq->name);
434431
nq->name = NULL;
435-
nq->requested = false;
432+
433+
if (kill)
434+
tasklet_kill(&nq->nq_tasklet);
435+
tasklet_disable(&nq->nq_tasklet);
436436
}
437437

438438
void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq)

drivers/infiniband/hw/bnxt_re/qplib_rcfw.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -989,19 +989,18 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill)
989989
if (!creq->requested)
990990
return;
991991

992-
tasklet_disable(&creq->creq_tasklet);
992+
creq->requested = false;
993993
/* Mask h/w interrupts */
994994
bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, false);
995995
/* Sync with last running IRQ-handler */
996996
synchronize_irq(creq->msix_vec);
997-
if (kill)
998-
tasklet_kill(&creq->creq_tasklet);
999-
1000997
free_irq(creq->msix_vec, rcfw);
1001998
kfree(creq->irq_name);
1002999
creq->irq_name = NULL;
1003-
creq->requested = false;
10041000
atomic_set(&rcfw->rcfw_intr_enabled, 0);
1001+
if (kill)
1002+
tasklet_kill(&creq->creq_tasklet);
1003+
tasklet_disable(&creq->creq_tasklet);
10051004
}
10061005

10071006
void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw)

0 commit comments

Comments
 (0)