Re: [PATCH net-next v2 1/4] NTB: ntb_transport: Order RX descriptor reads after completion
From: Dave Jiang <dave.jiang@intel.com>
Date: 2026-08-19 16:41:05
Also in:
lkml
On 8/16/26 11:49 PM, Koichiro Den wrote:
The peer writes payloads and descriptors into a DMA-coherent memory
window. ntb_process_rxc() checks DESC_DONE_FLAG before consuming the
descriptor and payload, but coherent memory alone does not order those
reads on weakly ordered CPUs.
Read the completion word once and issue dma_rmb() after DONE is observed.
Use the saved word for subsequent transport flag checks.
Fixes: fce8a7bb5b4b ("PCI-Express Non-Transparent Bridge Support")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://lore.kernel.org/r/20260815032932.151F11F000E9@smtp.kernel.org/
Signed-off-by: Koichiro Den <redacted>Reviewed-by: Dave Jiang <dave.jiang@intel.com>
quoted hunk ↗ jump to hunk
--- Changes in v2: - New patch. (Sashiko) drivers/ntb/ntb_transport.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c index f59f926d4bfa..d458a8b1de11 100644 --- a/drivers/ntb/ntb_transport.c +++ b/drivers/ntb/ntb_transport.c@@ -1609,21 +1609,25 @@ static int ntb_process_rxc(struct ntb_transport_qp *qp) { struct ntb_payload_header *hdr; struct ntb_queue_entry *entry; + unsigned int flags; void *offset; offset = qp->rx_buff + qp->rx_max_frame * qp->rx_index; hdr = offset + qp->rx_max_frame - sizeof(struct ntb_payload_header); - dev_dbg(&qp->ndev->pdev->dev, "qp %d: RX ver %u len %d flags %x\n", - qp->qp_num, hdr->ver, hdr->len, hdr->flags); - - if (!(hdr->flags & DESC_DONE_FLAG)) { + flags = READ_ONCE(hdr->flags); + if (!(flags & DESC_DONE_FLAG)) { dev_dbg(&qp->ndev->pdev->dev, "done flag not set\n"); qp->rx_ring_empty++; return -EAGAIN; } - if (hdr->flags & LINK_DOWN_FLAG) { + dma_rmb(); + + dev_dbg(&qp->ndev->pdev->dev, "qp %d: RX ver %u len %d flags %x\n", + qp->qp_num, hdr->ver, hdr->len, flags); + + if (flags & LINK_DOWN_FLAG) { dev_dbg(&qp->ndev->pdev->dev, "link down flag set\n"); ntb_qp_link_down(qp); hdr->flags = 0;