aboutsummaryrefslogtreecommitdiff
path: root/patches
diff options
context:
space:
mode:
authorArjan van de Ven <arjan@linux.intel.com>2010-08-21 13:15:21 -0700
committerArjan van de Ven <arjan@linux.intel.com>2010-08-21 13:15:21 -0700
commitcadb8f9a59bbb327ee993bda1e12776b8a0ce03f (patch)
tree7eb651a98ae79db3a51523f36d7bea6dede03301 /patches
parent805b4d532600631cdf482b6d39e36a137fe30fed (diff)
add workqueue support
Diffstat (limited to 'patches')
-rw-r--r--patches/0001-tracing-Make-timer-tracing-actually-useful.patch64
-rw-r--r--patches/0001-workqueue-Add-basic-tracepoints-to-track-workqueue-e.patch129
2 files changed, 193 insertions, 0 deletions
diff --git a/patches/0001-tracing-Make-timer-tracing-actually-useful.patch b/patches/0001-tracing-Make-timer-tracing-actually-useful.patch
new file mode 100644
index 0000000..1d8e21b
--- /dev/null
+++ b/patches/0001-tracing-Make-timer-tracing-actually-useful.patch
@@ -0,0 +1,64 @@
+From fe9633af11395d339880417439a1931bb9e7e493 Mon Sep 17 00:00:00 2001
+From: Arjan van de Ven <arjan@linux.intel.com>
+Date: Wed, 18 Aug 2010 15:28:59 -0400
+Subject: [PATCH] tracing: Make timer tracing actually useful
+
+PowerTOP would like to be able to trace timers.
+Unfortunately, the current timer tracing is not very useful, the actual
+timer function is not recorded in the trace at the start of timer execution.
+
+Although this is recorded for timer "start" time (when it gets armed), this
+is not useful; most timers get started early, and a tracer like PowerTOP
+will never see this event, but will only see the actual running of the timer.
+
+This patch just adds the function to the timer tracing; I've verified with
+PowerTOP that now it can get useful information about timers.
+
+Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
+---
+ include/trace/events/timer.h | 8 ++++++--
+ 1 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h
+index c624126..94511c8 100644
+--- a/include/trace/events/timer.h
++++ b/include/trace/events/timer.h
+@@ -81,14 +81,16 @@ TRACE_EVENT(timer_expire_entry,
+ TP_STRUCT__entry(
+ __field( void *, timer )
+ __field( unsigned long, now )
++ __field( void *, function )
+ ),
+
+ TP_fast_assign(
+ __entry->timer = timer;
+ __entry->now = jiffies;
++ __entry->function = timer->function;
+ ),
+
+- TP_printk("timer=%p now=%lu", __entry->timer, __entry->now)
++ TP_printk("timer=%p function=%pf now=%lu", __entry->timer, __entry->function,__entry->now)
+ );
+
+ /**
+@@ -200,14 +202,16 @@ TRACE_EVENT(hrtimer_expire_entry,
+ TP_STRUCT__entry(
+ __field( void *, hrtimer )
+ __field( s64, now )
++ __field( void *, function )
+ ),
+
+ TP_fast_assign(
+ __entry->hrtimer = hrtimer;
+ __entry->now = now->tv64;
++ __entry->function = hrtimer->function;
+ ),
+
+- TP_printk("hrtimer=%p now=%llu", __entry->hrtimer,
++ TP_printk("hrtimer=%p function=%pf now=%llu", __entry->hrtimer, __entry->function,
+ (unsigned long long)ktime_to_ns((ktime_t) { .tv64 = __entry->now }))
+ );
+
+--
+1.6.1.3
+
diff --git a/patches/0001-workqueue-Add-basic-tracepoints-to-track-workqueue-e.patch b/patches/0001-workqueue-Add-basic-tracepoints-to-track-workqueue-e.patch
new file mode 100644
index 0000000..11db56b
--- /dev/null
+++ b/patches/0001-workqueue-Add-basic-tracepoints-to-track-workqueue-e.patch
@@ -0,0 +1,129 @@
+From 1fd789ef484066ed5583c94dc03ef066cc1c0d94 Mon Sep 17 00:00:00 2001
+From: Arjan van de Ven <arjan@linux.intel.com>
+Date: Sat, 21 Aug 2010 13:07:26 -0700
+Subject: [PATCH] workqueue: Add basic tracepoints to track workqueue execution
+
+With the introduction of the new unified work queue thread pools,
+we lost one feature: It's no longer possible to know which worker
+is causing the CPU to wake out of idle. The result is that PowerTOP
+now reports a lot of "kworker/a:b" instead of more readable results.
+
+This patch adds a pair of tracepoints to the new workqueue code,
+similar in style to the timer/hrtimer tracepoints.
+
+With this pair of tracepoints, the next PowerTOP can correctly
+report which work item caused the wakeup (and how long it took):
+
+Interrupt (43) i915 time 3.51ms wakeups 141
+Work ieee80211_iface_work time 0.81ms wakeups 29
+Work do_dbs_timer time 0.55ms wakeups 24
+Process Xorg time 21.36ms wakeups 4
+Timer sched_rt_period_timer time 0.01ms wakeups 1
+
+Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
+---
+ include/trace/events/workqueue.h | 63 ++++++++++++++++++++++++++++++++++++++
+ kernel/workqueue.c | 9 +++++
+ 2 files changed, 72 insertions(+), 0 deletions(-)
+ create mode 100644 include/trace/events/workqueue.h
+
+diff --git a/include/trace/events/workqueue.h b/include/trace/events/workqueue.h
+new file mode 100644
+index 0000000..4fd2bd1
+--- /dev/null
++++ b/include/trace/events/workqueue.h
+@@ -0,0 +1,63 @@
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM workqueue
++
++#if !defined(_TRACE_WORKQUEUE_H) || defined(TRACE_HEADER_MULTI_READ)
++#define _TRACE_WORKQUEUE_H
++
++#include <linux/tracepoint.h>
++#include <linux/workqueue.h>
++
++/**
++ * workqueue_execute_start - called immediately before the workqueue callback
++ * @work: pointer to struct work_struct
++ *
++ * Allows to track workqueue execution.
++ */
++TRACE_EVENT(workqueue_execute_start,
++
++ TP_PROTO(struct work_struct *work),
++
++ TP_ARGS(work),
++
++ TP_STRUCT__entry(
++ __field( void *, work )
++ __field( void *, function)
++ ),
++
++ TP_fast_assign(
++ __entry->work = work;
++ __entry->function = work->func;
++ ),
++
++ TP_printk("work struct %p: function %pf", __entry->work, __entry->function)
++);
++
++/**
++ * workqueue_execute_end - called immediately before the workqueue callback
++ * @work: pointer to struct work_struct
++ *
++ * Allows to track workqueue execution.
++ */
++TRACE_EVENT(workqueue_execute_end,
++
++ TP_PROTO(struct work_struct *work),
++
++ TP_ARGS(work),
++
++ TP_STRUCT__entry(
++ __field( void *, work )
++ ),
++
++ TP_fast_assign(
++ __entry->work = work;
++ ),
++
++ TP_printk("work struct %p", __entry->work)
++);
++
++
++#endif /* _TRACE_WORKQUEUE_H */
++
++/* This part must be outside protection */
++#include <trace/define_trace.h>
++
+diff --git a/kernel/workqueue.c b/kernel/workqueue.c
+index 2994a0e..8bd600c 100644
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -35,6 +35,9 @@
+ #include <linux/lockdep.h>
+ #include <linux/idr.h>
+
++#define CREATE_TRACE_POINTS
++#include <trace/events/workqueue.h>
++
+ #include "workqueue_sched.h"
+
+ enum {
+@@ -1790,7 +1793,13 @@ static void process_one_work(struct worker *worker, struct work_struct *work)
+ work_clear_pending(work);
+ lock_map_acquire(&cwq->wq->lockdep_map);
+ lock_map_acquire(&lockdep_map);
++ trace_workqueue_execute_start(work);
+ f(work);
++ /*
++ * While we must be careful to not use "work" after this, the trace
++ * point will only record its address.
++ */
++ trace_workqueue_execute_end(work);
+ lock_map_release(&lockdep_map);
+ lock_map_release(&cwq->wq->lockdep_map);
+
+--
+1.7.1.1
+