bpf_perf_event_output helper
Subsystems (8)
cover bpf_perf_event_output helper
Over the last year there were multiple attempts to let eBPF programs output data into perf events by He Kuang and Wangnan.
The last one was:
https://lkml.org/lkml/2015/7/20/736
It was almost perfect with exception that all bpf programs would sent data into one global perf_event.
This patch set takes different approach by letting user space open independent PERF_COUNT_SW_BPF_OUTPUT events, so that program output won't collide.
Wangnan is working on corresponding perf patches.
Alexei Starovoitov (3):
perf: pad raw data samples automatically
bpf: introduce bpf_perf_event_output() helper
samples: bpf: add bpf_perf_event_output example
include/uapi/linux/bpf.h | 11 +++ include/uapi/linux/perf_event.h | 1 + kernel/bpf/arraymap.c | 2 + kernel/bpf/verifier.c | 3 +- kernel/events/core.c | 15 ++- kernel/trace/bpf_trace.c | 46 +++++++++ samples/bpf/Makefile | 7 ++ samples/bpf/bpf_helpers.h | 2 + samples/bpf/trace_output_kern.c | 31 +++++++ samples/bpf/trace_output_user.c | 196 +++++++++++++++++++++++++++++++++++++++ 10 files changed, 308 insertions(+), 6 deletions(-) create mode 100644 samples/bpf/trace_output_kern.c create mode 100644 samples/bpf/trace_output_user.c
Signature · 1 line
1.7.9.5
PATCH 1/3 perf: pad raw data samples automatically
Instead of WARN_ON in perf_event_output() on unpaded raw samples, pad them automatically.
--- kernel/events/core.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
kernel/events/core.c +10 -5
@@ -5286,9 +5286,15 @@ void perf_output_sample(struct perf_output_handle *handle,if (sample_type &PERF_SAMPLE_RAW ) {if (data->raw) { -perf_output_put (handle, data->raw->size); -__output_copy (handle, data->raw->data, - data->raw->size); +u32 raw_size = data->raw->size; +u32 real_size =round_up (raw_size +sizeof (u32), +sizeof (u64)) -sizeof (u32); +u64 zero =0 ; + +perf_output_put (handle, real_size); +__output_copy (handle, data->raw->data, raw_size); +if (real_size - raw_size) +__output_copy (handle, &zero, real_size - raw_size); }else { struct { u32 size;
@@ -5420,8 +5426,7 @@ void perf_prepare_sample(struct perf_event_header *header,else size +=sizeof (u32); -WARN_ON_ONCE (size & (sizeof (u64)-1 )); - header->size += size; + header->size +=round_up (size,sizeof (u64)); }if (sample_type &PERF_SAMPLE_BRANCH_STACK ) {
Signature · 1 line
1.7.9.5
PATCH 2/3 bpf: introduce bpf_perf_event_output() helper
In reply to Alexei StarovoitovThis helper is used to send raw data from eBPF program into special PERF_TYPE_SOFTWARE/PERF_COUNT_SW_BPF_OUTPUT perf_event. User space needs to perf_event_open() it (either for one or all cpus) and store FD into perf_event_array (similar to bpf_perf_event_read() helper) before eBPF program can send data into it.
Today the programs triggered by kprobe collect the data and either store it into the maps or print it via bpf_trace_printk() where latter is the debug facility and not suitable to stream the data. This new helper replaces such bpf_trace_printk() usage and allows programs to have dedicated channel into user space for post-processing of the raw data collected.
--- include/uapi/linux/bpf.h | 11 ++++++++++ include/uapi/linux/perf_event.h | 1 + kernel/bpf/arraymap.c | 2 ++ kernel/bpf/verifier.c | 3 ++- kernel/trace/bpf_trace.c | 46 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 1 deletion(-)
include/uapi/linux/bpf.h +11 -0
@@ -287,6 +287,17 @@ enum bpf_func_id {* Return: realm if != 0 */ BPF_FUNC_get_route_realm, + +/** +* bpf_perf_event_output(ctx, map, index, data, size) - output perf raw sample +* @ctx: struct pt_regs* +* @map: pointer to perf_event_array map +* @index: index of event in the map +* @data: data on stack to be output as raw data +* @size: size of data +* Return: 0 on success +*/ + BPF_FUNC_perf_event_output, __BPF_FUNC_MAX_ID, };
include/uapi/linux/perf_event.h +1 -0
@@ -110,6 +110,7 @@ enum perf_sw_ids {PERF_COUNT_SW_ALIGNMENT_FAULTS =7 ,PERF_COUNT_SW_EMULATION_FAULTS =8 ,PERF_COUNT_SW_DUMMY =9 , +PERF_COUNT_SW_BPF_OUTPUT =10 , PERF_COUNT_SW_MAX, /* non-ABI */ };
kernel/bpf/arraymap.c +2 -0
@@ -295,6 +295,8 @@ static void *perf_event_fd_array_get_ptr(struct bpf_map *map, int fd)return (void *)attr;if (attr->type !=PERF_TYPE_RAW && + !(attr->type ==PERF_TYPE_SOFTWARE && + attr->config ==PERF_COUNT_SW_BPF_OUTPUT ) && attr->type !=PERF_TYPE_HARDWARE ) {perf_event_release_kernel (event);return ERR_PTR (-EINVAL );
kernel/bpf/verifier.c +2 -1
@@ -245,6 +245,7 @@ static const struct { } func_limit[] = { {BPF_MAP_TYPE_PROG_ARRAY, BPF_FUNC_tail_call}, {BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_read}, + {BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_output}, }; static void print_verifier_state(struct verifier_env *env)
@@ -910,7 +911,7 @@ static int check_map_func_compatibility(struct bpf_map *map, int func_id)* don't allow any other map type to be passed into * the special func; */ -if (bool_map != bool_func) +if (bool_func && bool_map != bool_func)return -EINVAL ; }
kernel/trace/bpf_trace.c +46 -0
58 lines not on this page · raw message
Signature · 1 line
1.7.9.5
Re: [PATCH net-next 2/3] bpf: introduce bpf_perf_event_output() helper
hi, Alexei
I've tested the sample in next patch and it works well. I think more work on the perf side needs to be done for parsing PERF_COUNT_SW_BPF_OUTPUT event type, are you working on that?
Thank you.
Quoted 154 lines · Alexei Starovoitov
This helper is used to send raw data from eBPF program into special PERF_TYPE_SOFTWARE/PERF_COUNT_SW_BPF_OUTPUT
perf_event. User space needs toperf_event_open()it (either for one or all cpus) and store FD intoperf_event_array(similar tobpf_perf_event_read()helper) before eBPF program can send data into it.Today the programs triggered by kprobe collect the data and either store it into the maps or print it via
bpf_trace_printk()where latter is the debug facility and not suitable to stream the data. This new helper replaces suchbpf_trace_printk()usage and allows programs to have dedicated channel into user space for post-processing of the raw data collected.Signed-off-by Alexei Starovoitov <[email protected]>--- include/uapi/linux/bpf.h | 11 ++++++++++ include/uapi/linux/perf_event.h | 1 + kernel/bpf/arraymap.c | 2 ++ kernel/bpf/verifier.c | 3 ++- kernel/trace/bpf_trace.c | 46 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 1 deletion(-)include/uapi/linux/bpf.h +11
-0@@ -287,6 +287,17 @@ enum bpf_func_id {* Return: realm if != 0 */ BPF_FUNC_get_route_realm, + +/** +* bpf_perf_event_output(ctx, map, index, data, size) - output perf raw sample +* @ctx: struct pt_regs* +* @map: pointer to perf_event_array map +* @index: index of event in the map +* @data: data on stack to be output as raw data +* @size: size of data +* Return: 0 on success +*/ + BPF_FUNC_perf_event_output, __BPF_FUNC_MAX_ID, };include/uapi/linux/perf_event.h +1
-0@@ -110,6 +110,7 @@ enum perf_sw_ids {PERF_COUNT_SW_ALIGNMENT_FAULTS =7 ,PERF_COUNT_SW_EMULATION_FAULTS =8 ,PERF_COUNT_SW_DUMMY =9 , +PERF_COUNT_SW_BPF_OUTPUT =10 , PERF_COUNT_SW_MAX, /* non-ABI */ };kernel/bpf/arraymap.c +2
-0@@ -295,6 +295,8 @@ static void *perf_event_fd_array_get_ptr(struct bpf_map *map, int fd)return (void *)attr;if (attr->type !=PERF_TYPE_RAW && + !(attr->type ==PERF_TYPE_SOFTWARE && + attr->config ==PERF_COUNT_SW_BPF_OUTPUT ) && attr->type !=PERF_TYPE_HARDWARE ) {perf_event_release_kernel (event);return ERR_PTR (-EINVAL );kernel/bpf/verifier.c +2
-1@@ -245,6 +245,7 @@ static const struct { } func_limit[] = { {BPF_MAP_TYPE_PROG_ARRAY, BPF_FUNC_tail_call}, {BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_read}, + {BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_output}, }; static void print_verifier_state(struct verifier_env *env)@@ -910,7 +911,7 @@ static int check_map_func_compatibility(struct bpf_map *map, int func_id)* don't allow any other map type to be passed into * the special func; */ -if (bool_map != bool_func) +if (bool_func && bool_map != bool_func)return -EINVAL ; }kernel/trace/bpf_trace.c +46
-0@@ -215,6 +215,50 @@ const struct bpf_func_proto bpf_perf_event_read_proto = { .arg2_type = ARG_ANYTHING, }; +static u64 bpf_perf_event_output (u64 r1,u64 r2,u64 index,u64 r4,u64 size) +{ +struct pt_regs *regs = (struct pt_regs *) (long ) r1; +struct bpf_map *map = (struct bpf_map *) (long ) r2; + struct bpf_array *array = container_of(map, struct bpf_array, map); +void *data = (void *) (long ) r4; +struct perf_sample_data sample_data; +struct perf_event *event; +struct perf_raw_record raw = { + .size = size, + .data = data, + }; + +if (unlikely (index >= array->map.max_entries)) +return -E2BIG ; + + event = (struct perf_event *)array->ptrs[index]; +if (unlikely (!event)) +return -ENOENT ; + +if (unlikely (event->attr.type !=PERF_TYPE_SOFTWARE || + event->attr.config !=PERF_COUNT_SW_BPF_OUTPUT )) +return -EINVAL ; + +if (unlikely (event->oncpu !=smp_processor_id ())) +return -EOPNOTSUPP ; + +perf_sample_data_init (&sample_data,0 ,0 ); + sample_data.raw = &raw; +perf_event_output (event, &sample_data, regs); +return 0 ; +} + +static const struct bpf_func_proto bpf_perf_event_output_proto = { + .func = bpf_perf_event_output, + .gpl_only = false, + .ret_type =RET_INTEGER , + .arg1_type =ARG_PTR_TO_CTX , + .arg2_type =ARG_CONST_MAP_PTR , + .arg3_type =ARG_ANYTHING , + .arg4_type =ARG_PTR_TO_STACK , + .arg5_type =ARG_CONST_STACK_SIZE , +}; +static const struct bpf_func_proto *kprobe_prog_func_proto (enum bpf_func_id func_id) {switch (func_id) {@@ -242,6 +286,8 @@ static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id funcreturn &bpf_get_smp_processor_id_proto;case BPF_FUNC_perf_event_read:return &bpf_perf_event_read_proto; +case BPF_FUNC_perf_event_output: +return &bpf_perf_event_output_proto;default :return NULL ; }
Re: [PATCH net-next 2/3] bpf: introduce bpf_perf_event_output() helper
Quoted 7 lines · He Kuang
hi, Alexei
I've tested the sample in next patch and it works well. I think more work on the perf side needs to be done for parsing
PERF_COUNT_SW_BPF_OUTPUTevent type, are you working on that?Thank you.
We need to add something into parse-event.y/l to let it know the new software event. We can do this simple task. However, as I gussed before, perf is unable to print this new event so there is some work need to be done to let 'perf report' and 'perf script' know it.
One thing I can still remember is finding a way to inject format information through those output so 'perf script' and 'perf data convert --to-ctf' can decode the raw data without extra work. Can you remember that we have discussed a solution which connects debuginfo and output raw data using a builtin function in LLVM/clang? We already have clang/LLVM patch on it, but on perf side I haven't do start working on it. I think we can make perf output raw data hexadamically at first.
I'll do the above work and put related patch at the end of my eBPF patchset because they shouldn't be merged until this patchset upstreamed.
Thank you.
Quoted 165 lines · Alexei Starovoitov
Quoted 162 lines
This helper is used to send raw data from eBPF program into special PERF_TYPE_SOFTWARE/PERF_COUNT_SW_BPF_OUTPUT
perf_event. User space needs toperf_event_open()it (either for one or all cpus) and store FD intoperf_event_array(similar tobpf_perf_event_read()helper) before eBPF program can send data into it.Today the programs triggered by kprobe collect the data and either store it into the maps or print it via
bpf_trace_printk()where latter is the debug facility and not suitable to stream the data. This new helper replaces suchbpf_trace_printk()usage and allows programs to have dedicated channel into user space for post-processing of the raw data collected.Signed-off-by Alexei Starovoitov <[email protected]>--- include/uapi/linux/bpf.h | 11 ++++++++++ include/uapi/linux/perf_event.h | 1 + kernel/bpf/arraymap.c | 2 ++ kernel/bpf/verifier.c | 3 ++- kernel/trace/bpf_trace.c | 46 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 1 deletion(-)include/uapi/linux/bpf.h +3
-0@@ -287,6 +287,17 @@ enum bpf_func_id {* Return: realm if != 0 */ BPF_FUNC_get_route_realm, + +/** +* bpf_perf_event_output(ctx, map, index, data, size) - output perf raw sample
include/uapi/linux/bpf.h +8
-0+* @ctx: struct pt_regs* +* @map: pointer to perf_event_array map +* @index: index of event in the map +* @data: data on stack to be output as raw data +* @size: size of data +* Return: 0 on success +*/ + BPF_FUNC_perf_event_output, __BPF_FUNC_MAX_ID, };include/uapi/linux/perf_event.h +1
-0@@ -110,6 +110,7 @@ enum perf_sw_ids {PERF_COUNT_SW_ALIGNMENT_FAULTS =7 ,PERF_COUNT_SW_EMULATION_FAULTS =8 ,PERF_COUNT_SW_DUMMY =9 , +PERF_COUNT_SW_BPF_OUTPUT =10 , PERF_COUNT_SW_MAX, /* non-ABI */ };kernel/bpf/arraymap.c +2
-0@@ -295,6 +295,8 @@ static void *perf_event_fd_array_get_ptr(struct bpf_map *map, int fd) return (void *)attr;if (attr->type !=PERF_TYPE_RAW && + !(attr->type ==PERF_TYPE_SOFTWARE && + attr->config ==PERF_COUNT_SW_BPF_OUTPUT ) && attr->type !=PERF_TYPE_HARDWARE ) {perf_event_release_kernel (event);return ERR_PTR(-EINVAL);kernel/bpf/verifier.c +2
-1@@ -245,6 +245,7 @@ static const struct { } func_limit[] = { {BPF_MAP_TYPE_PROG_ARRAY, BPF_FUNC_tail_call}, {BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_read}, + {BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_output}, }; static void print_verifier_state(struct verifier_env *env)@@ -910,7 +911,7 @@ static int check_map_func_compatibility(structbpf_map *map, int func_id) * don't allow any other map type to be passed into * the special func; */ -if (bool_map != bool_func) +if (bool_func && bool_map != bool_func)return -EINVAL ; }kernel/trace/bpf_trace.c +44
-0@@ -215,6 +215,50 @@ const struct bpf_func_proto bpf_perf_event_read_proto = { .arg2_type = ARG_ANYTHING, }; +static u64 bpf_perf_event_output (u64 r1,u64 r2,u64 index,u64 r4,u64 size) +{ +struct pt_regs *regs = (struct pt_regs *) (long ) r1; +struct bpf_map *map = (struct bpf_map *) (long ) r2; + struct bpf_array *array = container_of(map, struct bpf_array, map); +void *data = (void *) (long ) r4; +struct perf_sample_data sample_data; +struct perf_event *event; +struct perf_raw_record raw = { + .size = size, + .data = data, + }; + +if (unlikely (index >= array->map.max_entries)) +return -E2BIG ; + + event = (struct perf_event *)array->ptrs[index]; +if (unlikely (!event)) +return -ENOENT ; + +if (unlikely (event->attr.type !=PERF_TYPE_SOFTWARE || + event->attr.config !=PERF_COUNT_SW_BPF_OUTPUT )) +return -EINVAL ; + +if (unlikely (event->oncpu !=smp_processor_id ())) +return -EOPNOTSUPP ; + +perf_sample_data_init (&sample_data,0 ,0 ); + sample_data.raw = &raw; +perf_event_output (event, &sample_data, regs); +return 0 ; +} + +static const struct bpf_func_proto bpf_perf_event_output_proto = { + .func = bpf_perf_event_output, + .gpl_only = false, + .ret_type =RET_INTEGER , + .arg1_type =ARG_PTR_TO_CTX , + .arg2_type =ARG_CONST_MAP_PTR , + .arg3_type =ARG_ANYTHING , + .arg4_type =ARG_PTR_TO_STACK , + .arg5_type =ARG_CONST_STACK_SIZE , +}; + static const struct bpf_func_proto *kprobe_prog_func_proto(enum
bpf_func_idfunc_id){ switch (func_id) {kernel/trace/bpf_trace.c +2
-0@@ -242,6 +286,8 @@ static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id func return &bpf_get_smp_processor_id_proto;case BPF_FUNC_perf_event_read:return &bpf_perf_event_read_proto; +case BPF_FUNC_perf_event_output: +return &bpf_perf_event_output_proto;default :return NULL ;}
Re: [PATCH net-next 2/3] bpf: introduce bpf_perf_event_output() helper
Quoted 2 lines · Wangnan (F)
I think we can
make perf output raw data hexadamically at first.
that would be my suggestion as well.
print it as hex first and when llvm type info is available you can teach perf to be smarter.
We're working on support for this feature in iovisor/bcc without requiring extra llvm work, since we can generate python classes on the fly from C code of bpf program.
Peter Zijlstra
maintainerRe: [PATCH net-next 2/3] bpf: introduce bpf_perf_event_output() helper
In reply to Alexei StarovoitovQuoted 12 lines · Alexei Starovoitov
This helper is used to send raw data from eBPF program into special PERF_TYPE_SOFTWARE/PERF_COUNT_SW_BPF_OUTPUT
perf_event. User space needs toperf_event_open()it (either for one or all cpus) and store FD intoperf_event_array(similar tobpf_perf_event_read()helper) before eBPF program can send data into it.include/uapi/linux/perf_event.h +0
-0
include/uapi/linux/perf_event.h enum perf_sw_ids { · line 116
Quoted 7 lines
include/uapi/linux/perf_event.h +1
-0@@ -110,6 +110,7 @@ enum perf_sw_ids {PERF_COUNT_SW_ALIGNMENT_FAULTS =7 ,PERF_COUNT_SW_EMULATION_FAULTS =8 ,PERF_COUNT_SW_DUMMY =9 , +PERF_COUNT_SW_BPF_OUTPUT =10 , PERF_COUNT_SW_MAX, /* non-ABI */ };
Do you really need the new type? Can't you use DUMMY for this?
Re: [PATCH net-next 2/3] bpf: introduce bpf_perf_event_output() helper
Quoted 6 lines · Peter Zijlstra
Quoted 5 lines
PERF_COUNT_SW_DUMMY= 9,include/uapi/linux/perf_event.h enum perf_sw_ids { · line 116
Quoted 4 lines
include/uapi/linux/perf_event.h +1
-0+PERF_COUNT_SW_BPF_OUTPUT =10 , PERF_COUNT_SW_MAX, /* non-ABI */ };Do you really need the new type? Can't you use DUMMY for this?
It works fine with dummy, but user space code looked odd when it perf_event_open-s dummy events and starts reading them. So I thought either to add alias:PERF_COUNT_SW_BPF_OUTPUT = PERF_COUNT_SW_DUMMY
or
add new number like I did above.
New number is cheap and I saw that dummy used for probing, so went with new number to disambiguate.
Peter Zijlstra
maintainerRe: [PATCH net-next 2/3] bpf: introduce bpf_perf_event_output() helper
Quoted 8 lines · Alexei Starovoitov
Quoted 6 lines · Peter Zijlstra
Quoted 5 lines
PERF_COUNT_SW_DUMMY= 9,include/uapi/linux/perf_event.h enum perf_sw_ids { · line 116
Quoted 4 lines
include/uapi/linux/perf_event.h +1
-0+PERF_COUNT_SW_BPF_OUTPUT =10 , PERF_COUNT_SW_MAX, /* non-ABI */ };Do you really need the new type? Can't you use DUMMY for this?
Quoted 8 lines
It works fine with dummy, but user space code looked odd when it perf_event_open-s dummy events and starts reading them. So I thought either to add alias:
PERF_COUNT_SW_BPF_OUTPUT=PERF_COUNT_SW_DUMMY
or
add new number like I did above.
New number is cheap and I saw that dummy used for probing, so went with new number to disambiguate.
Ah, ok. It wasn't clear to me why you needed another number.
The SW numbers add some extra (unused) data size to the kernel as a number of arrays are sized by them, but one more should not hurt (too) much.
Peter Zijlstra
maintainerRe: [PATCH net-next 2/3] bpf: introduce bpf_perf_event_output() helper
In reply to Alexei StarovoitovQuoted 27 lines · Alexei Starovoitov
+++
b/kernel/trace/bpf_trace.ckernel/trace/bpf_trace.c +22
-0@@ -215,6 +215,50 @@ const struct bpf_func_proto bpf_perf_event_read_proto = { .arg2_type = ARG_ANYTHING, }; +static u64 bpf_perf_event_output (u64 r1,u64 r2,u64 index,u64 r4,u64 size) +{ +struct pt_regs *regs = (struct pt_regs *) (long ) r1; +struct bpf_map *map = (struct bpf_map *) (long ) r2; + struct bpf_array *array = container_of(map, struct bpf_array, map); +void *data = (void *) (long ) r4; +struct perf_sample_data sample_data; +struct perf_event *event; +struct perf_raw_record raw = { + .size = size, + .data = data, + }; + +if (unlikely (index >= array->map.max_entries)) +return -E2BIG ; + + event = (struct perf_event *)array->ptrs[index]; +if (unlikely (!event)) +return -ENOENT ; + +if (unlikely (event->attr.type !=PERF_TYPE_SOFTWARE || + event->attr.config !=PERF_COUNT_SW_BPF_OUTPUT ))
kernel/trace/bpf_trace.c const struct bpf_func_proto bpf_perf_event_read_proto = { · line 249
Quoted 10 lines
kernel/trace/bpf_trace.c +10
-0+return -EINVAL ; + +if (unlikely (event->oncpu !=smp_processor_id ())) +return -EOPNOTSUPP ; + +perf_sample_data_init (&sample_data,0 ,0 ); + sample_data.raw = &raw; +perf_event_output (event, &sample_data, regs); +return 0 ; +}
Note that this function also very much requires event to be local.
Re: [PATCH net-next 2/3] bpf: introduce bpf_perf_event_output() helper
Quoted 9 lines · Peter Zijlstra
Quoted 8 lines
kernel/trace/bpf_trace.c +1
-0+if (unlikely (event->oncpu !=smp_processor_id ()))kernel/trace/bpf_trace.c const struct bpf_func_proto bpf_perf_event_read_proto = { · line 249
Quoted 7 lines
kernel/trace/bpf_trace.c +7
-0+return -EOPNOTSUPP ; + +perf_sample_data_init (&sample_data,0 ,0 ); + sample_data.raw = &raw; +perf_event_output (event, &sample_data, regs); +return 0 ; +}Note that this function also very much requires event to be local.
correct. that's why there is a dynamic check above to prevent buggy programs causing issues.
Peter Zijlstra
maintainerRe: [PATCH net-next 2/3] bpf: introduce bpf_perf_event_output() helper
In reply to Alexei Starovoitovkernel/trace/bpf_trace.c const struct bpf_func_proto bpf_perf_event_read_proto = { · line 253
Quoted 3 lines · Alexei Starovoitov
kernel/trace/bpf_trace.c +3
-0+static const struct bpf_func_proto bpf_perf_event_output_proto = { + .func = bpf_perf_event_output, + .gpl_only = false,
Oh ?
Quoted 7 lines
kernel/trace/bpf_trace.c +7
-0+ .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_CONST_MAP_PTR, + .arg3_type = ARG_ANYTHING, + .arg4_type = ARG_PTR_TO_STACK, + .arg5_type = ARG_CONST_STACK_SIZE, +};
Re: [PATCH net-next 2/3] bpf: introduce bpf_perf_event_output() helper
Quoted 5 lines · Peter Zijlstra
Quoted 3 lines · Alexei Starovoitov
kernel/trace/bpf_trace.c const struct bpf_func_proto bpf_perf_event_read_proto = { · line 253
Quoted 3 lines
kernel/trace/bpf_trace.c +3
-0+static const struct bpf_func_proto bpf_perf_event_output_proto = { + .func = bpf_perf_event_output, + .gpl_only = false,Oh ?
no particular reason. key helper bpf_probe_read() is gpl, so all bpf for tracing progs have to be gpl.
If you feel strongly about it, I can change it.
Peter Zijlstra
maintainerRe: [PATCH net-next 2/3] bpf: introduce bpf_perf_event_output() helper
Quoted 10 lines · Alexei Starovoitov
Quoted 5 lines · Peter Zijlstra
Quoted 3 lines · Alexei Starovoitov
kernel/trace/bpf_trace.c const struct bpf_func_proto bpf_perf_event_read_proto = { · line 253
Quoted 3 lines
kernel/trace/bpf_trace.c +3
-0+static const struct bpf_func_proto bpf_perf_event_output_proto = { + .func = bpf_perf_event_output, + .gpl_only = false,Oh ?
no particular reason. key helper
bpf_probe_read()is gpl, so all bpf for tracing progs have to be gpl.
If you feel strongly about it, I can change it.
All the perf symbols are export GPL, so I suppose this should be true.
Re: [PATCH net-next 2/3] bpf: introduce bpf_perf_event_output() helper
Quoted 8 lines · Peter Zijlstra
Quoted 7 lines · Alexei Starovoitov
Quoted 5 lines · Peter Zijlstra
Quoted 3 lines · Alexei Starovoitov
kernel/trace/bpf_trace.c const struct bpf_func_proto bpf_perf_event_read_proto = { · line 253
Quoted 3 lines
kernel/trace/bpf_trace.c +3
-0+static const struct bpf_func_proto bpf_perf_event_output_proto = { + .func = bpf_perf_event_output, + .gpl_only = false,Oh ?
Quoted 5 lines
Quoted 3 lines
no particular reason. key helper
bpf_probe_read()is gpl, so all bpf for tracing progs have to be gpl.
If you feel strongly about it, I can change it.All the perf symbols are export GPL, so I suppose this should be true.
ok. will send a patch.
Re: [PATCH net-next 2/3] bpf: introduce bpf_perf_event_output() helper
Quoted 9 lines · Alexei Starovoitov
Quoted 8 lines · Peter Zijlstra
Quoted 7 lines · Alexei Starovoitov
Quoted 5 lines · Peter Zijlstra
Quoted 3 lines · Alexei Starovoitov
kernel/trace/bpf_trace.c const struct bpf_func_proto bpf_perf_event_read_proto = { · line 253
Quoted 3 lines
kernel/trace/bpf_trace.c +3
-0+static const struct bpf_func_proto bpf_perf_event_output_proto = { + .func = bpf_perf_event_output, + .gpl_only = false,Oh ?
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
no particular reason. key helper
bpf_probe_read()is gpl, so all bpf for tracing progs have to be gpl.
If you feel strongly about it, I can change it.All the perf symbols are export GPL, so I suppose this should be true.
ok. will send a patch.
Can we (or have we already) setup some rules for licensing? Which part should be GPL? Who has the response to decide it?
Thank you.
Re: [PATCH net-next 2/3] bpf: introduce bpf_perf_event_output() helper
Quoted 2 lines · Wangnan (F)
Can we (or have we already) setup some rules for licensing? Which part should be GPL? Who has the response to decide it?
in my mind the rules were set long ago. See my other email.
PATCH 3/3 samples: bpf: add bpf_perf_event_output example
In reply to Alexei StarovoitovPerformance test and example of bpf_perf_event_output(). kprobe is attached to sys_write() and trivial bpf program streams pid+cookie into userspace via PERF_COUNT_SW_BPF_OUTPUT event.
Usage:
$ sudo ./bld_x64/samples/bpf/trace_output recv 2968913 events per sec
--- samples/bpf/Makefile | 7 ++ samples/bpf/bpf_helpers.h | 2 + samples/bpf/trace_output_kern.c | 31 +++++++ samples/bpf/trace_output_user.c | 196 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 236 insertions(+) create mode 100644 samples/bpf/trace_output_kern.c create mode 100644 samples/bpf/trace_output_user.c
samples/bpf/Makefile +7 -0
@@ -13,6 +13,7 @@ hostprogs-y += tracex3 hostprogs-y += tracex4 hostprogs-y += tracex5 hostprogs-y += tracex6 +hostprogs-y += trace_output hostprogs-y += lathist test_verifier-objs := test_verifier.o libbpf.o
@@ -27,6 +28,7 @@ tracex3-objs := bpf_load.o libbpf.o tracex3_user.o tracex4-objs := bpf_load.o libbpf.o tracex4_user.o tracex5-objs := bpf_load.o libbpf.o tracex5_user.o tracex6-objs := bpf_load.o libbpf.o tracex6_user.o +trace_output-objs := bpf_load.o libbpf.o trace_output_user.o lathist-objs := bpf_load.o libbpf.o lathist_user.o # Tell kbuild to always build the programs
@@ -40,6 +42,7 @@ always += tracex3_kern.o always += tracex4_kern.o always += tracex5_kern.o always += tracex6_kern.o +always += trace_output_kern.o always += tcbpf1_kern.o always += lathist_kern.o
@@ -55,6 +58,7 @@ HOSTLOADLIBES_tracex3 += -lelf HOSTLOADLIBES_tracex4 += -lelf -lrt HOSTLOADLIBES_tracex5 += -lelf HOSTLOADLIBES_tracex6 += -lelf +HOSTLOADLIBES_trace_output += -lelf -lrt HOSTLOADLIBES_lathist += -lelf # point this to your LLVM backend with bpf support
@@ -64,3 +68,6 @@ $(obj)/%.o: $(src)/%.c clang $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(EXTRA_CFLAGS) \ -D__KERNEL__ -Wno-unused-value -Wno-pointer-sign \ -O2 -emit-llvm -c $< -o -| $(LLC) -march=bpf -filetype=obj -o $@ + clang $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(EXTRA_CFLAGS) \ + -D__KERNEL__ -Wno-unused-value -Wno-pointer-sign \ + -O2 -emit-llvm -c $< -o -| $(LLC) -march=bpf -filetype=asm -o [email protected]
samples/bpf/bpf_helpers.h +2 -0
@@ -37,6 +37,8 @@ static int (*bpf_clone_redirect)(void *ctx, int ifindex, int flags) = (void *) BPF_FUNC_clone_redirect;static int (*bpf_redirect)(int ifindex,int flags) = (void *) BPF_FUNC_redirect; +static int (*bpf_perf_event_output)(void *ctx,void *map,int index,void *data,int size) = + (void *) BPF_FUNC_perf_event_output;/* llvm builtin functions that eBPF C program may use to * emit BPF_LD_ABS and BPF_LD_IND instructions
samples/bpf/trace_output_kern.c new file +31 -0
@@ -0,0 +1,31 @@ +#include <linux/ptrace.h> +#include <linux/version.h> +#include <uapi/linux/bpf.h> +#include "bpf_helpers.h" + +struct bpf_map_def SEC("maps") my_map = { + .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY, + .key_size = sizeof(int), + .value_size = sizeof(u32), + .max_entries = 2, +}; + +SEC("kprobe/sys_write") +int bpf_prog1 (struct pt_regs *ctx) +{ +struct S { +u64 pid; +u64 cookie; + } data; + +memset (&data,0 ,sizeof (data)); + data.pid =bpf_get_current_pid_tgid (); + data.cookie =0x12345678 ; + +bpf_perf_event_output (ctx, &my_map,0 , &data,sizeof (data)); + +return 0 ; +} + +char _license[] SEC("license") = "GPL"; +u32 _version SEC("version") = LINUX_VERSION_CODE;
samples/bpf/trace_output_user.c new file +196 -0
196 lines not on this page · raw message
Signature · 1 line
1.7.9.5
David Miller
maintainerFrom: Alexei Starovoitov <[email protected]>
Date: Tue, 20 Oct 2015 20:02:32 -0700
Quoted 11 lines
Over the last year there were multiple attempts to let eBPF programs output data into perf events by He Kuang and Wangnan.
The last one was:
https://lkml.org/lkml/2015/7/20/736
It was almost perfect with exception that all bpf programs would sent data into one globalperf_event.
This patch set takes different approach by letting user space open independentPERF_COUNT_SW_BPF_OUTPUTevents, so that program output won't collide.Wangnan is working on corresponding perf patches.
Series applied, thanks.