xref: /aosp_15_r20/external/bcc/tests/python/test_histogram.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*387f9dfdSAndroid Build Coastguard Worker# Copyright (c) PLUMgrid, Inc.
3*387f9dfdSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License")
4*387f9dfdSAndroid Build Coastguard Worker
5*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF
6*387f9dfdSAndroid Build Coastguard Workerfrom ctypes import c_int, c_ulonglong
7*387f9dfdSAndroid Build Coastguard Workerimport random
8*387f9dfdSAndroid Build Coastguard Workerimport time
9*387f9dfdSAndroid Build Coastguard Workerfrom unittest import main, TestCase
10*387f9dfdSAndroid Build Coastguard Worker
11*387f9dfdSAndroid Build Coastguard Workerclass TestHistogram(TestCase):
12*387f9dfdSAndroid Build Coastguard Worker    def test_simple(self):
13*387f9dfdSAndroid Build Coastguard Worker        b = BPF(text=b"""
14*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h>
15*387f9dfdSAndroid Build Coastguard Workerstruct bpf_map;
16*387f9dfdSAndroid Build Coastguard WorkerBPF_HISTOGRAM(hist1);
17*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(stub);
18*387f9dfdSAndroid Build Coastguard Workerint kprobe__htab_map_delete_elem(struct pt_regs *ctx, struct bpf_map *map, u64 *k) {
19*387f9dfdSAndroid Build Coastguard Worker    hist1.increment(bpf_log2l(*k));
20*387f9dfdSAndroid Build Coastguard Worker    hist1.atomic_increment(bpf_log2l(*k));
21*387f9dfdSAndroid Build Coastguard Worker    return 0;
22*387f9dfdSAndroid Build Coastguard Worker}
23*387f9dfdSAndroid Build Coastguard Worker""")
24*387f9dfdSAndroid Build Coastguard Worker        for i in range(0, 32):
25*387f9dfdSAndroid Build Coastguard Worker            for j in range(0, random.randint(1, 10)):
26*387f9dfdSAndroid Build Coastguard Worker                try: del b[b"stub"][c_ulonglong(1 << i)]
27*387f9dfdSAndroid Build Coastguard Worker                except: pass
28*387f9dfdSAndroid Build Coastguard Worker        b[b"hist1"].print_log2_hist()
29*387f9dfdSAndroid Build Coastguard Worker
30*387f9dfdSAndroid Build Coastguard Worker        for i in range(32, 64):
31*387f9dfdSAndroid Build Coastguard Worker            for j in range(0, random.randint(1, 10)):
32*387f9dfdSAndroid Build Coastguard Worker                try: del b[b"stub"][c_ulonglong(1 << i)]
33*387f9dfdSAndroid Build Coastguard Worker                except: pass
34*387f9dfdSAndroid Build Coastguard Worker        b[b"hist1"].print_log2_hist()
35*387f9dfdSAndroid Build Coastguard Worker        b.cleanup()
36*387f9dfdSAndroid Build Coastguard Worker
37*387f9dfdSAndroid Build Coastguard Worker    def test_struct(self):
38*387f9dfdSAndroid Build Coastguard Worker        b = BPF(text=b"""
39*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h>
40*387f9dfdSAndroid Build Coastguard Workerstruct bpf_map;
41*387f9dfdSAndroid Build Coastguard Workertypedef struct { void *map; u64 slot; } Key;
42*387f9dfdSAndroid Build Coastguard WorkerBPF_HISTOGRAM(hist1, Key, 1024);
43*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(stub1);
44*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(stub2);
45*387f9dfdSAndroid Build Coastguard Workerint kprobe__htab_map_delete_elem(struct pt_regs *ctx, struct bpf_map *map, u64 *k) {
46*387f9dfdSAndroid Build Coastguard Worker    hist1.increment((Key){map, bpf_log2l(*k)});
47*387f9dfdSAndroid Build Coastguard Worker    hist1.atomic_increment((Key){map, bpf_log2l(*k)});
48*387f9dfdSAndroid Build Coastguard Worker    return 0;
49*387f9dfdSAndroid Build Coastguard Worker}
50*387f9dfdSAndroid Build Coastguard Worker""")
51*387f9dfdSAndroid Build Coastguard Worker        for i in range(0, 64):
52*387f9dfdSAndroid Build Coastguard Worker            for j in range(0, random.randint(1, 10)):
53*387f9dfdSAndroid Build Coastguard Worker                try: del b[b"stub1"][c_ulonglong(1 << i)]
54*387f9dfdSAndroid Build Coastguard Worker                except: pass
55*387f9dfdSAndroid Build Coastguard Worker                try: del b[b"stub2"][c_ulonglong(1 << i)]
56*387f9dfdSAndroid Build Coastguard Worker                except: pass
57*387f9dfdSAndroid Build Coastguard Worker        b[b"hist1"].print_log2_hist()
58*387f9dfdSAndroid Build Coastguard Worker        b.cleanup()
59*387f9dfdSAndroid Build Coastguard Worker
60*387f9dfdSAndroid Build Coastguard Worker    def test_chars(self):
61*387f9dfdSAndroid Build Coastguard Worker        b = BPF(text=b"""
62*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h>
63*387f9dfdSAndroid Build Coastguard Worker#include <linux/sched.h>
64*387f9dfdSAndroid Build Coastguard Worker#include <linux/version.h>
65*387f9dfdSAndroid Build Coastguard Workertypedef struct { char name[TASK_COMM_LEN]; u64 slot; } Key;
66*387f9dfdSAndroid Build Coastguard WorkerBPF_HISTOGRAM(hist1, Key, 1024);
67*387f9dfdSAndroid Build Coastguard Workerint kprobe__finish_task_switch(struct pt_regs *ctx, struct task_struct *prev) {
68*387f9dfdSAndroid Build Coastguard Worker#if LINUX_VERSION_CODE < KERNEL_VERSION(5,5,0)
69*387f9dfdSAndroid Build Coastguard Worker    Key k = {.slot = bpf_log2l(prev->real_start_time)};
70*387f9dfdSAndroid Build Coastguard Worker#else
71*387f9dfdSAndroid Build Coastguard Worker    Key k = {.slot = bpf_log2l(prev->start_boottime)};
72*387f9dfdSAndroid Build Coastguard Worker#endif
73*387f9dfdSAndroid Build Coastguard Worker    if (!bpf_get_current_comm(&k.name, sizeof(k.name))) {
74*387f9dfdSAndroid Build Coastguard Worker        hist1.increment(k);
75*387f9dfdSAndroid Build Coastguard Worker        hist1.atomic_increment(k);
76*387f9dfdSAndroid Build Coastguard Worker    }
77*387f9dfdSAndroid Build Coastguard Worker    return 0;
78*387f9dfdSAndroid Build Coastguard Worker}
79*387f9dfdSAndroid Build Coastguard Worker""")
80*387f9dfdSAndroid Build Coastguard Worker        for i in range(0, 100): time.sleep(0.01)
81*387f9dfdSAndroid Build Coastguard Worker        b[b"hist1"].print_log2_hist()
82*387f9dfdSAndroid Build Coastguard Worker        b.cleanup()
83*387f9dfdSAndroid Build Coastguard Worker
84*387f9dfdSAndroid Build Coastguard Worker    def test_multiple_key(self):
85*387f9dfdSAndroid Build Coastguard Worker        b = BPF(text=b"""
86*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/ptrace.h>
87*387f9dfdSAndroid Build Coastguard Worker#include <uapi/linux/fs.h>
88*387f9dfdSAndroid Build Coastguard Workerstruct hist_s_key {
89*387f9dfdSAndroid Build Coastguard Worker    u64 key_1;
90*387f9dfdSAndroid Build Coastguard Worker    u64 key_2;
91*387f9dfdSAndroid Build Coastguard Worker};
92*387f9dfdSAndroid Build Coastguard Workerstruct hist_key {
93*387f9dfdSAndroid Build Coastguard Worker    struct hist_s_key s_key;
94*387f9dfdSAndroid Build Coastguard Worker    u64 slot;
95*387f9dfdSAndroid Build Coastguard Worker};
96*387f9dfdSAndroid Build Coastguard WorkerBPF_HISTOGRAM(mk_hist, struct hist_key, 1024);
97*387f9dfdSAndroid Build Coastguard Workerint kprobe__vfs_read(struct pt_regs *ctx, struct file *file,
98*387f9dfdSAndroid Build Coastguard Worker        char __user *buf, size_t count) {
99*387f9dfdSAndroid Build Coastguard Worker    struct hist_key key = {.slot = bpf_log2l(count)};
100*387f9dfdSAndroid Build Coastguard Worker    key.s_key.key_1 = (unsigned long)buf & 0x70;
101*387f9dfdSAndroid Build Coastguard Worker    key.s_key.key_2 = (unsigned long)buf & 0x7;
102*387f9dfdSAndroid Build Coastguard Worker    mk_hist.increment(key);
103*387f9dfdSAndroid Build Coastguard Worker    return 0;
104*387f9dfdSAndroid Build Coastguard Worker}
105*387f9dfdSAndroid Build Coastguard Worker""")
106*387f9dfdSAndroid Build Coastguard Worker        def bucket_sort(buckets):
107*387f9dfdSAndroid Build Coastguard Worker            buckets.sort()
108*387f9dfdSAndroid Build Coastguard Worker            return buckets
109*387f9dfdSAndroid Build Coastguard Worker
110*387f9dfdSAndroid Build Coastguard Worker        for i in range(0, 100): time.sleep(0.01)
111*387f9dfdSAndroid Build Coastguard Worker        b[b"mk_hist"].print_log2_hist("size", "k_1 & k_2",
112*387f9dfdSAndroid Build Coastguard Worker                section_print_fn=lambda bucket: "%3d %d" % (bucket[0], bucket[1]),
113*387f9dfdSAndroid Build Coastguard Worker                bucket_fn=lambda bucket: (bucket.key_1, bucket.key_2),
114*387f9dfdSAndroid Build Coastguard Worker                strip_leading_zero=True,
115*387f9dfdSAndroid Build Coastguard Worker                bucket_sort_fn=bucket_sort)
116*387f9dfdSAndroid Build Coastguard Worker        b.cleanup()
117*387f9dfdSAndroid Build Coastguard Worker
118*387f9dfdSAndroid Build Coastguard Workerif __name__ == "__main__":
119*387f9dfdSAndroid Build Coastguard Worker    main()
120