[PORT FROM R2] trace/runtime_pm: add runtime_pm trace event
authorPierre Tardy <pierre.tardy@intel.com>
Fri, 22 Oct 2010 08:07:07 +0000 (03:07 -0500)
committerbuildbot <buildbot@intel.com>
Fri, 17 Feb 2012 23:43:04 +0000 (15:43 -0800)
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 <pierre.tardy@intel.com>
Reviewed-on: http://android.intel.com:8080/35159
Reviewed-by: Martin, LoicX <loicx.martin@intel.com>
Reviewed-by: Gross, Mark <mark.gross@intel.com>
Tested-by: Martin, LoicX <loicx.martin@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
drivers/base/power/runtime.c
include/linux/pm_runtime.h
include/trace/events/power.h
kernel/trace/power-traces.c

index 577f4fd..c2aaf6c 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/sched.h>
 #include <linux/pm_runtime.h>
+#include <trace/events/power.h>
 #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);
        }
index 878cf84..b9a264f 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/device.h>
 #include <linux/pm.h>
+#include <trace/events/power.h>
 
 #include <linux/jiffies.h>
 
@@ -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)
index 1bcc2a8..8b9a83d 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <linux/ktime.h>
 #include <linux/tracepoint.h>
+#include <linux/device.h>
 
 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 */
index f55fcf6..e8c213a 100644 (file)
@@ -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