diff options
author | Kaixu Xia <xiakaixu@huawei.com> | 2015-08-06 03:02:36 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-08-10 01:50:06 -0400 |
commit | 47efb30274cbec1bd3c0c980a7ece328df2c16a8 (patch) | |
tree | 1393486ec4906557cdb1d9173e6e2e675bab3354 /samples/bpf | |
parent | 35578d7984003097af2b1e34502bc943d40c1804 (diff) |
samples/bpf: example of get selected PMU counter value
This is a simple example and shows how to use the new ability
to get the selected Hardware PMU counter value.
Signed-off-by: Kaixu Xia <xiakaixu@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'samples/bpf')
-rw-r--r-- | samples/bpf/Makefile | 4 | ||||
-rw-r--r-- | samples/bpf/bpf_helpers.h | 2 | ||||
-rw-r--r-- | samples/bpf/tracex6_kern.c | 26 | ||||
-rw-r--r-- | samples/bpf/tracex6_user.c | 68 |
4 files changed, 100 insertions, 0 deletions
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 4450fed91ab4..63e7d50e6a4f 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile | |||
@@ -12,6 +12,7 @@ hostprogs-y += tracex2 | |||
12 | hostprogs-y += tracex3 | 12 | hostprogs-y += tracex3 |
13 | hostprogs-y += tracex4 | 13 | hostprogs-y += tracex4 |
14 | hostprogs-y += tracex5 | 14 | hostprogs-y += tracex5 |
15 | hostprogs-y += tracex6 | ||
15 | hostprogs-y += lathist | 16 | hostprogs-y += lathist |
16 | 17 | ||
17 | test_verifier-objs := test_verifier.o libbpf.o | 18 | test_verifier-objs := test_verifier.o libbpf.o |
@@ -25,6 +26,7 @@ tracex2-objs := bpf_load.o libbpf.o tracex2_user.o | |||
25 | tracex3-objs := bpf_load.o libbpf.o tracex3_user.o | 26 | tracex3-objs := bpf_load.o libbpf.o tracex3_user.o |
26 | tracex4-objs := bpf_load.o libbpf.o tracex4_user.o | 27 | tracex4-objs := bpf_load.o libbpf.o tracex4_user.o |
27 | tracex5-objs := bpf_load.o libbpf.o tracex5_user.o | 28 | tracex5-objs := bpf_load.o libbpf.o tracex5_user.o |
29 | tracex6-objs := bpf_load.o libbpf.o tracex6_user.o | ||
28 | lathist-objs := bpf_load.o libbpf.o lathist_user.o | 30 | lathist-objs := bpf_load.o libbpf.o lathist_user.o |
29 | 31 | ||
30 | # Tell kbuild to always build the programs | 32 | # Tell kbuild to always build the programs |
@@ -37,6 +39,7 @@ always += tracex2_kern.o | |||
37 | always += tracex3_kern.o | 39 | always += tracex3_kern.o |
38 | always += tracex4_kern.o | 40 | always += tracex4_kern.o |
39 | always += tracex5_kern.o | 41 | always += tracex5_kern.o |
42 | always += tracex6_kern.o | ||
40 | always += tcbpf1_kern.o | 43 | always += tcbpf1_kern.o |
41 | always += lathist_kern.o | 44 | always += lathist_kern.o |
42 | 45 | ||
@@ -51,6 +54,7 @@ HOSTLOADLIBES_tracex2 += -lelf | |||
51 | HOSTLOADLIBES_tracex3 += -lelf | 54 | HOSTLOADLIBES_tracex3 += -lelf |
52 | HOSTLOADLIBES_tracex4 += -lelf -lrt | 55 | HOSTLOADLIBES_tracex4 += -lelf -lrt |
53 | HOSTLOADLIBES_tracex5 += -lelf | 56 | HOSTLOADLIBES_tracex5 += -lelf |
57 | HOSTLOADLIBES_tracex6 += -lelf | ||
54 | HOSTLOADLIBES_lathist += -lelf | 58 | HOSTLOADLIBES_lathist += -lelf |
55 | 59 | ||
56 | # point this to your LLVM backend with bpf support | 60 | # point this to your LLVM backend with bpf support |
diff --git a/samples/bpf/bpf_helpers.h b/samples/bpf/bpf_helpers.h index c77c872fe8ee..3a44d3a272af 100644 --- a/samples/bpf/bpf_helpers.h +++ b/samples/bpf/bpf_helpers.h | |||
@@ -31,6 +31,8 @@ static unsigned long long (*bpf_get_current_uid_gid)(void) = | |||
31 | (void *) BPF_FUNC_get_current_uid_gid; | 31 | (void *) BPF_FUNC_get_current_uid_gid; |
32 | static int (*bpf_get_current_comm)(void *buf, int buf_size) = | 32 | static int (*bpf_get_current_comm)(void *buf, int buf_size) = |
33 | (void *) BPF_FUNC_get_current_comm; | 33 | (void *) BPF_FUNC_get_current_comm; |
34 | static int (*bpf_perf_event_read)(void *map, int index) = | ||
35 | (void *) BPF_FUNC_perf_event_read; | ||
34 | 36 | ||
35 | /* llvm builtin functions that eBPF C program may use to | 37 | /* llvm builtin functions that eBPF C program may use to |
36 | * emit BPF_LD_ABS and BPF_LD_IND instructions | 38 | * emit BPF_LD_ABS and BPF_LD_IND instructions |
diff --git a/samples/bpf/tracex6_kern.c b/samples/bpf/tracex6_kern.c new file mode 100644 index 000000000000..23d1cffaf249 --- /dev/null +++ b/samples/bpf/tracex6_kern.c | |||
@@ -0,0 +1,26 @@ | |||
1 | #include <linux/version.h> | ||
2 | #include <uapi/linux/bpf.h> | ||
3 | #include "bpf_helpers.h" | ||
4 | |||
5 | struct bpf_map_def SEC("maps") my_map = { | ||
6 | .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY, | ||
7 | .key_size = sizeof(int), | ||
8 | .value_size = sizeof(u32), | ||
9 | .max_entries = 32, | ||
10 | }; | ||
11 | |||
12 | SEC("kprobe/sys_write") | ||
13 | int bpf_prog1(struct pt_regs *ctx) | ||
14 | { | ||
15 | u64 count; | ||
16 | u32 key = bpf_get_smp_processor_id(); | ||
17 | char fmt[] = "CPU-%d %llu\n"; | ||
18 | |||
19 | count = bpf_perf_event_read(&my_map, key); | ||
20 | bpf_trace_printk(fmt, sizeof(fmt), key, count); | ||
21 | |||
22 | return 0; | ||
23 | } | ||
24 | |||
25 | char _license[] SEC("license") = "GPL"; | ||
26 | u32 _version SEC("version") = LINUX_VERSION_CODE; | ||
diff --git a/samples/bpf/tracex6_user.c b/samples/bpf/tracex6_user.c new file mode 100644 index 000000000000..928f05eaa304 --- /dev/null +++ b/samples/bpf/tracex6_user.c | |||
@@ -0,0 +1,68 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <unistd.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <stdbool.h> | ||
5 | #include <string.h> | ||
6 | #include <fcntl.h> | ||
7 | #include <poll.h> | ||
8 | #include <sys/ioctl.h> | ||
9 | #include <linux/perf_event.h> | ||
10 | #include <linux/bpf.h> | ||
11 | #include "libbpf.h" | ||
12 | #include "bpf_load.h" | ||
13 | |||
14 | #define SAMPLE_PERIOD 0x7fffffffffffffffULL | ||
15 | |||
16 | static void test_bpf_perf_event(void) | ||
17 | { | ||
18 | int nr_cpus = sysconf(_SC_NPROCESSORS_CONF); | ||
19 | int *pmu_fd = malloc(nr_cpus * sizeof(int)); | ||
20 | unsigned long value; | ||
21 | int i; | ||
22 | |||
23 | struct perf_event_attr attr_insn_pmu = { | ||
24 | .freq = 0, | ||
25 | .sample_period = SAMPLE_PERIOD, | ||
26 | .inherit = 0, | ||
27 | .type = PERF_TYPE_HARDWARE, | ||
28 | .read_format = 0, | ||
29 | .sample_type = 0, | ||
30 | .config = 0,/* PMU: cycles */ | ||
31 | }; | ||
32 | |||
33 | for (i = 0; i < nr_cpus; i++) { | ||
34 | pmu_fd[i] = perf_event_open(&attr_insn_pmu, -1/*pid*/, i/*cpu*/, -1/*group_fd*/, 0); | ||
35 | if (pmu_fd[i] < 0) | ||
36 | printf("event syscall failed\n"); | ||
37 | |||
38 | bpf_update_elem(map_fd[0], &i, &pmu_fd[i], BPF_ANY); | ||
39 | ioctl(pmu_fd[i], PERF_EVENT_IOC_ENABLE, 0); | ||
40 | } | ||
41 | |||
42 | system("ls"); | ||
43 | system("pwd"); | ||
44 | system("sleep 2"); | ||
45 | |||
46 | for (i = 0; i < nr_cpus; i++) | ||
47 | close(pmu_fd[i]); | ||
48 | |||
49 | close(map_fd); | ||
50 | |||
51 | free(pmu_fd); | ||
52 | } | ||
53 | |||
54 | int main(int argc, char **argv) | ||
55 | { | ||
56 | char filename[256]; | ||
57 | |||
58 | snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); | ||
59 | |||
60 | if (load_bpf_file(filename)) { | ||
61 | printf("%s", bpf_log_buf); | ||
62 | return 1; | ||
63 | } | ||
64 | |||
65 | test_bpf_perf_event(); | ||
66 | |||
67 | return 0; | ||
68 | } | ||