commit 75640f70daa0e8bab73e398113ea755e23eab887
Author: William Cohen <wcohen@redhat.com>
Date: Mon Nov 12 17:24:44 2018 -0500
Adjust the periodic.stp example to work with newer Linux kernels
The data field in the timer_list struct was removed in newer kernels.
The various functions executed when a timer expires now use
container_of macros to find the struct that the timer_list was
embedded in. The periodic.stp script has been modified to use
container_of when the data field is not available.
diff --git a/testsuite/systemtap.examples/profiling/periodic.stp b/testsuite/systemtap.examples/profiling/periodic.stp
index 3b41981c0..f18f18399 100755
--- a/testsuite/systemtap.examples/profiling/periodic.stp
+++ b/testsuite/systemtap.examples/profiling/periodic.stp
@@ -7,7 +7,7 @@
#
# stap --all-modules periodic.stp
-global last_expire, period, funct, data
+global last_expire, period, funct, data, proc_info, delayed_work_info
probe kernel.trace("timer_expire_entry")
{
@@ -17,7 +17,9 @@ probe kernel.trace("timer_expire_entry")
elapsed = new_expire - old_expire
period[$timer] <<< elapsed
funct[$timer] = $timer->function
- data[$timer] = $timer->data
+ data[$timer] = @defined($timer->data) ? $timer->data : 0
+ proc_info[$timer] = @defined($timer->data) ? 0 : @container_of($timer, "struct process_timer", timer)->task
+ delayed_work_info[$timer] = @defined($timer->data) ? 0 : & @container_of($timer, "struct delayed_work", timer)
}
last_expire[$timer] = new_expire
}
@@ -29,14 +31,16 @@ function output()
foreach([timer] in period-) {
fname = symname(funct[timer])
if (fname == "process_timeout") {
+ ptr = (data[timer] ? data[timer] : proc_info[timer])
fname = sprintf("%s(%d)",
- kernel_string_n(@cast(data[timer], "struct task_struct", "kernel<linux/sched.h>")->comm, 16),
- @cast(data[timer], "struct task_struct", "kernel<linux/sched.h>")->pid)
+ kernel_string_n(@cast(ptr, "struct task_struct", "kernel<linux/sched.h>")->comm, 16),
+ @cast(ptr, "struct task_struct", "kernel<linux/sched.h>")->pid)
type="process"
} else if (fname == "delayed_work_timer_fn") {
- faddr = @defined(@cast(data[timer], "struct delayed_work", "kernel<linux/workqueue.h>")->work->func)
- ? @cast(data[timer], "struct delayed_work", "kernel<linux/workqueue.h>")->work->func
- : @cast(data[timer], "struct work_struct", "kernel<linux/workqueue.h>")->func
+ ptr = (data[timer] ? data[timer] : delayed_work_info[timer])
+ faddr = @defined(@cast(ptr, "struct delayed_work", "kernel<linux/workqueue.h>")->work->func)
+ ? @cast(ptr, "struct delayed_work", "kernel<linux/workqueue.h>")->work->func
+ : @cast(ptr, "struct work_struct", "kernel<linux/workqueue.h>")->func
fname = sprintf("%s", symname(faddr))
type="work_q"
} else {
@@ -68,5 +72,7 @@ probe timer.s($1)
delete period
delete funct
delete data
+ delete proc_info
+ delete delayed_work_info
}
%)