From 8f42d066aa4c04d9247cb36b87c855670973a03c Mon Sep 17 00:00:00 2001 From: Huang Yiwei Date: Mon, 26 Sep 2022 14:53:11 +0800 Subject: [PATCH] ANDROID: timer: Add vendor hook for timer calc index timer wheel calculates the index for any timer based on the expiry value and level granularity of the timer. Due to the level granularity timer will not fire at the exact time instead expire at a time value expires + granularity. This is done in the timer code when the index for each timer is calculated based on the expiry and granularity at each level: expires = (expires >> LVL_SHIFT(lvl)) + 1; For devfreq drivers the requirement is to fire the timer at the exact time. If the timer does not expire at the exact time then it'll take much longer to react and increase the device frequency. Devfreq driver registers timer for 10ms expiry and due to slack in timer code the expirty happens at 20 ms. For eg: Frame rendering time is 16ms. If devfreq driver reacts after 20ms instead of 10ms, that's way past a frame rendering time. Timers with 10ms to 630ms expiry fall under level 0, to overcome the granularity issue for level 0 with low expirty values do not add the granularity by introducing a new calc_index vendor hook. Bug: 178758017 Change-Id: I13cdf541e4c1bd426ce28b7a8a17cb8381eb2a92 Signed-off-by: Huang Yiwei --- drivers/android/vendor_hooks.c | 2 ++ include/trace/hooks/timer.h | 19 +++++++++++++++++++ kernel/time/timer.c | 3 +++ 3 files changed, 24 insertions(+) create mode 100644 include/trace/hooks/timer.h diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 4c94ea4b716a..6f6fb66dc7f5 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -37,6 +37,7 @@ #include #include #include +#include /* * Export tracepoints that act as a bare tracehook (ie: have no trace event @@ -109,3 +110,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rproc_recovery); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rproc_recovery_set); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_uninterruptible_tasks); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_uninterruptible_tasks_dn); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_timer_calc_index); diff --git a/include/trace/hooks/timer.h b/include/trace/hooks/timer.h new file mode 100644 index 000000000000..174d958e4c31 --- /dev/null +++ b/include/trace/hooks/timer.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM timer + +#define TRACE_INCLUDE_PATH trace/hooks + +#if !defined(_TRACE_HOOK_TIMER_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_TIMER_H + +#include +#include + +DECLARE_HOOK(android_vh_timer_calc_index, + TP_PROTO(unsigned int lvl, unsigned long *expires), + TP_ARGS(lvl, expires)); + +#endif /* _TRACE_HOOK_TIMER_H */ +/* This part must be outside protection */ +#include diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 717fcb9fb14a..0ba4c1615f1c 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -56,6 +56,8 @@ #define CREATE_TRACE_POINTS #include +#undef CREATE_TRACE_POINTS +#include __visible u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES; @@ -525,6 +527,7 @@ static inline unsigned calc_index(unsigned long expires, unsigned lvl, * * Round up with level granularity to prevent this. */ + trace_android_vh_timer_calc_index(lvl, &expires); expires = (expires >> LVL_SHIFT(lvl)) + 1; *bucket_expiry = expires << LVL_SHIFT(lvl); return LVL_OFFS(lvl) + (expires & LVL_MASK);