diff options
author | Yiwei Zhang <zzyiwei@google.com> | 2021-02-25 16:43:49 +0000 |
---|---|---|
committer | Yiwei Zhang <zzyiwei@google.com> | 2021-02-25 20:34:28 +0000 |
commit | 005940621e001d8473f2b290a17659c2cdf94493 (patch) | |
tree | 88c33a30804713ac638a8650fd49aa7f7371c2ae /mali_kbase/mali_kbase_pm.c | |
parent | 63fbdfe93ebfc2f77232ddb11e0ed3ccc0e11212 (diff) | |
download | gpu-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.c | 38 |
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); } |