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