Skip to content

Commit b2e5684

Browse files
fangyu0809joergroedel
authored andcommitted
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: 856c0cf ("iommu/riscv: Command and fault queue support") Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
1 parent 7217cee commit b2e5684

1 file changed

Lines changed: 3 additions & 0 deletions

File tree

drivers/iommu/riscv/iommu.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,13 +368,16 @@ static int riscv_iommu_queue_wait(struct riscv_iommu_queue *queue,
368368
unsigned int timeout_us)
369369
{
370370
unsigned int cons = atomic_read(&queue->head);
371+
unsigned int flags = RISCV_IOMMU_CQCSR_CQMF | RISCV_IOMMU_CQCSR_CMD_TO |
372+
RISCV_IOMMU_CQCSR_CMD_ILL;
371373

372374
/* Already processed by the consumer */
373375
if ((int)(cons - index) > 0)
374376
return 0;
375377

376378
/* Monitor consumer index */
377379
return readx_poll_timeout(riscv_iommu_queue_cons, queue, cons,
380+
(riscv_iommu_readl(queue->iommu, queue->qcr) & flags) ||
378381
(int)(cons - index) > 0, 0, timeout_us);
379382
}
380383

0 commit comments

Comments
 (0)