diff options
-rw-r--r-- | testsuite/systemtap.examples/ChangeLog | 5 | ||||
-rw-r--r-- | testsuite/systemtap.examples/profiling/latencytap.stp | 52 |
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 +} |