[PATCH 05/16] NTB: ntb_transport: Run RX processing on system workqueue
From: Koichiro Den <hidden>
Date: 2026-08-10 16:51:55
Also in:
lkml
Subsystem:
ntb driver core, the rest · Maintainers:
Jon Mason, Dave Jiang, Allen Hubbe, Linus Torvalds
Doorbell interrupts run every QP's RX tasklet on the IRQ CPU. With several queues, completion and replenishment work piles up there and DMA channels can run dry. Run per-QP RX processing on system_dfl_wq. The hard IRQ only queues work, and independent QPs can run on different CPUs. Signed-off-by: Koichiro Den <redacted> --- drivers/ntb/ntb_transport.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
index 4afad4489772..463ee6f17fcb 100644
--- a/drivers/ntb/ntb_transport.c
+++ b/drivers/ntb/ntb_transport.c@@ -179,7 +179,7 @@ struct ntb_transport_qp { unsigned int rx_max_frame; unsigned int rx_alloc_entry; dma_cookie_t last_cookie; - struct tasklet_struct rxc_db_work; + struct work_struct rxc_db_work; void (*event_handler)(void *data, int status); struct delayed_work link_work;
@@ -289,7 +289,7 @@ enum { #define NTB_QP_DEF_NUM_ENTRIES 100 #define NTB_LINK_DOWN_TIMEOUT 10 -static void ntb_transport_rxc_db(unsigned long data); +static void ntb_transport_rxc_db(struct work_struct *work); static const struct ntb_ctx_ops ntb_transport_ops; static struct ntb_client ntb_transport_client; static int ntb_async_tx_submit(struct ntb_transport_qp *qp,
@@ -654,7 +654,7 @@ static irqreturn_t ntb_transport_isr(int irq, void *dev) struct ntb_transport_qp *qp = dev; if (qp->client_ready) - tasklet_schedule(&qp->rxc_db_work); + queue_work(system_dfl_wq, &qp->rxc_db_work); return IRQ_HANDLED; }
@@ -1156,7 +1156,7 @@ static void ntb_qp_link_work(struct work_struct *work) qp->event_handler(qp->cb_data, qp->link_is_up); if (qp->active) - tasklet_schedule(&qp->rxc_db_work); + queue_work(system_dfl_wq, &qp->rxc_db_work); } else if (nt->link_is_up) schedule_delayed_work(&qp->link_work, msecs_to_jiffies(NTB_LINK_DOWN_TIMEOUT));
@@ -1243,8 +1243,7 @@ static int ntb_transport_init_queue(struct ntb_transport_ctx *nt, INIT_LIST_HEAD(&qp->tx_free_q); INIT_LIST_HEAD(&qp->tx_offl_q); - tasklet_init(&qp->rxc_db_work, ntb_transport_rxc_db, - (unsigned long)qp); + INIT_WORK(&qp->rxc_db_work, ntb_transport_rxc_db); return 0; }
@@ -1693,9 +1692,10 @@ static int ntb_process_rxc(struct ntb_transport_qp *qp) return 0; } -static void ntb_transport_rxc_db(unsigned long data) +static void ntb_transport_rxc_db(struct work_struct *work) { - struct ntb_transport_qp *qp = (void *)data; + struct ntb_transport_qp *qp = + container_of(work, struct ntb_transport_qp, rxc_db_work); int rc, i; dev_dbg(&qp->ndev->pdev->dev, "%s: doorbell %d received\n",
@@ -1716,7 +1716,7 @@ static void ntb_transport_rxc_db(unsigned long data) if (i == qp->rx_max_entry) { /* there is more work to do */ if (qp->active) - tasklet_schedule(&qp->rxc_db_work); + queue_work(system_dfl_wq, &qp->rxc_db_work); } else if (ntb_db_read(qp->ndev) & BIT_ULL(qp->qp_num)) { /* the doorbell bit is set: clear it */ ntb_db_clear(qp->ndev, BIT_ULL(qp->qp_num));
@@ -1728,7 +1728,7 @@ static void ntb_transport_rxc_db(unsigned long data) * there might be some more work to do. */ if (qp->active) - tasklet_schedule(&qp->rxc_db_work); + queue_work(system_dfl_wq, &qp->rxc_db_work); } }
@@ -2233,7 +2233,7 @@ void ntb_transport_free_queue(struct ntb_transport_qp *qp) qp_bit = BIT_ULL(qp->qp_num); ntb_db_set_mask(qp->ndev, qp_bit); - tasklet_kill(&qp->rxc_db_work); + cancel_work_sync(&qp->rxc_db_work); /* Catch cleanup queued while draining RX processing. */ cancel_work_sync(&qp->link_cleanup);
@@ -2334,7 +2334,7 @@ int ntb_transport_rx_enqueue(struct ntb_transport_qp *qp, void *cb, void *data, ntb_list_add(&qp->ntb_rx_q_lock, &entry->entry, &qp->rx_pend_q); if (qp->active) - tasklet_schedule(&qp->rxc_db_work); + queue_work(system_dfl_wq, &qp->rxc_db_work); return 0; }
@@ -2528,7 +2528,7 @@ static void ntb_transport_doorbell_callback(void *data, int vector) qp = &nt->qp_vec[qp_num]; if (qp->active) - tasklet_schedule(&qp->rxc_db_work); + queue_work(system_dfl_wq, &qp->rxc_db_work); db_bits &= ~BIT_ULL(qp_num); }
--
2.51.0