Re: [PATCH] PERF(kernel): Cleanup power events V2

Pierre Tardy
2010-10-26T16:56:58Z

> I would like to see a slightly more advanced tracepoint do the runtime pm
> framework;
> specifically I'd like to see the "comm" of the process that's taking a
> refcount on a device
> (that way, powertop can track which process keeps a device busy)
>
>
Yes, the "comm" for this tracepoint should be the runtime_pm workqueue.
To track responsabilities, I'm making another tracepoint, that traces
the rpm_get/put.

diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 0f38447..54d9911 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -792,7 +792,7 @@ EXPORT_SYMBOL_GPL(pm_request_resume);
int __pm_runtime_get(struct device *dev, bool sync)
{
int retval;

+ trace_runtime_pm_usage(dev, atomic_read(&dev->power.usage_count)+1);
atomic_inc(&dev->power.usage_count);
retval = sync ? pm_runtime_resume(dev) : pm_request_resume(dev);

@@ -813,6 +813,7 @@ int __pm_runtime_put(struct device *dev, bool sync)
{
int retval = 0;

+ trace_runtime_pm_usage(dev, atomic_read(&dev->power.usage_count)-1);
if (atomic_dec_and_test(&dev->power.usage_count))
retval = sync ? pm_runtime_idle(dev) : pm_request_idle(dev);

@@ -1065,6 +1066,7 @@ void pm_runtime_forbid(struct device *dev)
goto out;

dev->power.runtime_auto = false;
+ trace_runtime_pm_usage(dev, atomic_read(&dev->power.usage_count)+1);
atomic_inc(&dev->power.usage_count);
__pm_runtime_resume(dev, false);

@@ -1086,6 +1088,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))
__pm_runtime_idle(dev);
diff --git a/include/trace/events/power.h b/include/trace/events/power.h
index ea514eb..813229c 100644
--- a/include/trace/events/power.h
+++ b/include/trace/events/power.h
@@ -100,6 +100,29 @@ TRACE_EVENT(runtime_pm_status,
TP_printk("driver=%s dev=%s prev_status=%s status=%s",
__get_str(drivername),__get_str(devname),
show_rpm_status_name(__entry->prev_status),
show_rpm_status_name(__entry->status))
);
+TRACE_EVENT(runtime_pm_usage,
+
+ TP_PROTO(struct device *dev, int new_usage),
+
+ TP_ARGS(dev, new_usage),
+
+ TP_STRUCT__entry(
+ __string(devname,dev_name(dev))
+ __string(drivername,dev_driver_string(dev))
+ __field(u32, prev_usage)
+ __field(u32, usage)
+ ),
+
+ TP_fast_assign(
+ __assign_str(devname, dev_name(dev));
+ __assign_str(drivername, dev_driver_string(dev));
+ __entry->prev_usage = (u32)atomic_read(&dev->power.usage_count);
+ __entry->usage = (u32)new_usage;
+ ),
+
+ TP_printk("driver=%s dev=%s prev_usage=%d usage=%s",
__get_str(drivername),__get_str(devname),
+ __entry->prev_usage, __entry->usage)
+);
--
Pierre