From: Koichiro Den <den@valinux.co.jp>
To: Jon Mason <jdmason@kudzu.us>, Dave Jiang <dave.jiang@intel.com>,
Frank Li <Frank.Li@kernel.org>, Allen Hubbe <allenbh@gmail.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Niklas Cassel <cassel@kernel.org>,
Nicholas Bellinger <nab@linux-iscsi.org>
Cc: ntb@lists.linux.dev, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 16/16] NTB: ntb_transport: Add optional polling for direct-DMA RX
Date: Tue, 11 Aug 2026 01:51:35 +0900 [thread overview]
Message-ID: <20260810165136.2292436-17-den@valinux.co.jp> (raw)
In-Reply-To: <20260810165136.2292436-1-den@valinux.co.jp>
Direct RX normally relies on peer MSI or doorbell notifications.
Polling the completion state once per jiffy lets RX buffers be recycled
sooner, keeps the DMA engine saturated, and raises the throughput
ceiling.
Add an opt-in direct_dma_poll parameter. Notification-driven operation
remains the default, so continuous polling is enabled only when
requested.
The poll continues even after all currently visible completions are
consumed. The posted MWr transactions carrying data and completion can
theoretically be overtaken by the CPU MMIO write used for peer
notification. The notification may go through another PCI function and
ordering domain. Without polling, the last completion could remain
pending if no later notification arrives. This has not been observed.
Reading back each completion destination would close this window, but
the non-posted PCIe round trip significantly lowers throughput.
Signed-off-by: Koichiro Den <den@valinux.co.jp>
---
drivers/ntb/ntb_transport.c | 35 ++++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
index 2f69328d5201..d3eb4e2106b0 100644
--- a/drivers/ntb/ntb_transport.c
+++ b/drivers/ntb/ntb_transport.c
@@ -104,6 +104,11 @@ module_param(use_direct_dma, bool, 0644);
MODULE_PARM_DESC(use_direct_dma,
"Use PCI endpoint DMA to transfer directly to peer RX buffers");
+static bool direct_dma_poll;
+module_param(direct_dma_poll, bool, 0444);
+MODULE_PARM_DESC(direct_dma_poll,
+ "Poll direct-DMA RX completion state once per jiffy");
+
static unsigned int direct_dma_func;
module_param(direct_dma_func, uint, 0644);
MODULE_PARM_DESC(direct_dma_func,
@@ -234,6 +239,7 @@ struct ntb_transport_qp {
dma_cookie_t last_cookie;
struct work_struct rxc_db_work;
struct delayed_work direct_rx_retry;
+ struct delayed_work rxc_poll;
void (*event_handler)(void *data, int status);
struct delayed_work link_work;
@@ -835,6 +841,8 @@ EXPORT_SYMBOL_GPL(ntb_transport_rx_queue_size);
static void ntb_transport_rxc_db(struct work_struct *work);
static void ntb_direct_rx_retry_work(struct work_struct *work);
+static void ntb_transport_rxc_poll(struct work_struct *work);
+static bool ntb_direct_rx_can_complete(struct ntb_transport_qp *qp);
static void ntb_direct_rx_reclaim(struct ntb_transport_qp *qp);
static const struct ntb_ctx_ops ntb_transport_ops;
static struct ntb_client ntb_transport_client;
@@ -1523,6 +1531,7 @@ static void ntb_qp_link_down_reset(struct ntb_transport_qp *qp)
if (ntb_direct_link_capable(qp)) {
qp->active = false;
cancel_delayed_work_sync(&qp->direct_rx_retry);
+ cancel_delayed_work_sync(&qp->rxc_poll);
cancel_work_sync(&qp->rxc_db_work);
/* Catch a retry armed while draining RX work. */
cancel_delayed_work_sync(&qp->direct_rx_retry);
@@ -1808,8 +1817,11 @@ static void ntb_qp_link_work(struct work_struct *work)
if (qp->event_handler)
qp->event_handler(qp->cb_data, qp->link_is_up);
- if (qp->active)
+ if (qp->active) {
+ if (direct_dma_poll && ntb_direct_rx_can_complete(qp))
+ queue_delayed_work(system_dfl_wq, &qp->rxc_poll, 1);
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));
@@ -1900,6 +1912,7 @@ static int ntb_transport_init_queue(struct ntb_transport_ctx *nt,
INIT_WORK(&qp->rxc_db_work, ntb_transport_rxc_db);
INIT_DELAYED_WORK(&qp->direct_rx_retry, ntb_direct_rx_retry_work);
+ INIT_DELAYED_WORK(&qp->rxc_poll, ntb_transport_rxc_poll);
return 0;
}
@@ -2629,6 +2642,25 @@ static void ntb_transport_rxc_db(struct work_struct *work)
}
}
+static void ntb_transport_rxc_poll(struct work_struct *work)
+{
+ struct ntb_transport_qp *qp =
+ container_of(work, struct ntb_transport_qp, rxc_poll.work);
+ bool completion, control;
+
+ if (!qp->active || !ntb_direct_rx_can_complete(qp))
+ return;
+
+ control = ntb_direct_control_pending(qp);
+ completion = ntb_direct_rx_completion_word(qp);
+
+ if (completion || control)
+ queue_work(system_dfl_wq, &qp->rxc_db_work);
+
+ /* keep checking completion and control state */
+ queue_delayed_work(system_dfl_wq, &qp->rxc_poll, 1);
+}
+
static void ntb_tx_copy_callback(void *data,
const struct dmaengine_result *res)
{
@@ -3517,6 +3549,7 @@ void ntb_transport_free_queue(struct ntb_transport_qp *qp)
ntb_db_set_mask(qp->ndev, qp_bit);
cancel_delayed_work_sync(&qp->direct_rx_retry);
+ cancel_delayed_work_sync(&qp->rxc_poll);
cancel_work_sync(&qp->rxc_db_work);
/* Catch a retry armed while draining RX work. */
cancel_delayed_work_sync(&qp->direct_rx_retry);
--
2.51.0
prev parent reply other threads:[~2026-08-10 16:52 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-10 16:51 [PATCH 00/16] NTB: Add direct TX/RX using PCI endpoint DMA Koichiro Den
2026-08-10 16:51 ` [PATCH 01/16] NTB: ntb_transport: Abort link setup on QP MW allocation failure Koichiro Den
2026-08-10 18:41 ` Frank Li
2026-08-10 16:51 ` [PATCH 02/16] NTB: ntb_transport: Reject oversized TX buffers Koichiro Den
2026-08-10 16:51 ` [PATCH 03/16] NTB: ntb_transport: Start TX offload thread after queue setup Koichiro Den
2026-08-10 16:51 ` [PATCH 04/16] NTB: ntb_transport: Stop QP work before freeing a queue Koichiro Den
2026-08-10 16:51 ` [PATCH 05/16] NTB: ntb_transport: Run RX processing on system workqueue Koichiro Den
2026-08-10 16:51 ` [PATCH 06/16] NTB: ntb_transport: Define direct-DMA shared state Koichiro Den
2026-08-10 16:51 ` [PATCH 07/16] NTB: ntb_transport: Negotiate direct-DMA queue layout Koichiro Den
2026-08-10 16:51 ` [PATCH 08/16] NTB: ntb_transport: Add opt-in direct-DMA channel reservation Koichiro Den
2026-08-10 16:51 ` [PATCH 09/16] NTB: ntb_transport: Allocate direct-DMA queue state Koichiro Den
2026-08-10 16:51 ` [PATCH 10/16] NTB: ntb_transport: Implement direct-DMA QP session handshake Koichiro Den
2026-08-10 16:51 ` [PATCH 11/16] NTB: ntb_transport: Implement direct-DMA RX buffer publication Koichiro Den
2026-08-10 16:51 ` [PATCH 12/16] NTB: ntb_transport: Implement direct-DMA TX submission Koichiro Den
2026-08-10 16:51 ` [PATCH 13/16] NTB: ntb_transport: Implement safe direct-DMA teardown Koichiro Den
2026-08-10 16:51 ` [PATCH 14/16] NTB: ntb_transport: Enable direct-DMA queues Koichiro Den
2026-08-10 17:04 ` Koichiro Den
2026-08-10 16:51 ` [PATCH 15/16] NTB: ntb_transport: Report the direct-DMA payload limit Koichiro Den
2026-08-10 16:51 ` Koichiro Den [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260810165136.2292436-17-den@valinux.co.jp \
--to=den@valinux.co.jp \
--cc=Frank.Li@kernel.org \
--cc=allenbh@gmail.com \
--cc=cassel@kernel.org \
--cc=dave.jiang@intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=jdmason@kudzu.us \
--cc=linux-kernel@vger.kernel.org \
--cc=nab@linux-iscsi.org \
--cc=netdev@vger.kernel.org \
--cc=ntb@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox