summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--testsuite/systemtap.examples/ChangeLog5
-rw-r--r--testsuite/systemtap.examples/profiling/latencytap.stp52
2 files changed, 57 insertions, 0 deletions
diff --git a/testsuite/systemtap.examples/ChangeLog b/testsuite/systemtap.examples/ChangeLog
index 7a77d27a..810df78c 100644
--- a/testsuite/systemtap.examples/ChangeLog
+++ b/testsuite/systemtap.examples/ChangeLog
@@ -1,3 +1,8 @@
+2008-12-10 Tim Moore <timoore@redhat.com>
+
+ * profiling/latencytap.stp: Probe scheduler to identify processes
+ that have slept inordinately.
+
2008-12-09 William Cohen <wcohen@redhat.com>
* general/ansi_colors.stp:
diff --git a/testsuite/systemtap.examples/profiling/latencytap.stp b/testsuite/systemtap.examples/profiling/latencytap.stp
new file mode 100644
index 00000000..96944858
--- /dev/null
+++ b/testsuite/systemtap.examples/profiling/latencytap.stp
@@ -0,0 +1,52 @@
+#! /usr/bin/stap -g
+
+# Record the time that a process has spent asleep, and in what function
+
+global enqueued
+global sleep_time
+global process_names
+global sleep_agg
+
+function _get_sleep_time:long(rq_param:long, p_param:long)
+%{
+ struct rq *rq = (struct rq *)(unsigned long)THIS->rq_param;
+ struct task_struct *p = (struct task_struct *)(unsigned long)THIS->p_param;
+ struct sched_entity *se = &p->se;
+ u64 delta = cpu_clock(smp_processor_id()) - se->sleep_start;
+
+ if ((s64)delta < 0)
+ delta = 0;
+ THIS->__retvalue = delta;
+%}
+
+# Get the backtrace from an arbitrary task
+function task_backtrace:string (task:long)
+%{
+ _stp_stack_snprint(THIS->__retvalue, MAXSTRINGLEN,
+ task_pt_regs((struct task_struct *)THIS->task), 0, 0, MAXTRACE);
+%}
+
+probe kernel.function("enqueue_task_fair") {
+ if ($wakeup == 1) {
+ this_sleep = _get_sleep_time($rq, $p)
+ if (this_sleep > 0) {
+ sleep_time[$p->pid, task_backtrace($p)] += this_sleep
+ sleep_agg[$p->pid] <<< this_sleep
+ process_names[$p->pid] = kernel_string($p->comm)
+ }
+ }
+}
+
+global pid_sleep
+probe timer.ms(1000) {
+ foreach ([pid, backtrace] in sleep_time) {
+ pid_sleep[pid] += sleep_time[pid, backtrace]
+ }
+ foreach ([pid+] in pid_sleep) {
+ printf("%s %d %d\n", process_names[pid], @max(sleep_agg[pid]) / 1000000, @avg(sleep_agg[pid]) / 1000000)
+ }
+ # decode backtraces; unfortunately they are empty at the moment.
+ delete pid_sleep
+ delete sleep_time
+ delete process_names
+}