mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
iommu/arm-smmu-v3: Increase CMDQ drain timeout value
Waiting for a CMD_SYNC to be processed involves waiting for the command queue to drain, which can take an awful lot longer than waiting for a single entry to become available. Consequently, the common timeout value of 100us has been observed to be too short on some platforms when a CMD_SYNC is issued into a queued full of TLBI commands. This patch resolves the issue by using a different (1s) timeout when waiting for the CMDQ to drain and using a simple back-off mechanism when polling the cons pointer in the absence of WFE support. Signed-off-by: Sunil Goutham <sgoutham@cavium.com> [will: rewrote commit message and cosmetic changes] Signed-off-by: Will Deacon <will.deacon@arm.com>
This commit is contained in:
parent
2ea659a9ef
commit
b847de4e50
@ -408,6 +408,7 @@
|
||||
|
||||
/* High-level queue structures */
|
||||
#define ARM_SMMU_POLL_TIMEOUT_US 100
|
||||
#define ARM_SMMU_CMDQ_DRAIN_TIMEOUT_US 1000000 /* 1s! */
|
||||
|
||||
#define MSI_IOVA_BASE 0x8000000
|
||||
#define MSI_IOVA_LENGTH 0x100000
|
||||
@ -737,7 +738,13 @@ static void queue_inc_prod(struct arm_smmu_queue *q)
|
||||
*/
|
||||
static int queue_poll_cons(struct arm_smmu_queue *q, bool drain, bool wfe)
|
||||
{
|
||||
ktime_t timeout = ktime_add_us(ktime_get(), ARM_SMMU_POLL_TIMEOUT_US);
|
||||
ktime_t timeout;
|
||||
unsigned int delay = 1;
|
||||
|
||||
/* Wait longer if it's queue drain */
|
||||
timeout = ktime_add_us(ktime_get(), drain ?
|
||||
ARM_SMMU_CMDQ_DRAIN_TIMEOUT_US :
|
||||
ARM_SMMU_POLL_TIMEOUT_US);
|
||||
|
||||
while (queue_sync_cons(q), (drain ? !queue_empty(q) : queue_full(q))) {
|
||||
if (ktime_compare(ktime_get(), timeout) > 0)
|
||||
@ -747,7 +754,8 @@ static int queue_poll_cons(struct arm_smmu_queue *q, bool drain, bool wfe)
|
||||
wfe();
|
||||
} else {
|
||||
cpu_relax();
|
||||
udelay(1);
|
||||
udelay(delay);
|
||||
delay *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user