|
| 1 | +from pythonbpf import bpf, map, struct, section, bpfglobal, BPF |
| 2 | +from pythonbpf.helper import ktime |
| 3 | +from pythonbpf.maps import HashMap |
| 4 | +from pythonbpf.maps import PerfEventArray |
| 5 | +from ctypes import c_void_p, c_int64 |
| 6 | + |
| 7 | + |
| 8 | +@bpf |
| 9 | +@struct |
| 10 | +class data_t: |
| 11 | + ts: c_int64 |
| 12 | + ms: c_int64 |
| 13 | + |
| 14 | + |
| 15 | +@bpf |
| 16 | +@map |
| 17 | +def events() -> PerfEventArray: |
| 18 | + return PerfEventArray(key_size=c_int64, value_size=c_int64) |
| 19 | + |
| 20 | + |
| 21 | +@bpf |
| 22 | +@map |
| 23 | +def last() -> HashMap: |
| 24 | + return HashMap(key=c_int64, value=c_int64, max_entries=1) |
| 25 | + |
| 26 | + |
| 27 | +@bpf |
| 28 | +@section("tracepoint/syscalls/sys_enter_sync") |
| 29 | +def do_trace(ctx: c_void_p) -> c_int64: |
| 30 | + dat, dat.ts, key = data_t(), ktime(), 0 |
| 31 | + tsp = last.lookup(key) |
| 32 | + if tsp: |
| 33 | + delta = ktime() - tsp |
| 34 | + if delta < 1000000000: |
| 35 | + dat.ms = delta // 1000000 |
| 36 | + events.output(dat) |
| 37 | + last.delete(key) |
| 38 | + else: |
| 39 | + last.update(key, ktime()) |
| 40 | + return 0 # type: ignore [return-value] |
| 41 | + |
| 42 | + |
| 43 | +@bpf |
| 44 | +@bpfglobal |
| 45 | +def LICENSE() -> str: |
| 46 | + return "GPL" |
| 47 | + |
| 48 | + |
| 49 | +# Compile and load |
| 50 | +b = BPF() |
| 51 | +b.load() |
| 52 | +b.attach_all() |
| 53 | + |
| 54 | +print("Tracing for quick sync's... Ctrl-C to end") |
| 55 | + |
| 56 | +# format output |
| 57 | +start = 0 |
| 58 | + |
| 59 | + |
| 60 | +def callback(cpu, event): |
| 61 | + global start |
| 62 | + if start == 0: |
| 63 | + start = event.ts |
| 64 | + event.ts -= start |
| 65 | + print( |
| 66 | + f"At time {event.ts / 1e9} s: Multiple sync detected, Last sync: {event.ms} ms ago" |
| 67 | + ) |
| 68 | + |
| 69 | + |
| 70 | +perf = b["events"].open_perf_buffer(callback, struct_name="data_t") |
| 71 | +print("Starting to poll... (Ctrl+C to stop)") |
| 72 | +print("Try running: fork() or clone() system calls to trigger events") |
| 73 | + |
| 74 | +try: |
| 75 | + while True: |
| 76 | + b["events"].poll(1000) |
| 77 | +except KeyboardInterrupt: |
| 78 | + print("Stopping...") |
0 commit comments