perf, bpf: add support for HW_CACHE and RAW events
Subsystems (7)
cover perf, bpf: add support for HW_CACHE and RAW events
Patch 1: add support for HW_CACHE and RAW perf events to bpf:
- similar to PERF_TYPE_RAW and PERF_TYPE_HARDWARE allow PERF_TYPE_HW_CACHE events to be accessed via bpf_perf_event_read()
- similar to PERF_TYPE_HARDWARE and PERF_TYPE_SOFTWARE allow bpf programs to attch to PERF_TYPE_HW_CACHE and PERF_TYPE_RAW events as BPF_PROG_TYPE_PERF_EVENT program type
Patch 2: add tests for HW_CACHE and RAW events
---
Peter,
please review patch 1. It looks trivial and as far as we can see nothing else needed. The existing perf+bpf infra covers it just fine.
Thanks!
Teng Qin (2):
perf, bpf: add support for HW_CACHE and RAW events samples/bpf: add samples for HW_CACHE / RAW events
kernel/bpf/arraymap.c | 1 + kernel/events/core.c | 4 +- kernel/trace/bpf_trace.c | 1 + samples/bpf/bpf_helpers.h | 2 +- samples/bpf/trace_event_user.c | 46 +++++++++++- samples/bpf/tracex6_kern.c | 28 ++++++-- samples/bpf/tracex6_user.c | 155 +++++++++++++++++++++++++++++++---------- 7 files changed, 187 insertions(+), 50 deletions(-)
Signature · 1 line
2.9.3
PATCH 1/2 perf, bpf: add support for HW_CACHE and RAW events
From: Teng Qin <[email protected]>
This commit adds support for attach BPF program to RAW and HW_CACHE type events, and support for read HW_CACHE type event counters in BPF program. Existing code logic already supports them, so this commit is just update Enum value checks.
--- kernel/bpf/arraymap.c | 1 + kernel/events/core.c | 4 +++- kernel/trace/bpf_trace.c | 1 + 3 files changed, 5 insertions(+), 1 deletion(-)
kernel/bpf/arraymap.c +1 -0
@@ -473,6 +473,7 @@ static void *perf_event_fd_array_get_ptr(struct bpf_map *map, goto err_out;/* fall-through */ case PERF_TYPE_RAW : +case PERF_TYPE_HW_CACHE :case PERF_TYPE_HARDWARE : ee =bpf_event_entry_gen (perf_file, map_file);if (ee)
kernel/events/core.c +3 -1
@@ -8038,7 +8038,9 @@ static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd)struct bpf_prog *prog;if (event->attr.type ==PERF_TYPE_HARDWARE || - event->attr.type ==PERF_TYPE_SOFTWARE ) + event->attr.type ==PERF_TYPE_SOFTWARE || + event->attr.type ==PERF_TYPE_HW_CACHE || + event->attr.type ==PERF_TYPE_RAW )return perf_event_set_bpf_handler (event, prog_fd);if (event->attr.type !=PERF_TYPE_TRACEPOINT )
kernel/trace/bpf_trace.c +1 -0
@@ -249,6 +249,7 @@ BPF_CALL_2(bpf_perf_event_read, struct bpf_map *, map, u64, flags) event = ee->event;if (unlikely (event->attr.type !=PERF_TYPE_HARDWARE && + event->attr.type !=PERF_TYPE_HW_CACHE && event->attr.type !=PERF_TYPE_RAW ))return -EINVAL ;
Signature · 1 line
2.9.3
Peter Zijlstra
maintainerQuoted 6 lines · Alexei Starovoitov
From: Teng Qin <[email protected]>
This commit adds support for attach BPF program to RAW and
HW_CACHEtype events, and support for readHW_CACHEtype event counters in BPF program. Existing code logic already supports them, so this commit is just update Enum value checks.
So what I'm missing is why they were not supported previously, and what changed to allow it now.
Quoted 10 lines · Peter Zijlstra
Quoted 6 lines · Alexei Starovoitov
From: Teng Qin <[email protected]>
This commit adds support for attach BPF program to RAW and
HW_CACHEtype events, and support for readHW_CACHEtype event counters in BPF program. Existing code logic already supports them, so this commit is just update Enum value checks.So what I'm missing is why they were not supported previously, and what changed to allow it now.
that code path simply wasn't tested previously. Nothing changed on bpf side and on perf side.
Why it wasn't added on day one? There was no demand. Now people use bpf more and more and few folks got confused that these types of perf events were not supported, hence we're adding it.
Peter Zijlstra
maintainerQuoted 9 lines · Alexei Starovoitov
Quoted 8 lines · Peter Zijlstra
Quoted 6 lines · Alexei Starovoitov
From: Teng Qin <[email protected]>
This commit adds support for attach BPF program to RAW and
HW_CACHEtype events, and support for readHW_CACHEtype event counters in BPF program. Existing code logic already supports them, so this commit is just update Enum value checks.
Quoted 8 lines
Quoted 2 lines
So what I'm missing is why they were not supported previously, and what changed to allow it now.
that code path simply wasn't tested previously. Nothing changed on bpf side and on perf side.
Why it wasn't added on day one? There was no demand. Now people use bpf more and more and few folks got confused that these types of perf events were not supported, hence we're adding it.
OK. Is there anything stopping people from wanting to use the dynamic types, as found in:
/sys/bus/event_source/devices/*/type
?
In which case, do we want something like this instead?
kernel/events/core.c +1 -5
@@ -8063,12 +8063,8 @@ static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd)bool is_kprobe, is_tracepoint;struct bpf_prog *prog; -if (event->attr.type ==PERF_TYPE_HARDWARE || - event->attr.type ==PERF_TYPE_SOFTWARE ) -return perf_event_set_bpf_handler (event, prog_fd); -if (event->attr.type !=PERF_TYPE_TRACEPOINT ) -return -EINVAL ; +return perf_event_set_bpf_handler (event, prog_fd);if (event->tp_event->prog)return -EEXIST ;
Quoted 34 lines · Peter Zijlstra
Quoted 9 lines · Alexei Starovoitov
Quoted 8 lines · Peter Zijlstra
Quoted 6 lines · Alexei Starovoitov
From: Teng Qin <[email protected]>
This commit adds support for attach BPF program to RAW and
HW_CACHEtype events, and support for readHW_CACHEtype event counters in BPF program. Existing code logic already supports them, so this commit is just update Enum value checks.Quoted 8 lines
Quoted 2 lines
So what I'm missing is why they were not supported previously, and what changed to allow it now.
that code path simply wasn't tested previously. Nothing changed on bpf side and on perf side.
Why it wasn't added on day one? There was no demand. Now people use bpf more and more and few folks got confused that these types of perf events were not supported, hence we're adding it.OK. Is there anything stopping people from wanting to use the dynamic types, as found in:
/sys/bus/event_source/devices/*/type?
In which case, do we want something like this instead?
kernel/events/core.c +0
-0
kernel/events/core.c static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd) · line 8067
Quoted 10 lines
kernel/events/core.c +1
-5@@ -8063,12 +8063,8 @@ static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd)bool is_kprobe, is_tracepoint;struct bpf_prog *prog; -if (event->attr.type ==PERF_TYPE_HARDWARE || - event->attr.type ==PERF_TYPE_SOFTWARE ) -return perf_event_set_bpf_handler (event, prog_fd); -if (event->attr.type !=PERF_TYPE_TRACEPOINT ) -return -EINVAL ; +return perf_event_set_bpf_handler (event, prog_fd);
Good point. We were actually looking at how to deal with msr and cstate events. That should indeed address it.
Will respin.
Thanks for the feedback!
PATCH 2/2 samples/bpf: add samples for HW_CACHE / RAW events
In reply to Alexei StarovoitovFrom: Teng Qin <[email protected]>
This commit adds sample to test attach BPF to HW_CACHE and RAW type events into the trace_event sample. The test outputs a lot of things to screen, therefore make sure it aborts on error so it's easier to see if everything works. Also update clean-up logic to disable the perf event before closing pmu_fd.
This commit also adds sample to test read HW_CACHE and RAW type event counters from BPF program using bpf_perf_event_read. Refactored the existing sample to fork individual task on each CPU, attach kprobe to more controllable function, and more accurately check if each read on every CPU returned with good value.
--- samples/bpf/bpf_helpers.h | 2 +- samples/bpf/trace_event_user.c | 46 +++++++++++- samples/bpf/tracex6_kern.c | 28 ++++++-- samples/bpf/tracex6_user.c | 155 +++++++++++++++++++++++++++++++---------- 4 files changed, 182 insertions(+), 49 deletions(-)
samples/bpf/bpf_helpers.h +1 -1
@@ -31,7 +31,7 @@ static unsigned long long (*bpf_get_current_uid_gid)(void) = (void *) BPF_FUNC_get_current_uid_gid;static int (*bpf_get_current_comm)(void *buf,int buf_size) = (void *) BPF_FUNC_get_current_comm; -static int (*bpf_perf_event_read)(void *map,int index) = +static u64 (*bpf_perf_event_read)(void *map,u64 flags) = (void *) BPF_FUNC_perf_event_read;static int (*bpf_clone_redirect)(void *ctx,int ifindex,int flags) = (void *) BPF_FUNC_clone_redirect;
samples/bpf/trace_event_user.c +43 -3
89 lines not on this page · raw message
samples/bpf/tracex6_kern.c +21 -7
@@ -3,22 +3,36 @@#include <uapi/linux/bpf.h> #include "bpf_helpers.h" -struct bpf_map_def SEC("maps") my_map = { +struct bpf_map_def SEC("maps") counters = { .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY, .key_size = sizeof(int), .value_size = sizeof(u32), - .max_entries = 32, + .max_entries = 64, +}; +struct bpf_map_def SEC("maps") values = { + .type = BPF_MAP_TYPE_HASH, + .key_size = sizeof(int), + .value_size = sizeof(u64), + .max_entries = 64, }; -SEC("kprobe/sys_write") +SEC("kprobe/htab_map_get_next_key")int bpf_prog1 (struct pt_regs *ctx) { -u64 count; +u64 count, *val; +s64 error;u32 key =bpf_get_smp_processor_id (); -char fmt[] ="CPU-%d %llu\n" ; - count =bpf_perf_event_read (&my_map, key); -bpf_trace_printk (fmt,sizeof (fmt), key, count); + count =bpf_perf_event_read (&counters, key); + error = (s64 )count; +if (error <0 && error >-256 ) +return 0 ; + + val =bpf_map_lookup_elem (&values, &key); +if (val) + *val = count; +else +bpf_map_update_elem (&values, &key, &count,BPF_NOEXIST );return 0 ; }
samples/bpf/tracex6_user.c +117 -38
190 lines not on this page · raw message
Signature · 1 line
2.9.3
David Miller
maintainerRe: [PATCH net-next 2/2] samples/bpf: add samples for HW_CACHE / RAW events
From: Alexei Starovoitov <[email protected]>
Date: Mon, 22 May 2017 15:48:40 -0700
samples/bpf/bpf_helpers.h static unsigned long long (*bpf_get_current_uid_gid)(void) = · line 35
Quoted 7 lines
samples/bpf/bpf_helpers.h +1
-1@@ -31,7 +31,7 @@ static unsigned long long (*bpf_get_current_uid_gid)(void) = (void *) BPF_FUNC_get_current_uid_gid;static int (*bpf_get_current_comm)(void *buf,int buf_size) = (void *) BPF_FUNC_get_current_comm; -static int (*bpf_perf_event_read)(void *map,int index) = +static u64 (*bpf_perf_event_read)(void *map,u64 flags) = (void *) BPF_FUNC_perf_event_read;
If the second argument really is "u64 flags", then please update the comments in tools/include/uapi/linux/bpf.h as well.
Thank you.
Re: [PATCH net-next 2/2] samples/bpf: add samples for HW_CACHE / RAW events
Quoted 13 lines · David Miller
From: Alexei Starovoitov <[email protected]>
Date: Mon, 22 May 2017 15:48:40 -0700samples/bpf/bpf_helpers.h static unsigned long long (*bpf_get_current_uid_gid)(void) = · line 35
Quoted 7 lines
samples/bpf/bpf_helpers.h +1
-1@@ -31,7 +31,7 @@ static unsigned long long (*bpf_get_current_uid_gid)(void) = (void *) BPF_FUNC_get_current_uid_gid;static int (*bpf_get_current_comm)(void *buf,int buf_size) = (void *) BPF_FUNC_get_current_comm; -static int (*bpf_perf_event_read)(void *map,int index) = +static u64 (*bpf_perf_event_read)(void *map,u64 flags) = (void *) BPF_FUNC_perf_event_read;If the second argument really is "u64 flags", then please update the comments in
tools/include/uapi/linux/bpf.has well.
of course.
As independent patch, I assume.
For both tools/include/uapi/...bpf.h and include/uapi/...bpf.h
It has some info:
/* BPF_FUNC_perf_event_output and BPF_FUNC_perf_event_read flags. */
#define BPF_F_INDEX_MASK 0xffffffffULL
#define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK
yet perf_event_read() is least documented. hmm.
* u64 bpf_perf_event_read(&map, index)
* Return: Number events read or error code
that needs to be fixed.
David Miller
maintainerRe: [PATCH net-next 2/2] samples/bpf: add samples for HW_CACHE / RAW events
From: Alexei Starovoitov <[email protected]>
Date: Mon, 22 May 2017 16:35:07 -0700
Quoted 5 lines
yet
perf_event_read()is least documented. hmm.
* u64bpf_perf_event_read(&map, index)
* Return: Number events read or error codethat needs to be fixed.
That's exactly what I was talking about :-)