aboutsummaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
authorAndrii Nakryiko <andriin@fb.com>2019-07-23 17:34:44 -0400
committerAlexei Starovoitov <ast@kernel.org>2019-07-23 19:05:42 -0400
commitc17bec549c9dc969b4e725c56aa9ebb125378397 (patch)
tree23335974151011cdad8183fffed21db675ea75d1 /samples
parentf58a4d51d8da7b248d8796e9981feb3d5a43d3d2 (diff)
samples/bpf: switch trace_output sample to perf_buffer API
Convert trace_output sample to libbpf's perf_buffer API. Signed-off-by: Andrii Nakryiko <andriin@fb.com> Acked-by: Song Liu <songliubraving@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'samples')
-rw-r--r--samples/bpf/trace_output_user.c43
1 files changed, 14 insertions, 29 deletions
diff --git a/samples/bpf/trace_output_user.c b/samples/bpf/trace_output_user.c
index 2dd1d39b152a..8ee47699a870 100644
--- a/samples/bpf/trace_output_user.c
+++ b/samples/bpf/trace_output_user.c
@@ -18,9 +18,6 @@
18#include <libbpf.h> 18#include <libbpf.h>
19#include "bpf_load.h" 19#include "bpf_load.h"
20#include "perf-sys.h" 20#include "perf-sys.h"
21#include "trace_helpers.h"
22
23static int pmu_fd;
24 21
25static __u64 time_get_ns(void) 22static __u64 time_get_ns(void)
26{ 23{
@@ -31,12 +28,12 @@ static __u64 time_get_ns(void)
31} 28}
32 29
33static __u64 start_time; 30static __u64 start_time;
31static __u64 cnt;
34 32
35#define MAX_CNT 100000ll 33#define MAX_CNT 100000ll
36 34
37static int print_bpf_output(void *data, int size) 35static void print_bpf_output(void *ctx, int cpu, void *data, __u32 size)
38{ 36{
39 static __u64 cnt;
40 struct { 37 struct {
41 __u64 pid; 38 __u64 pid;
42 __u64 cookie; 39 __u64 cookie;
@@ -45,7 +42,7 @@ static int print_bpf_output(void *data, int size)
45 if (e->cookie != 0x12345678) { 42 if (e->cookie != 0x12345678) {
46 printf("BUG pid %llx cookie %llx sized %d\n", 43 printf("BUG pid %llx cookie %llx sized %d\n",
47 e->pid, e->cookie, size); 44 e->pid, e->cookie, size);
48 return LIBBPF_PERF_EVENT_ERROR; 45 return;
49 } 46 }
50 47
51 cnt++; 48 cnt++;
@@ -53,30 +50,14 @@ static int print_bpf_output(void *data, int size)
53 if (cnt == MAX_CNT) { 50 if (cnt == MAX_CNT) {
54 printf("recv %lld events per sec\n", 51 printf("recv %lld events per sec\n",
55 MAX_CNT * 1000000000ll / (time_get_ns() - start_time)); 52 MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
56 return LIBBPF_PERF_EVENT_DONE; 53 return;
57 } 54 }
58
59 return LIBBPF_PERF_EVENT_CONT;
60}
61
62static void test_bpf_perf_event(void)
63{
64 struct perf_event_attr attr = {
65 .sample_type = PERF_SAMPLE_RAW,
66 .type = PERF_TYPE_SOFTWARE,
67 .config = PERF_COUNT_SW_BPF_OUTPUT,
68 };
69 int key = 0;
70
71 pmu_fd = sys_perf_event_open(&attr, -1/*pid*/, 0/*cpu*/, -1/*group_fd*/, 0);
72
73 assert(pmu_fd >= 0);
74 assert(bpf_map_update_elem(map_fd[0], &key, &pmu_fd, BPF_ANY) == 0);
75 ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
76} 55}
77 56
78int main(int argc, char **argv) 57int main(int argc, char **argv)
79{ 58{
59 struct perf_buffer_opts pb_opts = {};
60 struct perf_buffer *pb;
80 char filename[256]; 61 char filename[256];
81 FILE *f; 62 FILE *f;
82 int ret; 63 int ret;
@@ -88,16 +69,20 @@ int main(int argc, char **argv)
88 return 1; 69 return 1;
89 } 70 }
90 71
91 test_bpf_perf_event(); 72 pb_opts.sample_cb = print_bpf_output;
92 73 pb = perf_buffer__new(map_fd[0], 8, &pb_opts);
93 if (perf_event_mmap(pmu_fd) < 0) 74 ret = libbpf_get_error(pb);
75 if (ret) {
76 printf("failed to setup perf_buffer: %d\n", ret);
94 return 1; 77 return 1;
78 }
95 79
96 f = popen("taskset 1 dd if=/dev/zero of=/dev/null", "r"); 80 f = popen("taskset 1 dd if=/dev/zero of=/dev/null", "r");
97 (void) f; 81 (void) f;
98 82
99 start_time = time_get_ns(); 83 start_time = time_get_ns();
100 ret = perf_event_poller(pmu_fd, print_bpf_output); 84 while ((ret = perf_buffer__poll(pb, 1000)) >= 0 && cnt < MAX_CNT) {
85 }
101 kill(0, SIGINT); 86 kill(0, SIGINT);
102 return ret; 87 return ret;
103} 88}