summaryrefslogtreecommitdiff
path: root/mali_kbase/mmu
diff options
context:
space:
mode:
authorJack Diver <diverj@google.com>2022-05-05 12:00:16 +0000
committerJack Diver <diverj@google.com>2022-05-06 16:47:09 +0000
commitd6c306f413a32d460c310aab5c3f7f5449ed5599 (patch)
tree4097ffa630868fa9c3ac13c2c16d980aeac4a828 /mali_kbase/mmu
parent76ee8a596d1df56bd958e2197abcc3e8b4849171 (diff)
downloadgpu-d6c306f413a32d460c310aab5c3f7f5449ed5599.tar.gz
mali_kbase: Ensure GPU L2 is up prior to MMU cmd
Fix races where the L2 has not finished powering up before we issue an MMU command. It's possible that the power up be deferred until after a scheduled power off, and in that case l2_desired may transiently be false. Replacing the current wait, with one that explicitly waits for L2 power up ensures that we don't issue a command for L2 power up has completed. Bug: 229473975 Signed-off-by: Jack Diver <diverj@google.com> Change-Id: Ic93eaf5f5cb520e0d34a5d3df8df9be05c477260
Diffstat (limited to 'mali_kbase/mmu')
-rw-r--r--mali_kbase/mmu/mali_kbase_mmu.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/mali_kbase/mmu/mali_kbase_mmu.c b/mali_kbase/mmu/mali_kbase_mmu.c
index 91615b2..6a20a25 100644
--- a/mali_kbase/mmu/mali_kbase_mmu.c
+++ b/mali_kbase/mmu/mali_kbase_mmu.c
@@ -1895,13 +1895,18 @@ kbase_mmu_flush_invalidate_as(struct kbase_device *kbdev, struct kbase_as *as,
return;
}
- /* There's a chance that we were the second thread to take a PM reference.
- * In that case, the owner of the first reference may not have completed the
- * L2 power up yet.
- * We need to wait for that to complete before proceeding.
+ /*
+ * Taking a pm reference does not guarantee that the GPU has finished powering up.
+ * It's possible that the power up has been deferred until after a scheduled power down.
+ * We must wait here for the L2 to be powered up, and holding a pm reference guarantees that
+ * it will not be powered down afterwards.
*/
- WARN_ON_ONCE(!kbdev->pm.backend.l2_desired);
- kbase_pm_wait_for_desired_state(kbdev);
+ err = kbase_pm_wait_for_l2_powered(kbdev);
+ if (err) {
+ dev_err(kbdev->dev, "Wait for L2 power up failed, skipping MMU command");
+ /* Drop the pm ref */
+ goto idle;
+ }
/* AS transaction begin */
mutex_lock(&kbdev->mmu_hw_mutex);
@@ -1942,6 +1947,7 @@ kbase_mmu_flush_invalidate_as(struct kbase_device *kbdev, struct kbase_as *as,
mutex_unlock(&kbdev->mmu_hw_mutex);
/* AS transaction end */
+idle:
kbase_pm_context_idle(kbdev);
}