1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
#! stap
global pidnames, faults, fault_types
probe kernel.function(%( kernel_v > "2.6.9" %? "__handle_mm_fault"
%: "handle_mm_fault" %)) {
# Maintain a pid-to-execname mapping. This logic should get transplanted
# into a tapset script that is automatically included upon reference to
# its exported global variable.
pidnames[pid()] = execname()
faults [pid(), $write_access ? 1 : 0] ++
}
# (needed only until bug 1132 supports $retvalue)
function get_retvalue:long () %{ THIS->__retvalue = fetch_register(0); %}
probe kernel.function(%( kernel_v > "2.6.9" %? "__handle_mm_fault"
%: "handle_mm_fault" %)).return {
fault_types [pid(), get_retvalue()] ++
}
# 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
function report () {
print ("time=" . _(gettimeofday_s()) . "\n")
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")
}
delete faults
delete fault_types
}
probe begin {
print ("Page fault tracking, start time=" . _(gettimeofday_s()) . "\n")
}
probe end {
print ("Page fault tracking, end time=" . _(gettimeofday_s()) . "\n")
}
|