mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
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: 1ac5a40479 ("RDMA/bnxt_re: Add bnxt_re RoCE driver")
Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Link: https://lore.kernel.org/r/1689322969-25402-3-git-send-email-selvin.xavier@broadcom.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
This commit is contained in:
committed by
Leon Romanovsky
parent
b5bbc65512
commit
29900bf351
@@ -420,19 +420,19 @@ void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill)
|
||||
if (!nq->requested)
|
||||
return;
|
||||
|
||||
tasklet_disable(&nq->nq_tasklet);
|
||||
nq->requested = false;
|
||||
/* Mask h/w interrupt */
|
||||
bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, false);
|
||||
/* Sync with last running IRQ handler */
|
||||
synchronize_irq(nq->msix_vec);
|
||||
if (kill)
|
||||
tasklet_kill(&nq->nq_tasklet);
|
||||
|
||||
irq_set_affinity_hint(nq->msix_vec, NULL);
|
||||
free_irq(nq->msix_vec, nq);
|
||||
kfree(nq->name);
|
||||
nq->name = NULL;
|
||||
nq->requested = false;
|
||||
|
||||
if (kill)
|
||||
tasklet_kill(&nq->nq_tasklet);
|
||||
tasklet_disable(&nq->nq_tasklet);
|
||||
}
|
||||
|
||||
void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq)
|
||||
|
||||
@@ -989,19 +989,18 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill)
|
||||
if (!creq->requested)
|
||||
return;
|
||||
|
||||
tasklet_disable(&creq->creq_tasklet);
|
||||
creq->requested = false;
|
||||
/* Mask h/w interrupts */
|
||||
bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, false);
|
||||
/* Sync with last running IRQ-handler */
|
||||
synchronize_irq(creq->msix_vec);
|
||||
if (kill)
|
||||
tasklet_kill(&creq->creq_tasklet);
|
||||
|
||||
free_irq(creq->msix_vec, rcfw);
|
||||
kfree(creq->irq_name);
|
||||
creq->irq_name = NULL;
|
||||
creq->requested = false;
|
||||
atomic_set(&rcfw->rcfw_intr_enabled, 0);
|
||||
if (kill)
|
||||
tasklet_kill(&creq->creq_tasklet);
|
||||
tasklet_disable(&creq->creq_tasklet);
|
||||
}
|
||||
|
||||
void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw)
|
||||
|
||||
Reference in New Issue
Block a user