ntb_qp_link_cleanup() cancels QP link work but does not wait for the RX tasklet. The tasklet can still be processing the ring while cleanup resets the QP, and transport link cleanup can free the MW before the tasklet finishes. Clear active under rx_sched_lock and drain the tasklet before resetting the QP. Temporarily disable QP link work so a concurrent client link-up request cannot reactivate RX during cleanup, then re-enable it for the existing link setup paths. This does not drain RX DMA transfers or their completion callbacks. The next patch waits for RX DMA and its completion path to finish accessing the MW. Fixes: 9143595a7e05 ("NTB: ntb_transport: Free MWs in ntb_transport_link_cleanup()") Cc: stable@vger.kernel.org Reviewed-by: Logan Gunthorpe Reviewed-by: Dave Jiang Signed-off-by: Koichiro Den --- Changes in v3: - Refine commit message by adding a note on the RX DMA follow-up. (Dave) - Add Reviewed-by tag. No code changes. drivers/ntb/ntb_transport.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c index 30411e118a7e..9f71af97a8ef 100644 --- a/drivers/ntb/ntb_transport.c +++ b/drivers/ntb/ntb_transport.c @@ -957,11 +957,16 @@ static void ntb_qp_link_cleanup(struct ntb_transport_qp *qp) dev_info(&pdev->dev, "qp %d: Link Cleanup\n", qp->qp_num); - cancel_delayed_work_sync(&qp->link_work); + disable_delayed_work_sync(&qp->link_work); + ntb_transport_set_qp_active(qp, false); + tasklet_kill(&qp->rxc_db_work); + ntb_qp_link_down_reset(qp); if (qp->event_handler) qp->event_handler(qp->cb_data, qp->link_is_up); + + enable_delayed_work(&qp->link_work); } static void ntb_qp_link_cleanup_work(struct work_struct *work) -- 2.51.0