Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
0efdcef
Documentation
LICENSES
arch
block
certs
crypto
drivers
fs
include
init
ipc
kernel
lib
mm
net
samples
auxdisplay
binderfs
bpf
.gitignore
Makefile
Makefile.target
README.rst
asm_goto_workaround.h
bpf_insn.h
bpf_load.c
bpf_load.h
cookie_uid_helper_example.c
cpustat_kern.c
cpustat_user.c
do_hbm_test.sh
fds_example.c
hash_func01.h
hbm.c
hbm.h
hbm_edt_kern.c
hbm_kern.h
hbm_out_kern.c
ibumad_kern.c
ibumad_user.c
lathist_kern.c
lathist_user.c
lwt_len_hist.sh
lwt_len_hist_kern.c
lwt_len_hist_user.c
map_perf_test_kern.c
map_perf_test_user.c
offwaketime_kern.c
offwaketime_user.c
parse_ldabs.c
parse_simple.c
parse_varlen.c
run_cookie_uid_helper_example.sh
sampleip_kern.c
sampleip_user.c
sock_example.c
sock_example.h
sock_flags_kern.c
sockex1_kern.c
sockex1_user.c
sockex2_kern.c
sockex2_user.c
sockex3_kern.c
sockex3_user.c
spintest_kern.c
spintest_user.c
syscall_nrs.c
syscall_tp_kern.c
syscall_tp_user.c
task_fd_query_kern.c
task_fd_query_user.c
tc_l2_redirect.sh
tc_l2_redirect_kern.c
tc_l2_redirect_user.c
tcbpf1_kern.c
tcp_basertt_kern.c
tcp_bpf.readme
tcp_bufs_kern.c
tcp_clamp_kern.c
tcp_cong_kern.c
tcp_dumpstats_kern.c
tcp_iw_kern.c
tcp_rwnd_kern.c
tcp_synrto_kern.c
tcp_tos_reflect_kern.c
test_cgrp2_array_pin.c
test_cgrp2_attach.c
test_cgrp2_sock.c
test_cgrp2_sock.sh
test_cgrp2_sock2.c
test_cgrp2_sock2.sh
test_cgrp2_tc.sh
test_cgrp2_tc_kern.c
test_cls_bpf.sh
test_current_task_under_cgroup_kern.c
test_current_task_under_cgroup_user.c
test_ipip.sh
test_lru_dist.c
test_lwt_bpf.c
test_lwt_bpf.sh
test_map_in_map_kern.c
test_map_in_map_user.c
test_overhead_kprobe_kern.c
test_overhead_raw_tp_kern.c
test_overhead_tp_kern.c
test_overhead_user.c
test_override_return.sh
test_probe_write_user_kern.c
test_probe_write_user_user.c
trace_event_kern.c
trace_event_user.c
trace_output_kern.c
trace_output_user.c
tracex1_kern.c
tracex1_user.c
tracex2_kern.c
tracex2_user.c
tracex3_kern.c
tracex3_user.c
tracex4_kern.c
tracex4_user.c
tracex5_kern.c
tracex5_user.c
tracex6_kern.c
tracex6_user.c
tracex7_kern.c
tracex7_user.c
xdp1_kern.c
xdp1_user.c
xdp2_kern.c
xdp2skb_meta.sh
xdp2skb_meta_kern.c
xdp_adjust_tail_kern.c
xdp_adjust_tail_user.c
xdp_fwd_kern.c
xdp_fwd_user.c
xdp_monitor_kern.c
xdp_monitor_user.c
xdp_redirect_cpu_kern.c
xdp_redirect_cpu_user.c
xdp_redirect_kern.c
xdp_redirect_map_kern.c
xdp_redirect_map_user.c
xdp_redirect_user.c
xdp_router_ipv4_kern.c
xdp_router_ipv4_user.c
xdp_rxq_info_kern.c
xdp_rxq_info_user.c
xdp_sample_pkts_kern.c
xdp_sample_pkts_user.c
xdp_tx_iptunnel_common.h
xdp_tx_iptunnel_kern.c
xdp_tx_iptunnel_user.c
xdpsock.h
xdpsock_kern.c
xdpsock_user.c
configfs
connector
ftrace
hidraw
hw_breakpoint
kdb
kfifo
kobject
kprobes
livepatch
mei
mic
pidfd
pktgen
qmi
rpmsg
seccomp
timers
trace_events
trace_printk
uhid
v4l
vfio-mdev
vfs
watchdog
Kconfig
Makefile
scripts
security
sound
tools
usr
virt
.clang-format
.cocciconfig
.get_maintainer.ignore
.gitattributes
.gitignore
.mailmap
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
Breadcrumbs
linux
/
samples
/
bpf
/
trace_event_user.c
Blame
Blame
Latest commit
History
History
354 lines (306 loc) · 7.92 KB
Breadcrumbs
linux
/
samples
/
bpf
/
trace_event_user.c
Top
File metadata and controls
Code
Blame
354 lines (306 loc) · 7.92 KB
Raw
// SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2016 Facebook */ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> #include <linux/perf_event.h> #include <linux/bpf.h> #include <signal.h> #include <errno.h> #include <sys/resource.h> #include <bpf/bpf.h> #include <bpf/libbpf.h> #include "perf-sys.h" #include "trace_helpers.h" #define SAMPLE_FREQ 50 static int pid; /* counts, stackmap */ static int map_fd[2]; struct bpf_program *prog; static bool sys_read_seen, sys_write_seen; static void print_ksym(__u64 addr) { struct ksym *sym; if (!addr) return; sym = ksym_search(addr); if (!sym) { printf("ksym not found. Is kallsyms loaded?\n"); return; } printf("%s;", sym->name); if (!strstr(sym->name, "sys_read")) sys_read_seen = true; else if (!strstr(sym->name, "sys_write")) sys_write_seen = true; } static void print_addr(__u64 addr) { if (!addr) return; printf("%llx;", addr); } #define TASK_COMM_LEN 16 struct key_t { char comm[TASK_COMM_LEN]; __u32 kernstack; __u32 userstack; }; static void print_stack(struct key_t *key, __u64 count) { __u64 ip[PERF_MAX_STACK_DEPTH] = {}; static bool warned; int i; printf("%3lld %s;", count, key->comm); if (bpf_map_lookup_elem(map_fd[1], &key->kernstack, ip) != 0) { printf("---;"); } else { for (i = PERF_MAX_STACK_DEPTH - 1; i >= 0; i--) print_ksym(ip[i]); } printf("-;"); if (bpf_map_lookup_elem(map_fd[1], &key->userstack, ip) != 0) { printf("---;"); } else { for (i = PERF_MAX_STACK_DEPTH - 1; i >= 0; i--) print_addr(ip[i]); } if (count < 6) printf("\r"); else printf("\n"); if (key->kernstack == -EEXIST && !warned) { printf("stackmap collisions seen. Consider increasing size\n"); warned = true; } else if ((int)key->kernstack < 0 && (int)key->userstack < 0) { printf("err stackid %d %d\n", key->kernstack, key->userstack); } } static void err_exit(int err) { kill(pid, SIGKILL); exit(err); } static void print_stacks(void) { struct key_t key = {}, next_key; __u64 value; __u32 stackid = 0, next_id; int error = 1, fd = map_fd[0], stack_map = map_fd[1]; sys_read_seen = sys_write_seen = false; while (bpf_map_get_next_key(fd, &key, &next_key) == 0) { bpf_map_lookup_elem(fd, &next_key, &value); print_stack(&next_key, value); bpf_map_delete_elem(fd, &next_key); key = next_key; } printf("\n"); if (!sys_read_seen || !sys_write_seen) { printf("BUG kernel stack doesn't contain sys_read() and sys_write()\n"); err_exit(error); } /* clear stack map */ while (bpf_map_get_next_key(stack_map, &stackid, &next_id) == 0) { bpf_map_delete_elem(stack_map, &next_id); stackid = next_id; } } static inline int generate_load(void) { if (system("dd if=/dev/zero of=/dev/null count=5000k status=none") < 0) { printf("failed to generate some load with dd: %s\n", strerror(errno)); return -1; } return 0; } static void test_perf_event_all_cpu(struct perf_event_attr *attr) { int nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); struct bpf_link **links = calloc(nr_cpus, sizeof(struct bpf_link *)); int i, pmu_fd, error = 1; if (!links) { printf("malloc of links failed\n"); goto err; } /* system wide perf event, no need to inherit */ attr->inherit = 0; /* open perf_event on all cpus */ for (i = 0; i < nr_cpus; i++) { pmu_fd = sys_perf_event_open(attr, -1, i, -1, 0); if (pmu_fd < 0) { printf("sys_perf_event_open failed\n"); goto all_cpu_err; } links[i] = bpf_program__attach_perf_event(prog, pmu_fd); if (libbpf_get_error(links[i])) { printf("bpf_program__attach_perf_event failed\n"); links[i] = NULL; close(pmu_fd); goto all_cpu_err; } } if (generate_load() < 0) goto all_cpu_err; print_stacks(); error = 0; all_cpu_err: for (i--; i >= 0; i--) bpf_link__destroy(links[i]); err: free(links); if (error) err_exit(error); } static void test_perf_event_task(struct perf_event_attr *attr) { struct bpf_link *link = NULL; int pmu_fd, error = 1; /* per task perf event, enable inherit so the "dd ..." command can be traced properly. * Enabling inherit will cause bpf_perf_prog_read_time helper failure. */ attr->inherit = 1; /* open task bound event */ pmu_fd = sys_perf_event_open(attr, 0, -1, -1, 0); if (pmu_fd < 0) { printf("sys_perf_event_open failed\n"); goto err; } link = bpf_program__attach_perf_event(prog, pmu_fd); if (libbpf_get_error(link)) { printf("bpf_program__attach_perf_event failed\n"); link = NULL; close(pmu_fd); goto err; } if (generate_load() < 0) goto err; print_stacks(); error = 0; err: bpf_link__destroy(link); if (error) err_exit(error); } static void test_bpf_perf_event(void) { struct perf_event_attr attr_type_hw = { .sample_freq = SAMPLE_FREQ, .freq = 1, .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES, }; struct perf_event_attr attr_type_sw = { .sample_freq = SAMPLE_FREQ, .freq = 1, .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_CLOCK, }; struct perf_event_attr attr_hw_cache_l1d = { .sample_freq = SAMPLE_FREQ, .freq = 1, .type = PERF_TYPE_HW_CACHE, .config = PERF_COUNT_HW_CACHE_L1D | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16), }; struct perf_event_attr attr_hw_cache_branch_miss = { .sample_freq = SAMPLE_FREQ, .freq = 1, .type = PERF_TYPE_HW_CACHE, .config = PERF_COUNT_HW_CACHE_BPU | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16), }; struct perf_event_attr attr_type_raw = { .sample_freq = SAMPLE_FREQ, .freq = 1, .type = PERF_TYPE_RAW, /* Intel Instruction Retired */ .config = 0xc0, }; struct perf_event_attr attr_type_raw_lock_load = { .sample_freq = SAMPLE_FREQ, .freq = 1, .type = PERF_TYPE_RAW, /* Intel MEM_UOPS_RETIRED.LOCK_LOADS */ .config = 0x21d0, /* Request to record lock address from PEBS */ .sample_type = PERF_SAMPLE_ADDR, /* Record address value requires precise event */ .precise_ip = 2, }; printf("Test HW_CPU_CYCLES\n"); test_perf_event_all_cpu(&attr_type_hw); test_perf_event_task(&attr_type_hw); printf("Test SW_CPU_CLOCK\n"); test_perf_event_all_cpu(&attr_type_sw); test_perf_event_task(&attr_type_sw); printf("Test HW_CACHE_L1D\n"); test_perf_event_all_cpu(&attr_hw_cache_l1d); test_perf_event_task(&attr_hw_cache_l1d); printf("Test HW_CACHE_BPU\n"); test_perf_event_all_cpu(&attr_hw_cache_branch_miss); test_perf_event_task(&attr_hw_cache_branch_miss); printf("Test Instruction Retired\n"); test_perf_event_all_cpu(&attr_type_raw); test_perf_event_task(&attr_type_raw); printf("Test Lock Load\n"); test_perf_event_all_cpu(&attr_type_raw_lock_load); test_perf_event_task(&attr_type_raw_lock_load); printf("*** PASS ***\n"); } int main(int argc, char **argv) { struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; struct bpf_object *obj = NULL; char filename[256]; int error = 1; snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); setrlimit(RLIMIT_MEMLOCK, &r); signal(SIGINT, err_exit); signal(SIGTERM, err_exit); if (load_kallsyms()) { printf("failed to process /proc/kallsyms\n"); goto cleanup; } obj = bpf_object__open_file(filename, NULL); if (libbpf_get_error(obj)) { printf("opening BPF object file failed\n"); obj = NULL; goto cleanup; } prog = bpf_object__find_program_by_name(obj, "bpf_prog1"); if (!prog) { printf("finding a prog in obj file failed\n"); goto cleanup; } /* load BPF program */ if (bpf_object__load(obj)) { printf("loading BPF object file failed\n"); goto cleanup; } map_fd[0] = bpf_object__find_map_fd_by_name(obj, "counts"); map_fd[1] = bpf_object__find_map_fd_by_name(obj, "stackmap"); if (map_fd[0] < 0 || map_fd[1] < 0) { printf("finding a counts/stackmap map in obj file failed\n"); goto cleanup; } pid = fork(); if (pid == 0) { read_trace_pipe(); return 0; } else if (pid == -1) { printf("couldn't spawn process\n"); goto cleanup; } test_bpf_perf_event(); error = 0; cleanup: bpf_object__close(obj); err_exit(error); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
You can’t perform that action at this time.