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:
Suman Tatiraju 2016-02-08 10:23:48 -08:00 committed by David Keitel
parent 8a8cf1caab
commit 7cb32a4085

View file

@ -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;
}