[PATCH] iommu/arm-smmu-v3: Stop queue allocation retry at PAGE_SIZE
Robin Murphy
robin.murphy at arm.com
Tue Apr 21 08:56:47 PDT 2026
On 18/04/2026 6:31 am, leo.jiang1224 at foxmail.com wrote:
> From: LoserJL <leo.jiang1224 at foxmail.com>
>
> In arm_smmu_init_one_queue(), the loop reduces max_n_shift if
> dmam_alloc_coherent() fails. However, since dmam_alloc_coherent()
> allocates at least PAGE_SIZE, retrying with a smaller size after
> a PAGE_SIZE failure is logically redundant.
Says who? It's certainly not a guarantee offered by the DMA API itself,
and indeed some allocation paths can definitely still allocate less than
a page - e.g. anything which hits a per-device or global coherent pool.
> Moreover, if a sub-page retry were to succeed due to concurrent memory
> release, the hardware would be configured with a smaller queue depth
> despite a full page being allocated. This leads to inefficient memory
> usage and unnecessary hardware performance limitation.
>
> Terminate the loop once qsz reaches PAGE_SIZE to ensure logical
> consistency and optimal hardware configuration.
That's really not an argument - even if an allocator does happen to
over-allocate for the requested size, that is hardly the caller's
concern; and as far as "optimal" queue sizes go in this case, those very
much depend on the number of CPUs issuing commands and volume of
expected stall/PRI events - in many cases PAGE_SIZE would already be far
too small to really work well.
Also note that if we _were_ to fail to allocate a PAGE_SIZE or smaller
queue, there would be very little chance of the subsequent allocation(s)
for the stream table succeeding, so realistically the driver is probably
going to end up failing to probe in such circumstances anyway.
Thanks,
Robin.
> Signed-off-by: LoserJL <leo.jiang1224 at foxmail.com>
> ---
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index e8d7dbe495f0..e0ec118ff560 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -4418,7 +4418,14 @@ int arm_smmu_init_one_queue(struct arm_smmu_device *smmu,
> qsz = ((1 << q->llq.max_n_shift) * dwords) << 3;
> q->base = dmam_alloc_coherent(smmu->dev, qsz, &q->base_dma,
> GFP_KERNEL);
> - if (q->base || qsz < PAGE_SIZE)
> + /*
> + * If allocation succeeds, we're done. If it fails, only retry
> + * if the requested size is still larger than a page. Since
> + * dmam_alloc_coherent() allocates at least PAGE_SIZE, retrying
> + * with a sub-page size is logically redundant and could lead
> + * to sub-optimal hardware configuration.
> + */
> + if (q->base || qsz <= PAGE_SIZE)
> break;
>
> q->llq.max_n_shift--;
More information about the linux-arm-kernel
mailing list