1#!/usr/bin/env python3 2# Copyright (c) 2016 PLUMgrid 3# Licensed under the Apache License, Version 2.0 (the "License") 4 5import bcc 6import ctypes 7import multiprocessing 8import os 9import time 10import unittest 11 12class TestPerfCounter(unittest.TestCase): 13 def test_cycles(self): 14 text = b""" 15BPF_PERF_ARRAY(cnt1, NUM_CPUS); 16BPF_ARRAY(prev, u64, NUM_CPUS); 17BPF_HISTOGRAM(dist); 18int do_sys_getuid(void *ctx) { 19 u32 cpu = bpf_get_smp_processor_id(); 20 u64 val = cnt1.perf_read(CUR_CPU_IDENTIFIER); 21 22 if (((s64)val < 0) && ((s64)val > -256)) 23 return 0; 24 25 prev.update(&cpu, &val); 26 return 0; 27} 28int do_ret_sys_getuid(void *ctx) { 29 u32 cpu = bpf_get_smp_processor_id(); 30 u64 val = cnt1.perf_read(CUR_CPU_IDENTIFIER); 31 32 if (((s64)val < 0) && ((s64)val > -256)) 33 return 0; 34 35 u64 *prevp = prev.lookup(&cpu); 36 if (prevp) { 37 dist.increment(bpf_log2l(val - *prevp)); 38 dist.atomic_increment(bpf_log2l(val - *prevp)); 39 } 40 return 0; 41} 42""" 43 mypid = os.getpid() 44 b = bcc.BPF(text=text, debug=0, 45 cflags=["-DNUM_CPUS=%d" % multiprocessing.cpu_count()]) 46 event_name = b.get_syscall_fnname(b"getuid") 47 b.attach_kprobe(event=event_name, fn_name=b"do_sys_getuid") 48 b.attach_kretprobe(event=event_name, fn_name=b"do_ret_sys_getuid") 49 cnt1 = b[b"cnt1"] 50 try: 51 cnt1.open_perf_event(bcc.PerfType.HARDWARE, 52 bcc.PerfHWConfig.CPU_CYCLES, pid=mypid) 53 except: 54 if ctypes.get_errno() == 2: 55 raise self.skipTest("hardware events unsupported") 56 raise 57 for i in range(0, 100): 58 os.getuid() 59 b[b"dist"].print_log2_hist() 60 61if __name__ == "__main__": 62 unittest.main() 63