3 # userfaultfd-wrlat Summarize userfaultfd write fault latencies.
4 # Events are continuously accumulated for the
5 # run, while latency distribution histogram is
6 # dumped each 'interval' seconds.
8 # For Linux, uses BCC, eBPF.
10 # USAGE: userfaultfd-lat [interval [count]]
12 # Copyright Virtuozzo GmbH, 2020
15 # Andrey Gruzdev <andrey.gruzdev@virtuozzo.com>
17 # This work is licensed under the terms of the GNU GPL, version 2 or
18 # later. See the COPYING file in the top-level directory.
20 from __future__
import print_function
22 from ctypes
import c_ushort
, c_int
, c_ulonglong
23 from time
import sleep
27 print("USAGE: %s [interval [count]]" % argv
[0])
32 #include <uapi/linux/ptrace.h>
35 BPF_HASH(ev_start, u32, u64);
36 BPF_HISTOGRAM(ev_delta_hist, u64);
38 /* Trace UFFD page fault start event. */
39 static void do_event_start()
41 /* Using "(u32)" to drop group ID which is upper 32 bits */
42 u32 tid = (u32) bpf_get_current_pid_tgid();
43 u64 ts = bpf_ktime_get_ns();
45 ev_start.update(&tid, &ts);
48 /* Trace UFFD page fault end event. */
49 static void do_event_end()
51 /* Using "(u32)" to drop group ID which is upper 32 bits */
52 u32 tid = (u32) bpf_get_current_pid_tgid();
53 u64 ts = bpf_ktime_get_ns();
56 tsp = ev_start.lookup(&tid);
58 u64 delta = ts - (*tsp);
59 /* Transform time delta to milliseconds */
60 ev_delta_hist.increment(bpf_log2l(delta / 1000000));
61 ev_start.delete(&tid);
65 /* KPROBE for handle_userfault(). */
66 int probe_handle_userfault(struct pt_regs *ctx, struct vm_fault *vmf,
69 /* Trace only UFFD write faults. */
70 if (reason & VM_UFFD_WP) {
76 /* KRETPROBE for handle_userfault(). */
77 int retprobe_handle_userfault(struct pt_regs *ctx)
89 interval
= int(argv
[1])
94 except: # also catches -h, --help
98 b
= BPF(text
=bpf_text
)
100 b
.attach_kprobe(event
="handle_userfault", fn_name
="probe_handle_userfault")
101 b
.attach_kretprobe(event
="handle_userfault", fn_name
="retprobe_handle_userfault")
104 print("Tracing UFFD-WP write fault latency... Hit Ctrl-C to end.")
116 except KeyboardInterrupt:
120 b
["ev_delta_hist"].print_log2_hist("msecs")