summaryrefslogtreecommitdiff
path: root/mali_kbase/mali_kbase_pm.c
diff options
context:
space:
mode:
authorYiwei Zhang <zzyiwei@google.com>2021-02-25 16:43:49 +0000
committerYiwei Zhang <zzyiwei@google.com>2021-02-25 20:34:28 +0000
commit005940621e001d8473f2b290a17659c2cdf94493 (patch)
tree88c33a30804713ac638a8650fd49aa7f7371c2ae /mali_kbase/mali_kbase_pm.c
parent63fbdfe93ebfc2f77232ddb11e0ed3ccc0e11212 (diff)
downloadgpu-005940621e001d8473f2b290a17659c2cdf94493.tar.gz
mali_kbase: APC: avoid unnecessary apc request
If a second apc request is coming while the first one is still powering on the GPU, then the 2nd one should only update the apc.end_ts instead. This change adds a apc.pending to help avoid the duplicate work. If relative wake duration is not positive after GPU has been powered on, call kbase_pm_context_idle directly after to cancel out instead of queuing apc.power_off_work again. Bug: 170337464 Test: systrace and latency sensitive workload Signed-off-by: Yiwei Zhang <zzyiwei@google.com> Change-Id: I24c5745770a0be49e872e4875f05f24afc7ec87e
Diffstat (limited to 'mali_kbase/mali_kbase_pm.c')
-rw-r--r--mali_kbase/mali_kbase_pm.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/mali_kbase/mali_kbase_pm.c b/mali_kbase/mali_kbase_pm.c
index bf3001e..920fc56 100644
--- a/mali_kbase/mali_kbase_pm.c
+++ b/mali_kbase/mali_kbase_pm.c
@@ -373,10 +373,13 @@ void kbase_pm_apc_term(struct kbase_device *kbdev)
* This worker handles the power on request on mali_apc_thread.
*
* Normally it will power on the GPU and schedule a timer to power off the GPU
- * based on the requested wake duration.
+ * based on the requested wake duration. If relative wake duration is not larger
+ * than zero after GPU has been powered on, do power off here directly.
*
* If the driver is suspending, it won't power on the GPU or schedule the timer
* for powering off.
+ *
+ * apc.pending must be reset before this worker function returns.
*/
static void kbase_pm_apc_power_on_worker(struct kthread_work *data)
{
@@ -386,10 +389,15 @@ static void kbase_pm_apc_power_on_worker(struct kthread_work *data)
ktime_t cur_ts;
if (kbase_pm_context_active_handle_suspend(kbdev,
- KBASE_PM_SUSPEND_HANDLER_DONT_INCREASE))
+ KBASE_PM_SUSPEND_HANDLER_DONT_INCREASE)) {
+ mutex_lock(&kbdev->apc.lock);
+ kbdev->apc.pending = false;
+ mutex_unlock(&kbdev->apc.lock);
return;
+ }
mutex_lock(&kbdev->apc.lock);
+ kbdev->apc.pending = false;
cur_ts = ktime_get();
if (ktime_after(kbdev->apc.end_ts, cur_ts)) {
hrtimer_start(&kbdev->apc.timer,
@@ -400,10 +408,7 @@ static void kbase_pm_apc_power_on_worker(struct kthread_work *data)
}
mutex_unlock(&kbdev->apc.lock);
- /* When relative duration is non-positive, queue power off work here. */
- kthread_init_work(&kbdev->apc.power_off_work,
- kbase_pm_apc_power_off_worker);
- kthread_queue_work(&kbdev->apc.worker, &kbdev->apc.power_off_work);
+ kbase_pm_context_idle(kbdev);
}
void kbase_pm_apc_request(struct kbase_device *kbdev, u32 dur_usec)
@@ -414,7 +419,7 @@ void kbase_pm_apc_request(struct kbase_device *kbdev, u32 dur_usec)
req_ts = ktime_add_us(ktime_get(),
min(dur_usec, (u32)KBASE_APC_MAX_DUR_USEC));
if (!ktime_after(req_ts, kbdev->apc.end_ts))
- goto out;
+ goto out_unlock;
/* When the return value of hrtimer_try_to_cancel() is:
* 1: Timer is canceled, so restart to extend wake duration and exit.
@@ -426,16 +431,21 @@ void kbase_pm_apc_request(struct kbase_device *kbdev, u32 dur_usec)
hrtimer_start(&kbdev->apc.timer,
ktime_sub(req_ts, kbdev->apc.end_ts),
HRTIMER_MODE_REL);
- goto out;
+ goto out_unlock;
}
kbdev->apc.end_ts = req_ts;
- mutex_unlock(&kbdev->apc.lock);
- kthread_init_work(&kbdev->apc.power_on_work,
- kbase_pm_apc_power_on_worker);
- kthread_queue_work(&kbdev->apc.worker, &kbdev->apc.power_on_work);
- return;
+ if (!kbdev->apc.pending) {
+ kbdev->apc.pending = true;
+ mutex_unlock(&kbdev->apc.lock);
+
+ kthread_init_work(&kbdev->apc.power_on_work,
+ kbase_pm_apc_power_on_worker);
+ kthread_queue_work(&kbdev->apc.worker,
+ &kbdev->apc.power_on_work);
+ return;
+ }
-out:
+out_unlock:
mutex_unlock(&kbdev->apc.lock);
}