public inbox for linux-i3c@lists.infradead.org
 help / color / mirror / Atom feed
From: Adrian Hunter <adrian.hunter@intel.com>
To: alexandre.belloni@bootlin.com
Cc: Frank.Li@nxp.com, linux-i3c@lists.infradead.org
Subject: [PATCH V2 03/14] i3c: mipi-i3c-hci: Factor out DMA mapping from queuing path
Date: Wed,  4 Mar 2026 20:16:54 +0200	[thread overview]
Message-ID: <20260304181706.143841-4-adrian.hunter@intel.com> (raw)
In-Reply-To: <20260304181706.143841-1-adrian.hunter@intel.com>

Prepare for fixing a race in the DMA ring enqueue path when handling
parallel transfers.  Move all DMA mapping out of hci_dma_queue_xfer()
and into a new helper that performs the mapping up front.

This refactoring allows the upcoming fix to extend the spinlock coverage
around the enqueue operation without performing DMA mapping under the
spinlock.

No functional change is intended in this patch.

Fixes: 9ad9a52cce282 ("i3c/master: introduce the mipi-i3c-hci driver")
Cc: stable@vger.kernel.org
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---


Changes in V2:

	New patch split out from "i3c: mipi-i3c-hci: Fix race in DMA ring
	enqueue for parallel xfers"


 drivers/i3c/master/mipi-i3c-hci/dma.c | 49 ++++++++++++++++++---------
 1 file changed, 33 insertions(+), 16 deletions(-)

diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c
index b903a2da1fd1..ba451f026386 100644
--- a/drivers/i3c/master/mipi-i3c-hci/dma.c
+++ b/drivers/i3c/master/mipi-i3c-hci/dma.c
@@ -439,6 +439,33 @@ static void hci_dma_unmap_xfer(struct i3c_hci *hci,
 	}
 }
 
