Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:mhocko
mmdebug-tools
bpf_trace_sys_time.py
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File bpf_trace_sys_time.py of Package mmdebug-tools
#!/usr/bin/python3 # Script to gather time spent in syscalls via BPF. The script reports for each # process syscalls it did, total time (in ns) spent in each syscall type and # number of syscalls of each type. Output looks like: # # PID COMM SCN CNT SUM # 6681 sshd 16 1 3510 # 6681 sshd 0 5 20433 # 6681 sshd 1 5 97640 # 6681 sshd 14 18 10396 # 1908 irqbalance 257 31 169720 # 6760 bpf_trace_sys_t 15 1 2077 # 1908 irqbalance 3 22 9623 # 6681 sshd 23 8 4750585528 # # Syscall numbers can be decoded to symbolic names e.g. using # /usr/include/asm/unistd_64.h or corresponding architecture syscall table. # # Note that the tool needs python3-bcc package installed. from __future__ import print_function from bcc import BPF from time import sleep import signal import ctypes import sys # define BPF program bpf_text = """ /* Hack for LLVM and 5.x kernels */ #undef asm_volatile_goto #define asm_volatile_goto(x...) #include <uapi/linux/ptrace.h> #include <linux/sched.h> #include <uapi/asm/unistd.h> #include <linux/mm.h> struct tracked_task { u64 start; char comm[TASK_COMM_LEN]; int scn; }; BPF_HASH(tasks, pid_t, struct tracked_task); #define PID_SHIFT 12 #define PID_SCN_TO_KEY(pid, scn) (((pid) << PID_SHIFT) | (scn)) struct sc_stat { u64 sum; int count; }; BPF_HASH(duration, unsigned int, struct sc_stat); static void track_current_task(int scn) { pid_t pid = (u32)bpf_get_current_pid_tgid(); struct tracked_task *tt; struct tracked_task init = {}; tt = tasks.lookup(&pid); if (tt == NULL) { init.start = bpf_ktime_get_ns(); bpf_get_current_comm(init.comm, TASK_COMM_LEN); init.scn = scn; tasks.insert(&pid, &init); } else { tt->start = bpf_ktime_get_ns(); tt->scn = scn; } } static void add_sys_time(pid_t pid, int scn, u64 len) { unsigned int key = PID_SCN_TO_KEY(pid, scn); struct sc_stat *stat; struct sc_stat init = { }; stat = duration.lookup(&key); if (!stat) { init.sum = len; init.count = 1; duration.insert(&key, &init); } else { stat->sum += len; stat->count++; } } static void untrack_current_task(void) { pid_t pid = (u32)bpf_get_current_pid_tgid(); struct tracked_task *tt; u64 end = bpf_ktime_get_ns(); tt = tasks.lookup(&pid); if (tt == NULL) return; add_sys_time(pid, tt->scn, end - tt->start); } TRACEPOINT_PROBE(raw_syscalls, sys_enter) { track_current_task(args->id); return 0; } TRACEPOINT_PROBE(raw_syscalls, sys_exit) { untrack_current_task(); return 0; } """ # load BPF program b = BPF(text=bpf_text) print("Tracing tasks. Press Ctrl-C to end.", file=sys.stderr); try: sleep(99999) except KeyboardInterrupt: print(file=sys.stderr) print("%5s %-16s %5s %5s %12s" % ("PID", "COMM", "SCN", "CNT", "SUM")) tasks = b["tasks"] calls = b["duration"] for pidscn, dur in calls.items(): pid = pidscn.value >> 12 print("%5d %-16s %5d %5d %12d" % (pid, tasks[ctypes.c_int(pid)].comm.decode("utf-8"), (pidscn.value & ((1<<12) - 1)), dur.count, dur.sum))
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor