Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0afacebf authored by Suman Tatiraju's avatar Suman Tatiraju
Browse files

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: default avatarSuman Tatiraju <sumant@codeaurora.org>
parent 1c10389d
Loading
Loading
Loading
Loading
+14 −2
Original line number Original line Diff line number Diff line
@@ -2142,7 +2142,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
@@ -2155,7 +2155,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;
}
}