This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Return values for vm.pagefault.return changed with newer kernels


Frank Ch. Eigler wrote:
> William Cohen <wcohen@redhat.com> writes:
> 
>> [...]
>> Seems like the saner way to take care of this is to move the this information
>> into the tapsets/memory.stp [...]
>>
>> function vm_fault_minor(long:fault_no)
>> function vm_fault_major(long:fault_no)
>> function vm_fault_oom(long:fault_no)
>> function vm_fault_sigbus(long:fault_no)
>> function vm_fault_error(long:fault_no)
> 
> I guess we need to speculate about future uses and possible future
> changes of this stuff.  It would make about as much sense to have
> something smaller api-wise:
> 
> a single test function
>    function vm_fault_class_p(fault_number:long, class:string)
> and a variable that lists available classes
>    global vm_fault_classes:string []
> 
> ... or else to have code that converts the old style enums to new
> style bit masks in some tapset variable.
> 
> 
> - FChE

I worked out a similar function (vm_fault_contains), but using the integer
VM_FAULT_MAJOR, VM_FAULT_MINOR, etc. into the memory.stp tapset.

vm_fault_contains:long (value:long, test:long)

The patch adds the function to tapset/memory.stp and include changes to
pfaults.stp to exercise the function. The attached patched has been verified to
work with current 2.6.27 kernel on Fedora 10 and older kernel on Red Hat
Enterprise Linux 5.

Any comments on it would be appreciated.

-Will
diff --git a/tapset/memory.stp b/tapset/memory.stp
index 2d7f8b0..827017e 100644
--- a/tapset/memory.stp
+++ b/tapset/memory.stp
@@ -6,6 +6,44 @@
 // redistribute it and/or modify it under the terms of the GNU General
 // Public License (GPL); either version 2, or (at your option) any
 // later version.
+%{
+#include <linux/mm.h>
+%}
+
+global VM_FAULT_OOM=0, VM_FAULT_SIGBUS=1, VM_FAULT_MINOR=2, VM_FAULT_MAJOR=3
+global VM_FAULT_NOPAGE=4, VM_FAULT_LOCKED=5, VM_FAULT_ERROR=6
+
+function vm_fault_contains:long (value:long, test:long)
+%{
+	int res;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
+	switch (THIS->test){
+	case 0: res = THIS->value == VM_FAULT_OOM; break;
+	case 1: res = THIS->value == VM_FAULT_SIGBUS; break;
+	case 2: res = THIS->value == VM_FAULT_MINOR; break;
+	case 3: res = THIS->value == VM_FAULT_MAJOR; break;
+	default:
+		res = 0; break;
+	}
+#else
+	switch (THIS->test){
+	case 0: res = THIS->value & VM_FAULT_OOM; break;
+	case 1: res = THIS->value & VM_FAULT_SIGBUS; break;
+	case 2: /* VM_FAULT_MINOR infered by that flags off */
+		res = !((VM_FAULT_OOM | VM_FAULT_SIGBUS | VM_FAULT_MAJOR) & 
+				 THIS->value);
+		 break;
+	case 3: res = THIS->value & VM_FAULT_MAJOR; break;
+	case 4: res = THIS->value & VM_FAULT_NOPAGE; break;
+	case 5: res = THIS->value & VM_FAULT_LOCKED; break;
+	case 6: res = THIS->value & VM_FAULT_ERROR; break;
+	default:
+		res = 0;
+	}
+#endif
+	THIS->__retvalue = (res != 0);
+	return;
+%}
 
 /**
  * probe vm.pagefault - Records that a page fault occurred.
diff --git a/testsuite/systemtap.samples/pfaults.stp b/testsuite/systemtap.samples/pfaults.stp
index 577e93c..2b02c3e 100644
--- a/testsuite/systemtap.samples/pfaults.stp
+++ b/testsuite/systemtap.samples/pfaults.stp
@@ -8,51 +8,38 @@ probe vm.pagefault {
    # its exported global variable.
    pidnames[pid()] = execname()
 
-   faults [pid(), $write_access ? 1 : 0] ++
+   faults [pid(), write_access ? 1 : 0] += 1
 }
 
 probe vm.pagefault.return {
-  fault_types [pid(), $return] ++
+  p = pid()
+  fault_types[p, VM_FAULT_MINOR] += vm_fault_contains(fault_type,VM_FAULT_MINOR)
+  fault_types[p, VM_FAULT_MAJOR] += vm_fault_contains(fault_type,VM_FAULT_MAJOR)
 }
 
-
-# Some constants, to come from a future "VM tapset"
-
-global VM_FAULT_OOM, VM_FAULT_SIGBUS, VM_FAULT_MINOR, VM_FAULT_MAJOR
-probe begin {
-  VM_FAULT_OOM=-1
-  VM_FAULT_SIGBUS=0
-  VM_FAULT_MINOR=1
-  VM_FAULT_MAJOR=2
-}
-
-
-# Shut down the probing session after a while
-probe timer.ms(1000) { report() }
-probe timer.ms(10000) { exit() }
-
-function _(n) { return sprint(n) } # let's abbreviate
+probe timer.s(1) { report() }
 
 function report () {
-  print ("time=" . _(gettimeofday_s()) . "\n")
+  printf("time=%d\n", gettimeofday_s())
+  printf("%16s[%7s] %7s %7s %7s %7s\n",
+  	"exec", "pid", "reads", "writes",
+	"minor", "major")
   foreach ([pid] in pidnames) {
     if (faults[pid,0]+faults[pid,1] == 0) continue
-    print (pidnames[pid] . "[" . _(pid) . "]" .
-           " reads=" . _(faults[pid,0]) . 
-           " writes=" . _(faults[pid,1]) .
-           " oom=" . _(fault_types[pid,VM_FAULT_OOM]) .
-           " sigbus=" . _(fault_types[pid,VM_FAULT_SIGBUS]) .
-           " minor=" . _(fault_types[pid,VM_FAULT_MINOR]) .
-           " major=" . _(fault_types[pid,VM_FAULT_MAJOR]) .
-           "\n")
-    }
+    printf("%16s[%7d] %7d %7d %7d %7d\n",
+           pidnames[pid], pid,
+           faults[pid,0], faults[pid,1],
+	   fault_types[pid,VM_FAULT_MINOR],
+	   fault_types[pid,VM_FAULT_MAJOR])
+  }
+  delete pidnames
   delete faults
   delete fault_types
 }
 
 probe begin {
-  print ("Page fault tracking, start time=" . _(gettimeofday_s()) . "\n")
+  printf("Page fault tracking, start time=%d\n", gettimeofday_s())
 }
 probe end {
-  print ("Page fault tracking, end time=" . _(gettimeofday_s()) . "\n")
+  printf("Page fault tracking, end time=%d\n", gettimeofday_s())
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]