Commit b2e56845 authored by Fangyu Yu's avatar Fangyu Yu Committed by Joerg Roedel
Browse files

iommu/riscv: Stop polling when CQCSR reports an error



The cmdq wait loop busy-polls the consumer index until it advances
or the software timeout expires. If the IOMMU has already signaled
a command queue failure in CQCSR, continuing to poll for progress is
pointless.

Make riscv_iommu_queue_wait() also terminate the poll when any of these
CQCSR error bits are observed.

This helps the caller return earlier in failure cases and avoids
spinning until the full timeout interval when the hardware has already
reported an error. On single-core systems in particular, the current
busy-wait can delay servicing the command-timeout interrupt until the
software timeout expires (90s by default).

Fixes: 856c0cfe ("iommu/riscv: Command and fault queue support")
Signed-off-by: default avatarFangyu Yu <fangyu.yu@linux.alibaba.com>
Signed-off-by: default avatarJoerg Roedel <joerg.roedel@amd.com>
parent 7217cee3
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -368,6 +368,8 @@ static int riscv_iommu_queue_wait(struct riscv_iommu_queue *queue,
				  unsigned int timeout_us)
{
	unsigned int cons = atomic_read(&queue->head);
	unsigned int flags = RISCV_IOMMU_CQCSR_CQMF | RISCV_IOMMU_CQCSR_CMD_TO |
			     RISCV_IOMMU_CQCSR_CMD_ILL;

	/* Already processed by the consumer */
	if ((int)(cons - index) > 0)
@@ -375,6 +377,7 @@ static int riscv_iommu_queue_wait(struct riscv_iommu_queue *queue,

	/* Monitor consumer index */
	return readx_poll_timeout(riscv_iommu_queue_cons, queue, cons,
				 (riscv_iommu_readl(queue->iommu, queue->qcr) & flags) ||
				 (int)(cons - index) > 0, 0, timeout_us);
}