msm: kgsl: Fix race condition in adreno_spin_idle()
adreno_spin_idle spins for a timeout checking for gpu to idle. Sometimes due to race conditions the timeout can occur before the loop is executed. Change the logic to a do-while loop and add an extra idle check after the timeout before returning failure. CRs-Fixed: 978122 Change-Id: Idb92a0180dd8cc3e662b1ccf44d69e4bbafb29f1 Signed-off-by: Suman Tatiraju <sumant@codeaurora.org>
This commit is contained in:
parent
8a8cf1caab
commit
7cb32a4085
1 changed files with 14 additions and 2 deletions
|
@ -2165,7 +2165,7 @@ int adreno_spin_idle(struct adreno_device *adreno_dev, unsigned int timeout)
|
||||||
adreno_getreg(adreno_dev, ADRENO_REG_RBBM_STATUS) << 2,
|
adreno_getreg(adreno_dev, ADRENO_REG_RBBM_STATUS) << 2,
|
||||||
0x00000000, 0x80000000);
|
0x00000000, 0x80000000);
|
||||||
|
|
||||||
while (time_before(jiffies, wait)) {
|
do {
|
||||||
/*
|
/*
|
||||||
* If we fault, stop waiting and return an error. The dispatcher
|
* If we fault, stop waiting and return an error. The dispatcher
|
||||||
* will clean up the fault from the work queue, but we need to
|
* will clean up the fault from the work queue, but we need to
|
||||||
|
@ -2178,7 +2178,19 @@ int adreno_spin_idle(struct adreno_device *adreno_dev, unsigned int timeout)
|
||||||
|
|
||||||
if (adreno_isidle(KGSL_DEVICE(adreno_dev)))
|
if (adreno_isidle(KGSL_DEVICE(adreno_dev)))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
} while (time_before(jiffies, wait));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Under rare conditions, preemption can cause the while loop to exit
|
||||||
|
* without checking if the gpu is idle. check one last time before we
|
||||||
|
* return failure.
|
||||||
|
*/
|
||||||
|
if (adreno_gpu_fault(adreno_dev) != 0)
|
||||||
|
return -EDEADLK;
|
||||||
|
|
||||||
|
if (adreno_isidle(KGSL_DEVICE(adreno_dev)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue