| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| From: Park Bumgyu <bumgyu.park@samsung.com> |
| Date: Thu, 20 Aug 2020 11:17:23 +0900 |
| Subject: NOUPSTREAM: ANDROID: cpuidle: CPU Idle related vendor hooks |
| |
| An event that gather the idle state that the cpu attempted to enter and |
| actually entered is added. Through this, the idle statistics of the cpu |
| can be obtained and used for vendor specific algorithms or for system |
| analysis. |
| |
| [CPNOTE: 27/05/21] Lee: Vendor related code - maintain forever |
| |
| Squash |
| NOUPSTREAM: ANDROID: cpuidle-psci: Add vendor hook for cpuidle psci enter and exit |
| |
| Bug: 162980647 |
| Bug: 176198732 |
| Bug: 183690687 |
| Bug: 192436062 |
| Bug: 195914333 |
| Bug: 190353898 |
| |
| Change-Id: I9c2491d524722042e881864488f7b3cf7e903d1e |
| Signed-off-by: Park Bumgyu <bumgyu.park@samsung.com> |
| --- |
| drivers/android/vendor_hooks.c | 8 ++++++++ |
| drivers/cpuidle/cpuidle-psci.c | 5 +++++ |
| drivers/cpuidle/cpuidle.c | 17 +++++++++++++++-- |
| include/trace/hooks/cpuidle.h | 25 +++++++++++++++++++++++++ |
| include/trace/hooks/cpuidle_psci.h | 25 +++++++++++++++++++++++++ |
| 5 files changed, 78 insertions(+), 2 deletions(-) |
| create mode 100644 include/trace/hooks/cpuidle.h |
| create mode 100644 include/trace/hooks/cpuidle_psci.h |
| |
| diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c |
| --- a/drivers/android/vendor_hooks.c |
| +++ b/drivers/android/vendor_hooks.c |
| @@ -11,6 +11,7 @@ |
| #include <trace/hooks/sched.h> |
| #include <trace/hooks/fpsimd.h> |
| #include <trace/hooks/dtask.h> |
| +#include <trace/hooks/cpuidle.h> |
| #include <trace/hooks/mpam.h> |
| #include <trace/hooks/wqlockup.h> |
| #include <trace/hooks/debug.h> |
| @@ -24,6 +25,8 @@ |
| #include <trace/hooks/iommu.h> |
| #include <trace/hooks/net.h> |
| #include <trace/hooks/timer.h> |
| +#include <trace/hooks/pm_domain.h> |
| +#include <trace/hooks/cpuidle_psci.h> |
| #include <trace/hooks/vmscan.h> |
| #include <trace/hooks/creds.h> |
| #include <trace/hooks/memory.h> |
| @@ -49,6 +52,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_user_nice); |
| EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_setscheduler); |
| EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_is_fpsimd_save); |
| EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sched_show_task); |
| +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpu_idle_enter); |
| +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpu_idle_exit); |
| EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mpam_set); |
| EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_find_busiest_group); |
| EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_wq_lockup_pool); |
| @@ -112,6 +117,9 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_iommu_setup_dma_ops); |
| EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ptype_head); |
| EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_kfree_skb); |
| EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_timer_calc_index); |
| +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_allow_domain_state); |
| +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpuidle_psci_enter); |
| +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpuidle_psci_exit); |
| EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_cgroup_force_kthread_migration); |
| EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_check_preempt_tick); |
| EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_check_preempt_wakeup_ignore); |
| diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c |
| --- a/drivers/cpuidle/cpuidle-psci.c |
| +++ b/drivers/cpuidle/cpuidle-psci.c |
| @@ -25,6 +25,7 @@ |
| #include <linux/string.h> |
| |
| #include <asm/cpuidle.h> |
| +#include <trace/hooks/cpuidle_psci.h> |
| |
| #include "cpuidle-psci.h" |
| #include "dt_idle_states.h" |
| @@ -67,6 +68,8 @@ static int __psci_enter_domain_idle_state(struct cpuidle_device *dev, |
| if (ret) |
| return -1; |
| |
| + trace_android_vh_cpuidle_psci_enter(dev, s2idle); |
| + |
| /* Do runtime PM to manage a hierarchical CPU toplogy. */ |
| rcu_irq_enter_irqson(); |
| if (s2idle) |
| @@ -88,6 +91,8 @@ static int __psci_enter_domain_idle_state(struct cpuidle_device *dev, |
| pm_runtime_get_sync(pd_dev); |
| rcu_irq_exit_irqson(); |
| |
| + trace_android_vh_cpuidle_psci_exit(dev, s2idle); |
| + |
| cpu_pm_exit(); |
| |
| /* Clear the domain state to start fresh when back from idle. */ |
| diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c |
| --- a/drivers/cpuidle/cpuidle.c |
| +++ b/drivers/cpuidle/cpuidle.c |
| @@ -24,6 +24,7 @@ |
| #include <linux/tick.h> |
| #include <linux/mmu_context.h> |
| #include <trace/events/power.h> |
| +#include <trace/hooks/cpuidle.h> |
| |
| #include "cpuidle.h" |
| |
| @@ -202,10 +203,21 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, |
| { |
| int entered_state; |
| |
| - struct cpuidle_state *target_state = &drv->states[index]; |
| - bool broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP); |
| + struct cpuidle_state *target_state; |
| + bool broadcast; |
| ktime_t time_start, time_end; |
| |
| + /* |
| + * The vendor hook may modify index, which means target_state and |
| + * broadcast must be assigned after the vendor hook. |
| + */ |
| + trace_android_vh_cpu_idle_enter(&index, dev); |
| + if (index < 0) |
| + return index; |
| + |
| + target_state = &drv->states[index]; |
| + broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP); |
| + |
| /* |
| * Tell the time framework to switch to a broadcast timer because our |
| * local timer will be shut down. If a local timer is used from another |
| @@ -242,6 +254,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, |
| sched_clock_idle_wakeup_event(); |
| time_end = ns_to_ktime(local_clock()); |
| trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu); |
| + trace_android_vh_cpu_idle_exit(entered_state, dev); |
| |
| /* The cpu is no longer idle or about to enter idle. */ |
| sched_idle_set_state(NULL); |
| diff --git a/include/trace/hooks/cpuidle.h b/include/trace/hooks/cpuidle.h |
| new file mode 100644 |
| --- /dev/null |
| +++ b/include/trace/hooks/cpuidle.h |
| @@ -0,0 +1,25 @@ |
| +/* SPDX-License-Identifier: GPL-2.0 */ |
| +#undef TRACE_SYSTEM |
| +#define TRACE_SYSTEM cpuidle |
| + |
| +#define TRACE_INCLUDE_PATH trace/hooks |
| + |
| +#if !defined(_TRACE_HOOK_CPUIDLE_H) || defined(TRACE_HEADER_MULTI_READ) |
| +#define _TRACE_HOOK_CPUIDLE_H |
| + |
| +#include <linux/tracepoint.h> |
| +#include <trace/hooks/vendor_hooks.h> |
| + |
| +struct cpuidle_device; |
| + |
| +DECLARE_HOOK(android_vh_cpu_idle_enter, |
| + TP_PROTO(int *state, struct cpuidle_device *dev), |
| + TP_ARGS(state, dev)) |
| +DECLARE_HOOK(android_vh_cpu_idle_exit, |
| + TP_PROTO(int state, struct cpuidle_device *dev), |
| + TP_ARGS(state, dev)) |
| + |
| +#endif /* _TRACE_HOOK_CPUIDLE_H */ |
| +/* This part must be outside protection */ |
| +#include <trace/define_trace.h> |
| + |
| diff --git a/include/trace/hooks/cpuidle_psci.h b/include/trace/hooks/cpuidle_psci.h |
| new file mode 100644 |
| --- /dev/null |
| +++ b/include/trace/hooks/cpuidle_psci.h |
| @@ -0,0 +1,25 @@ |
| +/* SPDX-License-Identifier: GPL-2.0 */ |
| +#undef TRACE_SYSTEM |
| +#define TRACE_SYSTEM cpuidle_psci |
| +#define TRACE_INCLUDE_PATH trace/hooks |
| +#if !defined(_TRACE_HOOK_CPUIDLE_PSCI_H) || defined(TRACE_HEADER_MULTI_READ) |
| +#define _TRACE_HOOK_CPUIDLE_PSCI_H |
| +#include <linux/tracepoint.h> |
| +#include <trace/hooks/vendor_hooks.h> |
| +/* |
| + * Following tracepoints are not exported in tracefs and provide a |
| + * mechanism for vendor modules to hook and extend functionality |
| + */ |
| + |
| +struct cpuidle_device; |
| +DECLARE_HOOK(android_vh_cpuidle_psci_enter, |
| + TP_PROTO(struct cpuidle_device *dev, bool s2idle), |
| + TP_ARGS(dev, s2idle)); |
| + |
| +DECLARE_HOOK(android_vh_cpuidle_psci_exit, |
| + TP_PROTO(struct cpuidle_device *dev, bool s2idle), |
| + TP_ARGS(dev, s2idle)); |
| + |
| +#endif /* _TRACE_HOOK_CPUIDLE_PSCI_H */ |
| +/* This part must be outside protection */ |
| +#include <trace/define_trace.h> |