aboutsummaryrefslogtreecommitdiffstats
path: root/samples/bpf
diff options
context:
space:
mode:
authorKaixu Xia <xiakaixu@huawei.com>2015-08-06 03:02:36 -0400
committerDavid S. Miller <davem@davemloft.net>2015-08-10 01:50:06 -0400
commit47efb30274cbec1bd3c0c980a7ece328df2c16a8 (patch)
tree1393486ec4906557cdb1d9173e6e2e675bab3354 /samples/bpf
parent35578d7984003097af2b1e34502bc943d40c1804 (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/Makefile4
-rw-r--r--samples/bpf/bpf_helpers.h2
-rw-r--r--samples/bpf/tracex6_kern.c26
-rw-r--r--samples/bpf/tracex6_user.c68
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
12hostprogs-y += tracex3 12hostprogs-y += tracex3
13hostprogs-y += tracex4 13hostprogs-y += tracex4
14hostprogs-y += tracex5 14hostprogs-y += tracex5
15hostprogs-y += tracex6
15hostprogs-y += lathist 16hostprogs-y += lathist
16 17
17test_verifier-objs := test_verifier.o libbpf.o 18test_verifier-objs := test_verifier.o libbpf.o
@@ -25,6 +26,7 @@ tracex2-objs := bpf_load.o libbpf.o tracex2_user.o
25tracex3-objs := bpf_load.o libbpf.o tracex3_user.o 26tracex3-objs := bpf_load.o libbpf.o tracex3_user.o
26tracex4-objs := bpf_load.o libbpf.o tracex4_user.o 27tracex4-objs := bpf_load.o libbpf.o tracex4_user.o
27tracex5-objs := bpf_load.o libbpf.o tracex5_user.o 28tracex5-objs := bpf_load.o libbpf.o tracex5_user.o
29tracex6-objs := bpf_load.o libbpf.o tracex6_user.o
28lathist-objs := bpf_load.o libbpf.o lathist_user.o 30lathist-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
37always += tracex3_kern.o 39always += tracex3_kern.o
38always += tracex4_kern.o 40always += tracex4_kern.o
39always += tracex5_kern.o 41always += tracex5_kern.o
42always += tracex6_kern.o
40always += tcbpf1_kern.o 43always += tcbpf1_kern.o
41always += lathist_kern.o 44always += lathist_kern.o
42 45
@@ -51,6 +54,7 @@ HOSTLOADLIBES_tracex2 += -lelf
51HOSTLOADLIBES_tracex3 += -lelf 54HOSTLOADLIBES_tracex3 += -lelf
52HOSTLOADLIBES_tracex4 += -lelf -lrt 55HOSTLOADLIBES_tracex4 += -lelf -lrt
53HOSTLOADLIBES_tracex5 += -lelf 56HOSTLOADLIBES_tracex5 += -lelf
57HOSTLOADLIBES_tracex6 += -lelf
54HOSTLOADLIBES_lathist += -lelf 58HOSTLOADLIBES_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;
32static int (*bpf_get_current_comm)(void *buf, int buf_size) = 32static int (*bpf_get_current_comm)(void *buf, int buf_size) =
33 (void *) BPF_FUNC_get_current_comm; 33 (void *) BPF_FUNC_get_current_comm;
34static 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
5struct 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
12SEC("kprobe/sys_write")
13int 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
25char _license[] SEC("license") = "GPL";
26u32 _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
16static 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
54int 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}