+static struct i3c_dma *hci_dma_map_xfer(struct device *dev, struct hci_xfer *xfer)
+{
+	enum dma_data_direction dir = xfer->rnw ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+	bool need_bounce = device_iommu_mapped(dev) && xfer->rnw && (xfer->data_len & 3);
+
+	return i3c_master_dma_map_single(dev, xfer->data, xfer->data_len, need_bounce, dir);
+}
+
+static int hci_dma_map_xfer_list(struct i3c_hci *hci, struct device *dev,
+				 struct hci_xfer *xfer_list, int n)
+{
+	for (int i = 0; i < n; i++) {
+		struct hci_xfer *xfer = xfer_list + i;
+
+		if (!xfer->data)
+			continue;
+
+		xfer->dma = hci_dma_map_xfer(dev, xfer);
+		if (!xfer->dma) {
+			hci_dma_unmap_xfer(hci, xfer_list, i);
+			return -ENOMEM;
+		}
+	}
+
+	return 0;
+}
+
 static int hci_dma_queue_xfer(struct i3c_hci *hci,
 			      struct hci_xfer *xfer_list, int n)
 {
@@ -446,6 +473,11 @@ static int hci_dma_queue_xfer(struct i3c_hci *hci,
 	struct hci_rh_data *rh;
 	unsigned int i, ring, enqueue_ptr;
 	u32 op1_val, op2_val;
+	int ret;
+
+	ret = hci_dma_map_xfer_list(hci, rings->sysdev, xfer_list, n);
+	if (ret)
+		return ret;
 
 	/* For now we only use ring 0 */
 	ring = 0;
@@ -456,9 +488,6 @@ static int hci_dma_queue_xfer(struct i3c_hci *hci,
 	for (i = 0; i < n; i++) {
 		struct hci_xfer *xfer = xfer_list + i;
 		u32 *ring_data = rh->xfer + rh->xfer_struct_sz * enqueue_ptr;
-		enum dma_data_direction dir = xfer->rnw ? DMA_FROM_DEVICE :
-							  DMA_TO_DEVICE;
-		bool need_bounce;
 
 		/* store cmd descriptor */
 		*ring_data++ = xfer->cmd_desc[0];
@@ -477,18 +506,6 @@ static int hci_dma_queue_xfer(struct i3c_hci *hci,
 
 		/* 2nd and 3rd words of Data Buffer Descriptor Structure */
 		if (xfer->data) {
-			need_bounce = device_iommu_mapped(rings->sysdev) &&
-				      xfer->rnw &&
-				      xfer->data_len != ALIGN(xfer->data_len, 4);
-			xfer->dma = i3c_master_dma_map_single(rings->sysdev,
-							      xfer->data,
-							      xfer->data_len,
-							      need_bounce,
-							      dir);
-			if (!xfer->dma) {
-				hci_dma_unmap_xfer(hci, xfer_list, i);
-				return -ENOMEM;
-			}
 			*ring_data++ = lower_32_bits(xfer->dma->addr);
 			*ring_data++ = upper_32_bits(xfer->dma->addr);
 		} else {
@@ -511,7 +528,7 @@ static int hci_dma_queue_xfer(struct i3c_hci *hci,
 		op2_val = rh_reg_read(RING_OPERATION2);
 		if (enqueue_ptr == FIELD_GET(RING_OP2_CR_DEQ_PTR, op2_val)) {
 			/* the ring is full */
-			hci_dma_unmap_xfer(hci, xfer_list, i + 1);
+			hci_dma_unmap_xfer(hci, xfer_list, n);
 			return -EBUSY;
 		}
 	}
-- 
2.51.0


-- 
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c

  parent reply	other threads:[~2026-03-04 18:17 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-04 18:16 [PATCH V2 00/14] i3c: mipi-i3c-hci: Fixes for v7.0 Adrian Hunter
2026-03-04 18:16 ` [PATCH V2 01/14] i3c: mipi-i3c-hci: Use ETIMEDOUT instead of ETIME for timeout errors Adrian Hunter
2026-03-04 18:16 ` [PATCH V2 02/14] i3c: mipi-i3c-hci: Fix Hot-Join NACK Adrian Hunter
2026-03-04 18:16 ` Adrian Hunter [this message]
2026-03-04 19:53   ` [PATCH V2 03/14] i3c: mipi-i3c-hci: Factor out DMA mapping from queuing path Frank Li
2026-03-04 18:16 ` [PATCH V2 04/14] i3c: mipi-i3c-hci: Consolidate spinlocks Adrian Hunter
2026-03-04 19:54   ` Frank Li
2026-03-04 18:16 ` [PATCH V2 05/14] i3c: mipi-i3c-hci: Fix race in DMA ring enqueue for parallel xfers Adrian Hunter
2026-03-04 19:57   ` Frank Li
2026-03-04 18:16 ` [PATCH V2 06/14] i3c: mipi-i3c-hci: Fix race in DMA ring dequeue Adrian Hunter
2026-03-04 20:00   ` Frank Li
2026-03-05 10:13     ` Adrian Hunter
2026-03-05 15:52       ` Frank Li
2026-03-04 18:16 ` [PATCH V2 07/14] i3c: mipi-i3c-hci: Fix race between DMA ring dequeue and interrupt handler Adrian Hunter
2026-03-04 20:05   ` Frank Li
2026-03-04 18:16 ` [PATCH V2 08/14] i3c: mipi-i3c-hci: Correct RING_CTRL_ABORT handling in DMA dequeue Adrian Hunter
2026-03-04 18:17 ` [PATCH V2 09/14] i3c: mipi-i3c-hci: Add missing TID field to no-op command descriptor Adrian Hunter
2026-03-04 18:17 ` [PATCH V2 10/14] i3c: mipi-i3c-hci: Restart DMA ring correctly after dequeue abort Adrian Hunter
2026-03-04 18:17 ` [PATCH V2 11/14] i3c: mipi-i3c-hci: Consolidate common xfer processing logic Adrian Hunter
2026-03-04 18:17 ` [PATCH V2 12/14] i3c: mipi-i3c-hci: Fix race in DMA error handling in interrupt context Adrian Hunter
2026-03-04 20:09   ` Frank Li
2026-03-04 18:17 ` [PATCH V2 13/14] i3c: mipi-i3c-hci: Fix handling of shared IRQs during early initialization Adrian Hunter
2026-03-04 20:11   ` Frank Li
2026-03-04 18:17 ` [PATCH V2 14/14] i3c: mipi-i3c-hci: Fallback to software reset when bus disable fails Adrian Hunter

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=20260304181706.143841-4-adrian.hunter@intel.com \
    --to=adrian.hunter@intel.com \
    --cc=Frank.Li@nxp.com \
    --cc=alexandre.belloni@bootlin.com \
    --cc=linux-i3c@lists.infradead.org \
    /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