[PATCH V2 06/14] i3c: mipi-i3c-hci: Fix race in DMA ring dequeue

Adrian Hunter adrian.hunter at intel.com
Thu Mar 5 02:13:43 PST 2026


On 04/03/2026 22:00, Frank Li wrote:
> On Wed, Mar 04, 2026 at 08:16:57PM +0200, Adrian Hunter wrote:
>> The HCI DMA dequeue path (hci_dma_dequeue_xfer()) may be invoked for
>> multiple transfers that timeout around the same time.  However, the
>> function is not serialized and can race with itself.
>>
>> When a timeout occurs, hci_dma_dequeue_xfer() stops the ring, processes
>> incomplete transfers, and then restarts the ring.  If another timeout
>> triggers a parallel call into the same function, the two instances may
>> interfere with each other - stopping or restarting the ring at unexpected
>> times.
>>
>> Add a mutex so that hci_dma_dequeue_xfer() is serialized with respect to
>> itself.
>>
>> Fixes: 9ad9a52cce282 ("i3c/master: introduce the mipi-i3c-hci driver")
>> Cc: stable at vger.kernel.org
>> Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
>> ---
>>
>>
>> Changes in V2:
>>
>> 	Mutex now defined in struct i3c_hci instead of struct hci_rh_data
>>
>>
>>  drivers/i3c/master/mipi-i3c-hci/core.c | 1 +
>>  drivers/i3c/master/mipi-i3c-hci/dma.c  | 2 ++
>>  drivers/i3c/master/mipi-i3c-hci/hci.h  | 1 +
>>  3 files changed, 4 insertions(+)
>>
>> diff --git a/drivers/i3c/master/mipi-i3c-hci/core.c b/drivers/i3c/master/mipi-i3c-hci/core.c
>> index faf5eae2409f..061e84a5c412 100644
>> --- a/drivers/i3c/master/mipi-i3c-hci/core.c
>> +++ b/drivers/i3c/master/mipi-i3c-hci/core.c
>> @@ -927,6 +927,7 @@ static int i3c_hci_probe(struct platform_device *pdev)
>>  		return -ENOMEM;
>>
>>  	spin_lock_init(&hci->lock);
>> +	mutex_init(&hci->control_mutex);
>>
>>  	/*
>>  	 * Multi-bus instances share the same MMIO address range, but not
>> diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c
>> index 74b255ad6d0f..f7d411e5e11f 100644
>> --- a/drivers/i3c/master/mipi-i3c-hci/dma.c
>> +++ b/drivers/i3c/master/mipi-i3c-hci/dma.c
>> @@ -547,6 +547,8 @@ static bool hci_dma_dequeue_xfer(struct i3c_hci *hci,
>>  	unsigned int i;
>>  	bool did_unqueue = false;
>>
>> +	guard(mutex)(&hci->control_mutex);
>> +
> 
> if dequeue use mutex, equeue also need use the same mutex protect to make
> sure no equeue happen during dequeue. Or you can guaratee equeue never
> happen when dequeue.

There are several other issues in this area, and they will be
addressed in later patch sets.

For this specific case, the enqueue path is already protected
by the existing spinlock, and we want to keep that path as lightweight
as possible.   Adding a mutex there would unnecessarily penalize the
common fast path, so it's not the right trade‑off.

Also, the ABORT handling is only relevant when a timeout occurs
while the ring is still running.  That situation only arises when the
timeout value is too aggressive or the controller ends up stuck - both
of which are rare.  Compared to ordinary error conditions (e.g. a NACK)
that stop the ring immediately, this race is lower priority.

This patch set is already quite large, so it makes sense to defer
broader coordination changes to a follow‑up series.




More information about the linux-i3c mailing list