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,
|
||||
0x00000000, 0x80000000);
|
||||
|
||||
while (time_before(jiffies, wait)) {
|
||||
do {
|
||||
/*
|
||||
* If we fault, stop waiting and return an error. The dispatcher
|
||||
* 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)))
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue