From b11fb45e68fdd598d50d1821f40ea54aa125c1d9 Mon Sep 17 00:00:00 2001 From: Pierre Tardy Date: Fri, 22 Oct 2010 03:07:07 -0500 Subject: [PATCH] [PORT FROM R2] trace/runtime_pm: add runtime_pm trace event BZ: 23293 based on the recent hook from Arjan for powertop statistics we add a tracepoint in order for pytimechart to display the runtime_pm activity over time, and versus other events. We also add a usage counter change tracer that will trace accountability of a runtime_resume Change-Id: Iab7cb7a09fc002c3e74e0186855edc2d0367a8b3 Orig-Change-Id: I59f8162e7129b98454752ca60c920c40ce4e8bd1 Signed-off-by: Pierre Tardy Reviewed-on: http://android.intel.com:8080/35159 Reviewed-by: Martin, LoicX Reviewed-by: Gross, Mark Tested-by: Martin, LoicX Reviewed-by: buildbot Tested-by: buildbot --- drivers/base/power/runtime.c | 17 ++++++++++++-- include/linux/pm_runtime.h | 3 +++ include/trace/events/power.h | 54 ++++++++++++++++++++++++++++++++++++++++++++ kernel/trace/power-traces.c | 4 ++++ 4 files changed, 76 insertions(+), 2 deletions(-) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 577f4fd..c2aaf6c 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -9,6 +9,7 @@ #include #include +#include #include "power.h" static int rpm_resume(struct device *dev, int rpmflags); @@ -49,6 +50,7 @@ void update_pm_runtime_accounting(struct device *dev) static void __update_runtime_status(struct device *dev, enum rpm_status status) { update_pm_runtime_accounting(dev); + trace_runtime_pm_status(dev, status); dev->power.runtime_status = status; } @@ -735,6 +737,8 @@ int __pm_runtime_idle(struct device *dev, int rpmflags) might_sleep_if(!(rpmflags & RPM_ASYNC)); if (rpmflags & RPM_GET_PUT) { + trace_runtime_pm_usage(dev, + atomic_read(&dev->power.usage_count)-1); if (!atomic_dec_and_test(&dev->power.usage_count)) return 0; } @@ -766,6 +770,8 @@ int __pm_runtime_suspend(struct device *dev, int rpmflags) might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe); if (rpmflags & RPM_GET_PUT) { + trace_runtime_pm_usage(dev, + atomic_read(&dev->power.usage_count)-1); if (!atomic_dec_and_test(&dev->power.usage_count)) return 0; } @@ -797,6 +803,7 @@ int __pm_runtime_resume(struct device *dev, int rpmflags) if (rpmflags & RPM_GET_PUT) atomic_inc(&dev->power.usage_count); + trace_runtime_pm_usage(dev, atomic_read(&dev->power.usage_count)); spin_lock_irqsave(&dev->power.lock, flags); retval = rpm_resume(dev, rpmflags); @@ -1053,6 +1060,7 @@ void pm_runtime_forbid(struct device *dev) dev->power.runtime_auto = false; atomic_inc(&dev->power.usage_count); + trace_runtime_pm_usage(dev, atomic_read(&dev->power.usage_count)); rpm_resume(dev, 0); out: @@ -1073,6 +1081,7 @@ void pm_runtime_allow(struct device *dev) goto out; dev->power.runtime_auto = true; + trace_runtime_pm_usage(dev, atomic_read(&dev->power.usage_count)-1); if (atomic_dec_and_test(&dev->power.usage_count)) rpm_idle(dev, RPM_AUTO); @@ -1141,6 +1150,8 @@ static void update_autosuspend(struct device *dev, int old_delay, int old_use) /* If it used to be allowed then prevent it. */ if (!old_use || old_delay >= 0) { atomic_inc(&dev->power.usage_count); + trace_runtime_pm_usage(dev, + atomic_read(&dev->power.usage_count)); rpm_resume(dev, 0); } } @@ -1149,9 +1160,11 @@ static void update_autosuspend(struct device *dev, int old_delay, int old_use) else { /* If it used to be prevented then allow it. */ - if (old_use && old_delay < 0) + if (old_use && old_delay < 0) { atomic_dec(&dev->power.usage_count); - + trace_runtime_pm_usage(dev, + atomic_read(&dev->power.usage_count)); + } /* Maybe we can autosuspend now. */ rpm_idle(dev, RPM_AUTO); } diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 878cf84..b9a264f 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -11,6 +11,7 @@ #include #include +#include #include @@ -59,11 +60,13 @@ static inline void pm_suspend_ignore_children(struct device *dev, bool enable) static inline void pm_runtime_get_noresume(struct device *dev) { atomic_inc(&dev->power.usage_count); + trace_runtime_pm_usage(dev, atomic_read(&dev->power.usage_count)); } static inline void pm_runtime_put_noidle(struct device *dev) { atomic_add_unless(&dev->power.usage_count, -1, 0); + trace_runtime_pm_usage(dev, atomic_read(&dev->power.usage_count)); } static inline bool device_run_wake(struct device *dev) diff --git a/include/trace/events/power.h b/include/trace/events/power.h index 1bcc2a8..8b9a83d 100644 --- a/include/trace/events/power.h +++ b/include/trace/events/power.h @@ -6,6 +6,7 @@ #include #include +#include DECLARE_EVENT_CLASS(cpu, @@ -234,6 +235,59 @@ DEFINE_EVENT(power_domain, power_domain_target, TP_ARGS(name, state, cpu_id) ); +#ifdef CONFIG_PM_RUNTIME +#define rpm_status_name(status) { RPM_##status, #status } +#define show_rpm_status_name(val) \ + __print_symbolic(val, \ + rpm_status_name(SUSPENDED), \ + rpm_status_name(SUSPENDING), \ + rpm_status_name(RESUMING), \ + rpm_status_name(ACTIVE) \ + ) +TRACE_EVENT(runtime_pm_status, + + TP_PROTO(struct device *dev, int status), + + TP_ARGS(dev, status), + + TP_STRUCT__entry( + __string(devname, dev_name(dev)) + __string(drivername, dev_driver_string(dev)) + __field(u32, status) + ), + + TP_fast_assign( + __assign_str(devname, dev_name(dev)); + __assign_str(drivername, dev_driver_string(dev)); + __entry->status = status; + ), + + TP_printk("driver=%s dev=%s status=%s", __get_str(drivername), + __get_str(devname), show_rpm_status_name(__entry->status)) +); +TRACE_EVENT(runtime_pm_usage, + + TP_PROTO(struct device *dev, int usage), + + TP_ARGS(dev, usage), + + TP_STRUCT__entry( + __string(devname, dev_name(dev)) + __string(drivername, dev_driver_string(dev)) + __field(u32, usage) + ), + + TP_fast_assign( + __assign_str(devname, dev_name(dev)); + __assign_str(drivername, dev_driver_string(dev)); + __entry->usage = (u32)usage; + ), + + TP_printk("driver=%s dev=%s usage=%d", __get_str(drivername), + __get_str(devname), __entry->usage) +); +#endif /* CONFIG_PM_RUNTIME */ + #endif /* _TRACE_POWER_H */ /* This part must be outside protection */ diff --git a/kernel/trace/power-traces.c b/kernel/trace/power-traces.c index f55fcf6..e8c213a 100644 --- a/kernel/trace/power-traces.c +++ b/kernel/trace/power-traces.c @@ -18,3 +18,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(power_start); #endif EXPORT_TRACEPOINT_SYMBOL_GPL(cpu_idle); +EXPORT_TRACEPOINT_SYMBOL_GPL(power_frequency); +#ifdef CONFIG_PM_RUNTIME +EXPORT_TRACEPOINT_SYMBOL_GPL(runtime_pm_usage); +#endif -- 2.7.4