From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:03:58
hi,
this patchset adds trampoline and dispatcher objects
to be visible in /proc/kallsyms. The last patch also
adds sorting for all bpf objects in /proc/kallsyms.
$ sudo cat /proc/kallsyms | tail -20
...
ffffffffa050f000 t bpf_prog_5a2b06eab81b8f51 [bpf]
ffffffffa0511000 t bpf_prog_6deef7357e7b4530 [bpf]
ffffffffa0542000 t bpf_trampoline_13832 [bpf]
ffffffffa0548000 t bpf_prog_96f1b5bf4e4cc6dc_mutex_lock [bpf]
ffffffffa0572000 t bpf_prog_d1c63e29ad82c4ab_bpf_prog1 [bpf]
ffffffffa0585000 t bpf_prog_e314084d332a5338__dissect [bpf]
ffffffffa0587000 t bpf_prog_59785a79eac7e5d2_mutex_unlock [bpf]
ffffffffa0589000 t bpf_prog_d0db6e0cac050163_mutex_lock [bpf]
ffffffffa058d000 t bpf_prog_d8f047721e4d8321_bpf_prog2 [bpf]
ffffffffa05df000 t bpf_trampoline_25637 [bpf]
ffffffffa05e3000 t bpf_prog_d8f047721e4d8321_bpf_prog2 [bpf]
ffffffffa05e5000 t bpf_prog_3b185187f1855c4c [bpf]
ffffffffa05e7000 t bpf_prog_d8f047721e4d8321_bpf_prog2 [bpf]
ffffffffa05eb000 t bpf_prog_93cebb259dd5c4b2_do_sys_open [bpf]
ffffffffa0677000 t bpf_dispatcher_xdp [bpf]
v3 changes:
- use container_of directly in bpf_get_ksym_start [Daniel]
- add more changelog explanations for ksym addresses [Daniel]
v2 changes:
- omit extra condition in __bpf_ksym_add for sorting code (Andrii)
- rename bpf_kallsyms_tree_ops to bpf_ksym_tree (Andrii)
- expose only executable code in kallsyms (Andrii)
- use full trampoline key as its kallsyms id (Andrii)
- explained the BPF_TRAMP_REPLACE case (Andrii)
- small format changes in bpf_trampoline_link_prog/bpf_trampoline_unlink_prog (Andrii)
- propagate error value in bpf_dispatcher_update and update kallsym if it's successful (Andrii)
- get rid of __always_inline for bpf_ksym_tree callbacks (Andrii)
- added KSYMBOL notification for bpf_image add/removal
- added perf tools changes to properly display trampoline/dispatcher
For perf tool to properly display trampoline/dispatcher you need
also Arnaldo's perf/urgent branch changes. I merged everything
into following branch:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git bpf/kallsyms
thanks,
jirka
---
Björn Töpel (1):
bpf: Add bpf_trampoline_ name prefix for DECLARE_BPF_DISPATCHER
Jiri Olsa (17):
x86/mm: Rename is_kernel_text to __is_kernel_text
bpf: Add struct bpf_ksym
bpf: Add name to struct bpf_ksym
bpf: Add lnode list node to struct bpf_ksym
bpf: Add bpf_ksym_tree tree
bpf: Move bpf_tree add/del from bpf_prog_ksym_node_add/del
bpf: Separate kallsyms add/del functions
bpf: Add bpf_ksym_add/del functions
bpf: Re-initialize lnode in bpf_ksym_del
bpf: Rename bpf_tree to bpf_progs_tree
bpf: Add trampolines to kallsyms
bpf: Return error value in bpf_dispatcher_update
bpf: Add dispatchers to kallsyms
bpf: Sort bpf kallsyms symbols
perf tools: Synthesize bpf_trampoline/dispatcher ksymbol event
perf tools: Set ksymbol dso as loaded on arrival
perf annotate: Add base support for bpf_image
arch/x86/mm/init_32.c | 14 +++++++++-----
include/linux/bpf.h | 55 ++++++++++++++++++++++++++++++++++++++-----------------
include/linux/filter.h | 13 +++----------
kernel/bpf/core.c | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------
kernel/bpf/dispatcher.c | 19 ++++++++++++++-----
kernel/bpf/trampoline.c | 38 +++++++++++++++++++++++++++++++++++++-
kernel/events/core.c | 9 ++++-----
net/core/filter.c | 5 ++---
tools/perf/util/annotate.c | 20 ++++++++++++++++++++
tools/perf/util/bpf-event.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/dso.c | 1 +
tools/perf/util/dso.h | 1 +
tools/perf/util/machine.c | 12 ++++++++++++
tools/perf/util/symbol.c | 1 +
14 files changed, 371 insertions(+), 91 deletions(-)
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:04:00
The kbuild test robot reported compile issue on x86 in one of
the following patches that adds <linux/kallsyms.h> include into
<linux/bpf.h>, which is picked up by init_32.c object.
The problem is that <linux/kallsyms.h> defines global function
is_kernel_text which colides with the static function of the
same name defined in init_32.c:
$ make ARCH=i386
...
>> arch/x86/mm/init_32.c:241:19: error: redefinition of 'is_kernel_text'
static inline int is_kernel_text(unsigned long addr)
^~~~~~~~~~~~~~
In file included from include/linux/bpf.h:21:0,
from include/linux/bpf-cgroup.h:5,
from include/linux/cgroup-defs.h:22,
from include/linux/cgroup.h:28,
from include/linux/hugetlb.h:9,
from arch/x86/mm/init_32.c:18:
include/linux/kallsyms.h:31:19: note: previous definition of 'is_kernel_text' was here
static inline int is_kernel_text(unsigned long addr)
Renaming the init_32.c is_kernel_text function to __is_kernel_text.
Reported-by: kbuild test robot <redacted>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
arch/x86/mm/init_32.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:04:05
From: Björn Töpel <redacted>
Adding bpf_trampoline_ name prefix for DECLARE_BPF_DISPATCHER,
so all the dispatchers have the common name prefix.
And also a small '_' cleanup for bpf_dispatcher_nopfunc function
name.
Signed-off-by: Björn Töpel <redacted>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
include/linux/bpf.h | 21 +++++++++++----------
include/linux/filter.h | 7 +++----
net/core/filter.c | 5 ++---
3 files changed, 16 insertions(+), 17 deletions(-)
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:04:09
Adding 'struct bpf_ksym' object that will carry the
kallsym information for bpf symbol. Adding the start
and end address to begin with. It will be used by
bpf_prog, bpf_trampoline, bpf_dispatcher.
The symbol_start/symbol_end values were originally used
to sort bpf_prog objects. For the address displayed in
/proc/kallsyms we are using prog->bpf_func.
I'm using the bpf_func for program symbol start instead
of the symbol_start, because it makes no difference for
sorting bpf_prog objects and we can use it directly as
an address for display it in /proc/kallsyms.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
include/linux/bpf.h | 6 ++++++
kernel/bpf/core.c | 26 +++++++++++---------------
2 files changed, 17 insertions(+), 15 deletions(-)
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:04:13
Adding name to 'struct bpf_ksym' object to carry the name
of the symbol for bpf_prog, bpf_trampoline, bpf_dispatcher.
The current benefit is that name is now generated only when
the symbol is added to the list, so we don't need to generate
it every time it's accessed.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
include/linux/bpf.h | 2 ++
include/linux/filter.h | 6 ------
kernel/bpf/core.c | 8 +++++---
kernel/events/core.c | 9 ++++-----
4 files changed, 11 insertions(+), 14 deletions(-)
@@ -681,7 +683,7 @@ const char *__bpf_address_lookup(unsigned long addr, unsigned long *size,unsignedlongsymbol_start=prog->aux->ksym.start;unsignedlongsymbol_end=prog->aux->ksym.end;-bpf_get_prog_name(prog,sym);+strncpy(sym,prog->aux->ksym.name,KSYM_NAME_LEN);ret=sym;if(size)
@@ -738,7 +740,7 @@ int bpf_get_kallsym(unsigned int symnum, unsigned long *value, char *type,if(it++!=symnum)continue;-bpf_get_prog_name(aux->prog,sym);+strncpy(sym,aux->ksym.name,KSYM_NAME_LEN);*value=(unsignedlong)aux->prog->bpf_func;*type=BPF_SYM_ELF_TYPE;
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:04:16
Adding lnode list node to 'struct bpf_ksym' object,
so the symbol itself can be chained and used in other
objects like bpf_trampoline and bpf_dispatcher.
Changing iterator to bpf_ksym in bpf_get_kallsym.
The ksym->start is holding the prog->bpf_func value,
so it's ok to use it in bpf_get_kallsym.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
include/linux/bpf.h | 2 +-
kernel/bpf/core.c | 22 +++++++++++-----------
2 files changed, 12 insertions(+), 12 deletions(-)
@@ -728,7 +728,7 @@ const struct exception_table_entry *search_bpf_extables(unsigned long addr)intbpf_get_kallsym(unsignedintsymnum,unsignedlong*value,char*type,char*sym){-structbpf_prog_aux*aux;+structbpf_ksym*ksym;unsignedintit=0;intret=-ERANGE;
@@ -736,13 +736,13 @@ int bpf_get_kallsym(unsigned int symnum, unsigned long *value, char *type,returnret;rcu_read_lock();-list_for_each_entry_rcu(aux,&bpf_kallsyms,ksym_lnode){+list_for_each_entry_rcu(ksym,&bpf_kallsyms,lnode){if(it++!=symnum)continue;-strncpy(sym,aux->ksym.name,KSYM_NAME_LEN);+strncpy(sym,ksym->name,KSYM_NAME_LEN);-*value=(unsignedlong)aux->prog->bpf_func;+*value=ksym->start;*type=BPF_SYM_ELF_TYPE;ret=0;
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:04:23
The bpf_tree is used both for kallsyms iterations and searching
for exception tables of bpf programs, which is needed only for
bpf programs.
Adding bpf_ksym_tree that will hold symbols for all bpf_prog
bpf_trampoline and bpf_dispatcher objects and keeping bpf_tree
only for bpf_prog objects to keep it fast.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
include/linux/bpf.h | 1 +
kernel/bpf/core.c | 56 ++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 51 insertions(+), 6 deletions(-)
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:04:23
Moving bpf_tree add/del from bpf_prog_ksym_node_add/del,
because it will be used (and renamed) in following patches
for bpf_ksym objects. The bpf_tree is specific for bpf_prog
objects.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
kernel/bpf/core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:04:30
Adding bpf_ksym_add/del functions as locked version
for __bpf_ksym_add/del. It will be used in following
patches for bpf_trampoline and bpf_dispatcher.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
include/linux/bpf.h | 3 +++
kernel/bpf/core.c | 14 ++++++++++++++
2 files changed, 17 insertions(+)
@@ -573,6 +573,9 @@ struct bpf_image {#define BPF_IMAGE_SIZE (PAGE_SIZE - sizeof(struct bpf_image))boolis_bpf_image_address(unsignedlongaddress);void*bpf_image_alloc(void);+/* Called only from code, so there's no need for stubs. */+voidbpf_ksym_add(structbpf_ksym*ksym);+voidbpf_ksym_del(structbpf_ksym*ksym);#elsestaticinlinestructbpf_trampoline*bpf_trampoline_lookup(u64key){
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:04:33
When bpf_prog is removed from kallsyms it's on the way
out to be removed, so we don't care about lnode state.
However the bpf_ksym_del will be used also by bpf_trampoline
and bpf_dispatcher objects, which stay allocated even when
they are not in kallsyms list, hence the lnode re-init.
The list_del_rcu commentary states that we need to call
synchronize_rcu, before we can change/re-init the list_head
pointers.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
kernel/bpf/core.c | 7 +++++++
1 file changed, 7 insertions(+)
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:04:37
Renaming bpf_tree to bpf_progs_tree and bpf_tree_ops
to bpf_progs_tree_ops to better capture the usage of
the tree which is for the bpf_prog objects only.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
kernel/bpf/core.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:04:55
Adding trampolines to kallsyms. It's displayed as
bpf_trampoline_<ID> [bpf]
where ID is the BTF id of the trampoline function.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
include/linux/bpf.h | 3 +++
kernel/bpf/trampoline.c | 38 +++++++++++++++++++++++++++++++++++++-
2 files changed, 40 insertions(+), 1 deletion(-)
@@ -502,6 +502,7 @@ struct bpf_trampoline {/* Executable image of trampoline */void*image;u64selector;+structbpf_ksymksym;};#define BPF_DISPATCHER_MAX 48 /* Fits in 2048B */
@@ -573,6 +574,8 @@ struct bpf_image {#define BPF_IMAGE_SIZE (PAGE_SIZE - sizeof(struct bpf_image))boolis_bpf_image_address(unsignedlongaddress);void*bpf_image_alloc(void);+voidbpf_image_ksym_add(void*data,structbpf_ksym*ksym);+voidbpf_image_ksym_del(structbpf_ksym*ksym);/* Called only from code, so there's no need for stubs. */voidbpf_ksym_add(structbpf_ksym*ksym);voidbpf_ksym_del(structbpf_ksym*ksym);
@@ -5,6 +5,7 @@#include<linux/filter.h>#include<linux/ftrace.h>#include<linux/rbtree_latch.h>+#include<linux/perf_event.h>/* dummy _ops. The verifier will operate on target program's ops. */conststructbpf_verifier_opsbpf_extension_verifier_ops={
@@ -96,6 +97,22 @@ bool is_bpf_image_address(unsigned long addr)returnret;}+voidbpf_image_ksym_add(void*data,structbpf_ksym*ksym)+{+ksym->start=(unsignedlong)data;+ksym->end=ksym->start+BPF_IMAGE_SIZE;+bpf_ksym_add(ksym);+perf_event_ksymbol(PERF_RECORD_KSYMBOL_TYPE_BPF,ksym->start,+BPF_IMAGE_SIZE,false,ksym->name);+}++voidbpf_image_ksym_del(structbpf_ksym*ksym)+{+bpf_ksym_del(ksym);+perf_event_ksymbol(PERF_RECORD_KSYMBOL_TYPE_BPF,ksym->start,+BPF_IMAGE_SIZE,true,ksym->name);+}+structbpf_trampoline*bpf_trampoline_lookup(u64key){structbpf_trampoline*tr;
@@ -291,6 +317,10 @@ int bpf_trampoline_link_prog(struct bpf_prog *prog)err=-EBUSY;gotoout;}+/* With cnt == 0 image is not used (no symbol in kallsyms)+*andwillnotbeusedforBPF_PROG_TYPE_EXTprogtype,+*sothere'snosymboladdedforthiscase.+*/tr->extension_prog=prog;err=bpf_arch_text_poke(tr->func.addr,BPF_MOD_JUMP,NULL,prog->bpf_func);
@@ -311,7 +341,10 @@ int bpf_trampoline_link_prog(struct bpf_prog *prog)if(err){hlist_del(&prog->aux->tramp_hlist);tr->progs_cnt[kind]--;+gotoout;}+if(cnt==0)+bpf_trampoline_ksym_add(tr);out:mutex_unlock(&tr->mutex);returnerr;
@@ -322,7 +355,7 @@ int bpf_trampoline_unlink_prog(struct bpf_prog *prog){enumbpf_tramp_prog_typekind;structbpf_trampoline*tr;-interr;+interr,cnt;tr=prog->aux->trampoline;kind=bpf_attach_type_to_tramp(prog->expected_attach_type);
@@ -336,6 +369,9 @@ int bpf_trampoline_unlink_prog(struct bpf_prog *prog)}hlist_del(&prog->aux->tramp_hlist);tr->progs_cnt[kind]--;+cnt=tr->progs_cnt[BPF_TRAMP_FENTRY]+tr->progs_cnt[BPF_TRAMP_FEXIT];+if(cnt==0)+bpf_image_ksym_del(&tr->ksym);err=bpf_trampoline_update(prog->aux->trampoline);out:mutex_unlock(&tr->mutex);
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:04:57
We don't currently propagate error value from
bpf_dispatcher_update function. This will be
needed in following patch, that needs to update
kallsyms based on the success of dispatcher
update.
Suggested-by: Andrii Nakryiko <redacted>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
kernel/bpf/dispatcher.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:05:03
Adding dispatchers to kallsyms. It's displayed as
bpf_dispatcher_<NAME>
where NAME is the name of dispatcher.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
include/linux/bpf.h | 19 ++++++++++++-------
kernel/bpf/dispatcher.c | 9 ++++++++-
2 files changed, 20 insertions(+), 8 deletions(-)
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:05:09
Currently we don't sort bpf_kallsyms and display symbols
in proc/kallsyms as they come in via __bpf_ksym_add.
Using the latch tree to get the next bpf_ksym object
and insert the new symbol ahead of it.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
kernel/bpf/core.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:05:12
Synthesize bpf images (trampolines/dispatchers) on start,
as ksymbol events from /proc/kallsyms. Having this perf
can recognize samples from those images and perf report
and top shows them correctly.
The rest of the ksymbol handling is already in place from
for the bpf programs monitoring, so only the initial state
was needed.
perf report output:
# Overhead Command Shared Object Symbol
12.37% test_progs [kernel.vmlinux] [k] entry_SYSCALL_64
11.80% test_progs [kernel.vmlinux] [k] syscall_return_via_sysret
9.63% test_progs bpf_prog_bcf7977d3b93787c_prog2 [k] bpf_prog_bcf7977d3b93787c_prog2
6.90% test_progs bpf_trampoline_24456 [k] bpf_trampoline_24456
6.36% test_progs [kernel.vmlinux] [k] memcpy_erms
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
tools/perf/util/bpf-event.c | 98 +++++++++++++++++++++++++++++++++++++
1 file changed, 98 insertions(+)
@@ -290,11 +293,87 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session,returnerr?-1:0;}+structkallsyms_parse{+unionperf_event*event;+perf_event__handler_tprocess;+structmachine*machine;+structperf_tool*tool;+};++staticint+process_bpf_image(char*name,u64addr,structkallsyms_parse*data)+{+structmachine*machine=data->machine;+unionperf_event*event=data->event;+structperf_record_ksymbol*ksymbol;+u32size;++ksymbol=&event->ksymbol;++/*+*Thebpfimage(trampoline/dispatcher)sizeisalignedto+*page,whileitstartslittlebitafterthepageboundary.+*/+size=page_size-(addr-PERF_ALIGN(addr,page_size));++*ksymbol=(structperf_record_ksymbol){+.header={+.type=PERF_RECORD_KSYMBOL,+.size=offsetof(structperf_record_ksymbol,name),+},+.addr=addr,+.len=size,+.ksym_type=PERF_RECORD_KSYMBOL_TYPE_BPF,+.flags=0,+};++strncpy(ksymbol->name,name,KSYM_NAME_LEN);+ksymbol->header.size+=PERF_ALIGN(strlen(name)+1,sizeof(u64));+memset((void*)event+event->header.size,0,machine->id_hdr_size);+event->header.size+=machine->id_hdr_size;++returnperf_tool__process_synth_event(data->tool,event,machine,+data->process);+}++staticint+kallsyms_process_symbol(void*data,constchar*_name,+chartype__maybe_unused,u64start)+{+char*module,*name;+unsignedlongid;+interr=0;++module=strchr(_name,'\t');+if(!module)+return0;++/* We are going after [bpf] module ... */+if(strcmp(module+1,"[bpf]"))+return0;++name=memdup(_name,(module-_name)+1);+if(!name)+return-ENOMEM;++name[module-_name]=0;++/* .. and only for trampolines and dispatchers */+if((sscanf(name,"bpf_trampoline_%lu",&id)==1)||+(sscanf(name,"bpf_dispatcher_%lu",&id)==1))+err=process_bpf_image(name,start,data);++free(name);+returnerr;+}+intperf_event__synthesize_bpf_events(structperf_session*session,perf_event__handler_tprocess,structmachine*machine,structrecord_opts*opts){+constchar*kallsyms_filename="/proc/kallsyms";+structkallsyms_parsearg;unionperf_event*event;__u32id=0;interr;
@@ -303,6 +382,8 @@ int perf_event__synthesize_bpf_events(struct perf_session *session,event=malloc(sizeof(event->bpf)+KSYM_NAME_LEN+machine->id_hdr_size);if(!event)return-1;++/* Synthesize all the bpf programs in system. */while(true){err=bpf_prog_get_next_id(id,&id);if(err){
@@ -335,6 +416,23 @@ int perf_event__synthesize_bpf_events(struct perf_session *session,break;}}++/* Synthesize all the bpf images - trampolines/dispatchers. */+if(symbol_conf.kallsyms_name!=NULL)+kallsyms_filename=symbol_conf.kallsyms_name;++arg=(structkallsyms_parse){+.event=event,+.process=process,+.machine=machine,+.tool=session->tool,+};++if(kallsyms__parse(kallsyms_filename,&arg,kallsyms_process_symbol)){+pr_err("%s: failed to synthesize bpf images: %s\n",+__func__,strerror(errno));+}+free(event);returnerr;}
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:05:19
There's no special load action for ksymbol data on
map__load/dso__load action, where the kernel is getting
loaded. It only gets confused with kernel kallsyms/vmlinux
load for bpf object, which fails and could mess up with
the map.
Disabling any further load of the map for ksymbol related dso/map.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
tools/perf/util/machine.c | 1 +
1 file changed, 1 insertion(+)
From: Jiri Olsa <jolsa@kernel.org> Date: 2020-02-26 13:05:24
Adding the DSO_BINARY_TYPE__BPF_IMAGE dso binary type
to recognize bpf images that carry trampoline or dispatcher.
Upcoming patches will add support to read the image data,
store it within the BPF feature in perf.data and display
it for annotation purposes.
Currently we only display following message:
# ./perf annotate bpf_trampoline_24456 --stdio
Percent | Source code & Disassembly of . for cycles (504 ...
--------------------------------------------------------------- ...
: to be implemented
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
tools/perf/util/annotate.c | 20 ++++++++++++++++++++
tools/perf/util/dso.c | 1 +
tools/perf/util/dso.h | 1 +
tools/perf/util/machine.c | 11 +++++++++++
tools/perf/util/symbol.c | 1 +
5 files changed, 34 insertions(+)
From: Song Liu <song@kernel.org> Date: 2020-02-26 18:44:21
On Wed, Feb 26, 2020 at 5:04 AM Jiri Olsa [off-list ref] wrote:
The kbuild test robot reported compile issue on x86 in one of
the following patches that adds <linux/kallsyms.h> include into
<linux/bpf.h>, which is picked up by init_32.c object.
The problem is that <linux/kallsyms.h> defines global function
is_kernel_text which colides with the static function of the
same name defined in init_32.c:
$ make ARCH=i386
...
>> arch/x86/mm/init_32.c:241:19: error: redefinition of 'is_kernel_text'
static inline int is_kernel_text(unsigned long addr)
^~~~~~~~~~~~~~
In file included from include/linux/bpf.h:21:0,
from include/linux/bpf-cgroup.h:5,
from include/linux/cgroup-defs.h:22,
from include/linux/cgroup.h:28,
from include/linux/hugetlb.h:9,
from arch/x86/mm/init_32.c:18:
include/linux/kallsyms.h:31:19: note: previous definition of 'is_kernel_text' was here
static inline int is_kernel_text(unsigned long addr)
Renaming the init_32.c is_kernel_text function to __is_kernel_text.
Reported-by: kbuild test robot <redacted>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
From: Song Liu <song@kernel.org> Date: 2020-02-26 18:55:03
On Wed, Feb 26, 2020 at 5:04 AM Jiri Olsa [off-list ref] wrote:
From: Björn Töpel <redacted>
Adding bpf_trampoline_ name prefix for DECLARE_BPF_DISPATCHER,
so all the dispatchers have the common name prefix.
And also a small '_' cleanup for bpf_dispatcher_nopfunc function
name.
Signed-off-by: Björn Töpel <redacted>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
From: Song Liu <song@kernel.org> Date: 2020-02-26 19:01:52
On Wed, Feb 26, 2020 at 5:05 AM Jiri Olsa [off-list ref] wrote:
Adding 'struct bpf_ksym' object that will carry the
kallsym information for bpf symbol. Adding the start
and end address to begin with. It will be used by
bpf_prog, bpf_trampoline, bpf_dispatcher.
The symbol_start/symbol_end values were originally used
to sort bpf_prog objects. For the address displayed in
/proc/kallsyms we are using prog->bpf_func.
I'm using the bpf_func for program symbol start instead
of the symbol_start, because it makes no difference for
sorting bpf_prog objects and we can use it directly as
an address for display it in /proc/kallsyms.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
From: Song Liu <song@kernel.org> Date: 2020-02-26 21:14:58
On Wed, Feb 26, 2020 at 5:04 AM Jiri Olsa [off-list ref] wrote:
Adding name to 'struct bpf_ksym' object to carry the name
of the symbol for bpf_prog, bpf_trampoline, bpf_dispatcher.
The current benefit is that name is now generated only when
the symbol is added to the list, so we don't need to generate
it every time it's accessed.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
The patch looks good. But I wonder whether we want pay the cost of
extra 128 bytes per bpf program. Maybe make it a pointer and only
generate the string when it is first used?
Thanks,
Song
From: Song Liu <song@kernel.org> Date: 2020-02-26 22:51:28
On Wed, Feb 26, 2020 at 5:05 AM Jiri Olsa [off-list ref] wrote:
Adding lnode list node to 'struct bpf_ksym' object,
so the symbol itself can be chained and used in other
objects like bpf_trampoline and bpf_dispatcher.
Changing iterator to bpf_ksym in bpf_get_kallsym.
The ksym->start is holding the prog->bpf_func value,
so it's ok to use it in bpf_get_kallsym.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Acked-by: Song Liu <redacted>
nit: I think we should describe this as "move lnode list node to
struct bpf_ksym".
From: Song Liu <song@kernel.org> Date: 2020-02-26 23:10:23
On Wed, Feb 26, 2020 at 5:04 AM Jiri Olsa [off-list ref] wrote:
The bpf_tree is used both for kallsyms iterations and searching
for exception tables of bpf programs, which is needed only for
bpf programs.
Adding bpf_ksym_tree that will hold symbols for all bpf_prog
bpf_trampoline and bpf_dispatcher objects and keeping bpf_tree
only for bpf_prog objects to keep it fast.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
From: Song Liu <song@kernel.org> Date: 2020-02-26 23:12:35
On Wed, Feb 26, 2020 at 5:04 AM Jiri Olsa [off-list ref] wrote:
Moving bpf_tree add/del from bpf_prog_ksym_node_add/del,
because it will be used (and renamed) in following patches
for bpf_ksym objects. The bpf_tree is specific for bpf_prog
objects.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
From: Song Liu <song@kernel.org> Date: 2020-02-26 23:14:23
On Wed, Feb 26, 2020 at 5:05 AM Jiri Olsa [off-list ref] wrote:
Moving bpf_prog_ksym_node_add/del to __bpf_ksym_add/del
and changing the argument to 'struct bpf_ksym' object.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
From: Song Liu <song@kernel.org> Date: 2020-02-26 23:16:23
On Wed, Feb 26, 2020 at 5:06 AM Jiri Olsa [off-list ref] wrote:
Adding bpf_ksym_add/del functions as locked version
for __bpf_ksym_add/del. It will be used in following
patches for bpf_trampoline and bpf_dispatcher.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
From: Song Liu <song@kernel.org> Date: 2020-02-26 23:21:50
On Wed, Feb 26, 2020 at 5:06 AM Jiri Olsa [off-list ref] wrote:
When bpf_prog is removed from kallsyms it's on the way
out to be removed, so we don't care about lnode state.
However the bpf_ksym_del will be used also by bpf_trampoline
and bpf_dispatcher objects, which stay allocated even when
they are not in kallsyms list, hence the lnode re-init.
The list_del_rcu commentary states that we need to call
synchronize_rcu, before we can change/re-init the list_head
pointers.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
From: Song Liu <song@kernel.org> Date: 2020-02-26 23:22:28
On Wed, Feb 26, 2020 at 5:06 AM Jiri Olsa [off-list ref] wrote:
Renaming bpf_tree to bpf_progs_tree and bpf_tree_ops
to bpf_progs_tree_ops to better capture the usage of
the tree which is for the bpf_prog objects only.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
From: Song Liu <song@kernel.org> Date: 2020-02-26 23:36:34
On Wed, Feb 26, 2020 at 5:07 AM Jiri Olsa [off-list ref] wrote:
Adding trampolines to kallsyms. It's displayed as
bpf_trampoline_<ID> [bpf]
where ID is the BTF id of the trampoline function.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
From: Song Liu <song@kernel.org> Date: 2020-02-26 23:45:16
On Wed, Feb 26, 2020 at 5:07 AM Jiri Olsa [off-list ref] wrote:
We don't currently propagate error value from
bpf_dispatcher_update function. This will be
needed in following patch, that needs to update
kallsyms based on the success of dispatcher
update.
Suggested-by: Andrii Nakryiko <redacted>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
From: Song Liu <song@kernel.org> Date: 2020-02-26 23:48:33
On Wed, Feb 26, 2020 at 5:07 AM Jiri Olsa [off-list ref] wrote:
Adding dispatchers to kallsyms. It's displayed as
bpf_dispatcher_<NAME>
where NAME is the name of dispatcher.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
From: Song Liu <song@kernel.org> Date: 2020-02-26 23:57:33
On Wed, Feb 26, 2020 at 5:06 AM Jiri Olsa [off-list ref] wrote:
Currently we don't sort bpf_kallsyms and display symbols
in proc/kallsyms as they come in via __bpf_ksym_add.
Using the latch tree to get the next bpf_ksym object
and insert the new symbol ahead of it.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
From: Song Liu <song@kernel.org> Date: 2020-02-27 05:50:45
On Wed, Feb 26, 2020 at 5:06 AM Jiri Olsa [off-list ref] wrote:
Synthesize bpf images (trampolines/dispatchers) on start,
as ksymbol events from /proc/kallsyms. Having this perf
can recognize samples from those images and perf report
and top shows them correctly.
The rest of the ksymbol handling is already in place from
for the bpf programs monitoring, so only the initial state
was needed.
perf report output:
# Overhead Command Shared Object Symbol
12.37% test_progs [kernel.vmlinux] [k] entry_SYSCALL_64
11.80% test_progs [kernel.vmlinux] [k] syscall_return_via_sysret
9.63% test_progs bpf_prog_bcf7977d3b93787c_prog2 [k] bpf_prog_bcf7977d3b93787c_prog2
6.90% test_progs bpf_trampoline_24456 [k] bpf_trampoline_24456
6.36% test_progs [kernel.vmlinux] [k] memcpy_erms
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
From: Song Liu <song@kernel.org> Date: 2020-02-27 05:52:56
On Wed, Feb 26, 2020 at 5:06 AM Jiri Olsa [off-list ref] wrote:
There's no special load action for ksymbol data on
map__load/dso__load action, where the kernel is getting
loaded. It only gets confused with kernel kallsyms/vmlinux
load for bpf object, which fails and could mess up with
the map.
Disabling any further load of the map for ksymbol related dso/map.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
From: Song Liu <song@kernel.org> Date: 2020-02-27 05:54:30
On Wed, Feb 26, 2020 at 5:06 AM Jiri Olsa [off-list ref] wrote:
Adding the DSO_BINARY_TYPE__BPF_IMAGE dso binary type
to recognize bpf images that carry trampoline or dispatcher.
Upcoming patches will add support to read the image data,
store it within the BPF feature in perf.data and display
it for annotation purposes.
Currently we only display following message:
# ./perf annotate bpf_trampoline_24456 --stdio
Percent | Source code & Disassembly of . for cycles (504 ...
--------------------------------------------------------------- ...
: to be implemented
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
From: Martin KaFai Lau <hidden> Date: 2020-02-27 06:27:18
On Wed, Feb 26, 2020 at 02:03:39PM +0100, Jiri Olsa wrote:
quoted hunk
Adding trampolines to kallsyms. It's displayed as
bpf_trampoline_<ID> [bpf]
where ID is the BTF id of the trampoline function.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
include/linux/bpf.h | 3 +++
kernel/bpf/trampoline.c | 38 +++++++++++++++++++++++++++++++++++++-
2 files changed, 40 insertions(+), 1 deletion(-)
@@ -502,6 +502,7 @@ struct bpf_trampoline {/* Executable image of trampoline */void*image;u64selector;+structbpf_ksymksym;};#define BPF_DISPATCHER_MAX 48 /* Fits in 2048B */
@@ -573,6 +574,8 @@ struct bpf_image {#define BPF_IMAGE_SIZE (PAGE_SIZE - sizeof(struct bpf_image))boolis_bpf_image_address(unsignedlongaddress);void*bpf_image_alloc(void);+voidbpf_image_ksym_add(void*data,structbpf_ksym*ksym);+voidbpf_image_ksym_del(structbpf_ksym*ksym);/* Called only from code, so there's no need for stubs. */voidbpf_ksym_add(structbpf_ksym*ksym);voidbpf_ksym_del(structbpf_ksym*ksym);
@@ -5,6 +5,7 @@#include<linux/filter.h>#include<linux/ftrace.h>#include<linux/rbtree_latch.h>+#include<linux/perf_event.h>/* dummy _ops. The verifier will operate on target program's ops. */conststructbpf_verifier_opsbpf_extension_verifier_ops={
@@ -96,6 +97,22 @@ bool is_bpf_image_address(unsigned long addr)returnret;}+voidbpf_image_ksym_add(void*data,structbpf_ksym*ksym)+{+ksym->start=(unsignedlong)data;+ksym->end=ksym->start+BPF_IMAGE_SIZE;+bpf_ksym_add(ksym);+perf_event_ksymbol(PERF_RECORD_KSYMBOL_TYPE_BPF,ksym->start,+BPF_IMAGE_SIZE,false,ksym->name);+}++voidbpf_image_ksym_del(structbpf_ksym*ksym)+{+bpf_ksym_del(ksym);+perf_event_ksymbol(PERF_RECORD_KSYMBOL_TYPE_BPF,ksym->start,+BPF_IMAGE_SIZE,true,ksym->name);+}+structbpf_trampoline*bpf_trampoline_lookup(u64key){structbpf_trampoline*tr;
Do you have plan to support struct_ops which is also using
trampoline (in bpf_struct_ops_map_update_elem())?
Any idea on the name? bpf_struct_ops_<map_id>?
Do you have plan to support struct_ops which is also using
trampoline (in bpf_struct_ops_map_update_elem())?
Any idea on the name? bpf_struct_ops_<map_id>?
right, I was wondering we should also do that,
I'll check on it
jirka
From: Jiri Olsa <hidden> Date: 2020-02-27 08:15:37
On Wed, Feb 26, 2020 at 02:51:14PM -0800, Song Liu wrote:
On Wed, Feb 26, 2020 at 5:05 AM Jiri Olsa [off-list ref] wrote:
quoted
Adding lnode list node to 'struct bpf_ksym' object,
so the symbol itself can be chained and used in other
objects like bpf_trampoline and bpf_dispatcher.
Changing iterator to bpf_ksym in bpf_get_kallsym.
The ksym->start is holding the prog->bpf_func value,
so it's ok to use it in bpf_get_kallsym.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Acked-by: Song Liu <redacted>
nit: I think we should describe this as "move lnode list node to
struct bpf_ksym".
From: Jiri Olsa <hidden> Date: 2020-02-27 08:50:19
On Wed, Feb 26, 2020 at 01:14:43PM -0800, Song Liu wrote:
On Wed, Feb 26, 2020 at 5:04 AM Jiri Olsa [off-list ref] wrote:
quoted
Adding name to 'struct bpf_ksym' object to carry the name
of the symbol for bpf_prog, bpf_trampoline, bpf_dispatcher.
The current benefit is that name is now generated only when
the symbol is added to the list, so we don't need to generate
it every time it's accessed.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
The patch looks good. But I wonder whether we want pay the cost of
extra 128 bytes per bpf program. Maybe make it a pointer and only
generate the string when it is first used?
I thought 128 would not be that bad, also the code is quite
simple because of that.. if that's really a concern I could
make the changes, but that would probably mean changing the
design
jirka
From: Song Liu <song@kernel.org> Date: 2020-02-27 19:00:11
On Thu, Feb 27, 2020 at 12:50 AM Jiri Olsa [off-list ref] wrote:
On Wed, Feb 26, 2020 at 01:14:43PM -0800, Song Liu wrote:
quoted
On Wed, Feb 26, 2020 at 5:04 AM Jiri Olsa [off-list ref] wrote:
quoted
Adding name to 'struct bpf_ksym' object to carry the name
of the symbol for bpf_prog, bpf_trampoline, bpf_dispatcher.
The current benefit is that name is now generated only when
the symbol is added to the list, so we don't need to generate
it every time it's accessed.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
The patch looks good. But I wonder whether we want pay the cost of
extra 128 bytes per bpf program. Maybe make it a pointer and only
generate the string when it is first used?
I thought 128 would not be that bad, also the code is quite
simple because of that.. if that's really a concern I could
make the changes, but that would probably mean changing the
design
I guess this is OK. We can further optimize it if needed.
Acked-by: Song Liu <redacted>
On Wed, Feb 26, 2020 at 02:03:37PM +0100, Jiri Olsa wrote:
quoted hunk
When bpf_prog is removed from kallsyms it's on the way
out to be removed, so we don't care about lnode state.
However the bpf_ksym_del will be used also by bpf_trampoline
and bpf_dispatcher objects, which stay allocated even when
they are not in kallsyms list, hence the lnode re-init.
The list_del_rcu commentary states that we need to call
synchronize_rcu, before we can change/re-init the list_head
pointers.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
kernel/bpf/core.c | 7 +++++++
1 file changed, 7 insertions(+)
I don't understand what this is for.
The comment made it even more confusing.
What kind of ksym reuse are you expecting?
Looking at trampoline and dispatcher patches I think cnt == 0
condition is unnecessary. Just add them to ksym at creation time
and remove from ksym at destroy. Both are executable code sections.
Though RIP should never point into them while there are no progs
I think it's better to keep them in ksym always.
Imagine sw race conditions in destruction. CPU bugs. What not.
In patch 3 the name
bpf_get_prog_addr_region(const struct bpf_prog *prog)
became wrong and 'const' pointer makes it even more misleading.
The function is not getting prog addr. It's setting ksym's addr.
I think it should be called:
bpf_ksym_set_addr(struct bpf_ksym *ksym);
__always_inline should be removed too.
Similar in patch 4:
static void bpf_get_prog_name(const struct bpf_prog *prog)
also is wrong for the same reasons.
It probably should be:
static void bpf_ksym_set_name(struct bpf_ksym *ksym);
I'm still not confortable with patch 15 sorting bit.
next = rb_next(&ksym->tnode.node[0]);
if (next)
is too tricky for me. I cannot wrap my head yet.
Since user space doesn't rely on sorted order could you drop it?
Do patches 16-18 strongly depend on patches 1-15 ?
We can take them via bpf-next tree. No problem. Just need Arnaldo's ack.
Overall looks great. All around important work.
Please address above and respin. I would like to land it soon.
From: Jiri Olsa <hidden> Date: 2020-02-28 12:17:24
On Thu, Feb 27, 2020 at 11:50:36AM -0800, Alexei Starovoitov wrote:
On Wed, Feb 26, 2020 at 02:03:37PM +0100, Jiri Olsa wrote:
quoted
When bpf_prog is removed from kallsyms it's on the way
out to be removed, so we don't care about lnode state.
However the bpf_ksym_del will be used also by bpf_trampoline
and bpf_dispatcher objects, which stay allocated even when
they are not in kallsyms list, hence the lnode re-init.
The list_del_rcu commentary states that we need to call
synchronize_rcu, before we can change/re-init the list_head
pointers.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
kernel/bpf/core.c | 7 +++++++
1 file changed, 7 insertions(+)
I don't understand what this is for.
The comment made it even more confusing.
What kind of ksym reuse are you expecting?
Looking at trampoline and dispatcher patches I think cnt == 0
condition is unnecessary. Just add them to ksym at creation time
and remove from ksym at destroy. Both are executable code sections.
Though RIP should never point into them while there are no progs
I think it's better to keep them in ksym always.
Imagine sw race conditions in destruction. CPU bugs. What not.
aah ok, that should also solve your first question,
because the code above won't be needed anymore
I wish I read this comment before I prepared elabored ascii/code
picture of why the code above is needed ;-))
In patch 3 the name
bpf_get_prog_addr_region(const struct bpf_prog *prog)
became wrong and 'const' pointer makes it even more misleading.
The function is not getting prog addr. It's setting ksym's addr.
I think it should be called:
bpf_ksym_set_addr(struct bpf_ksym *ksym);
__always_inline should be removed too.
ok, will change
Similar in patch 4:
static void bpf_get_prog_name(const struct bpf_prog *prog)
also is wrong for the same reasons.
It probably should be:
static void bpf_ksym_set_name(struct bpf_ksym *ksym);
ok
I'm still not confortable with patch 15 sorting bit.
next = rb_next(&ksym->tnode.node[0]);
if (next)
is too tricky for me. I cannot wrap my head yet.
Since user space doesn't rely on sorted order could you drop it?
yes, as I said I only added it because I liked how simple it
turned out to be
Do patches 16-18 strongly depend on patches 1-15 ?
We can take them via bpf-next tree. No problem. Just need Arnaldo's ack.
actualy there're some changes on the list from this week, that touch
the same code, so we might need to take them through Arnaldo's code
I'l double check
Overall looks great. All around important work.
Please address above and respin. I would like to land it soon.
From: Arnaldo Carvalho de Melo <hidden> Date: 2020-02-28 13:15:06
Em Wed, Feb 26, 2020 at 02:03:43PM +0100, Jiri Olsa escreveu:
Synthesize bpf images (trampolines/dispatchers) on start,
as ksymbol events from /proc/kallsyms. Having this perf
can recognize samples from those images and perf report
and top shows them correctly.
The rest of the ksymbol handling is already in place from
for the bpf programs monitoring, so only the initial state
was needed.
Acked-by: Arnaldo Carvalho de Melo <redacted>
But at some point we should try and consolidate all those
kallsym__parse() calls we have in tools/perf/ not to do it that many
times, see below _before_ this patch:
[root@five ~]# perf probe -x ~/bin/perf kallsyms__parse
Added new event:
probe_perf:kallsyms__parse (on kallsyms__parse in /home/acme/bin/perf)
You can now use it in all perf tools, such as:
perf record -e probe_perf:kallsyms__parse -aR sleep 1
[root@five ~]# perf trace -e probe_perf:kallsyms__parse/max-stack=8/ -- perf record sleep 1
0.000 perf/6444 probe_perf:kallsyms__parse(__probe_ip: 4904384)
kallsyms__parse (/home/acme/bin/perf)
machine__get_running_kernel_start (/home/acme/bin/perf)
machine__create_kernel_maps (/home/acme/bin/perf)
perf_session__new (/home/acme/bin/perf)
cmd_record (/home/acme/bin/perf)
run_builtin (/home/acme/bin/perf)
main (/home/acme/bin/perf)
__libc_start_main (/usr/lib64/libc-2.30.so)
0.124 perf/6444 probe_perf:kallsyms__parse(__probe_ip: 4904384)
kallsyms__parse (/home/acme/bin/perf)
machine__get_running_kernel_start (/home/acme/bin/perf)
machine__create_kernel_maps (/home/acme/bin/perf)
perf_session__new (/home/acme/bin/perf)
cmd_record (/home/acme/bin/perf)
run_builtin (/home/acme/bin/perf)
main (/home/acme/bin/perf)
__libc_start_main (/usr/lib64/libc-2.30.so)
15.489 perf/6444 probe_perf:kallsyms__parse(__probe_ip: 4904384)
kallsyms__parse (/home/acme/bin/perf)
machine__create_kernel_maps (/home/acme/bin/perf)
perf_session__new (/home/acme/bin/perf)
cmd_record (/home/acme/bin/perf)
run_builtin (/home/acme/bin/perf)
main (/home/acme/bin/perf)
__libc_start_main (/usr/lib64/libc-2.30.so)
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.019 MB perf.data (7 samples) ]
[root@five ~]#
- Arnaldo
@@ -290,11 +293,87 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session,returnerr?-1:0;}+structkallsyms_parse{+unionperf_event*event;+perf_event__handler_tprocess;+structmachine*machine;+structperf_tool*tool;+};++staticint+process_bpf_image(char*name,u64addr,structkallsyms_parse*data)+{+structmachine*machine=data->machine;+unionperf_event*event=data->event;+structperf_record_ksymbol*ksymbol;+u32size;++ksymbol=&event->ksymbol;++/*+*Thebpfimage(trampoline/dispatcher)sizeisalignedto+*page,whileitstartslittlebitafterthepageboundary.+*/+size=page_size-(addr-PERF_ALIGN(addr,page_size));++*ksymbol=(structperf_record_ksymbol){+.header={+.type=PERF_RECORD_KSYMBOL,+.size=offsetof(structperf_record_ksymbol,name),+},+.addr=addr,+.len=size,+.ksym_type=PERF_RECORD_KSYMBOL_TYPE_BPF,+.flags=0,+};++strncpy(ksymbol->name,name,KSYM_NAME_LEN);+ksymbol->header.size+=PERF_ALIGN(strlen(name)+1,sizeof(u64));+memset((void*)event+event->header.size,0,machine->id_hdr_size);+event->header.size+=machine->id_hdr_size;++returnperf_tool__process_synth_event(data->tool,event,machine,+data->process);+}++staticint+kallsyms_process_symbol(void*data,constchar*_name,+chartype__maybe_unused,u64start)+{+char*module,*name;+unsignedlongid;+interr=0;++module=strchr(_name,'\t');+if(!module)+return0;++/* We are going after [bpf] module ... */+if(strcmp(module+1,"[bpf]"))+return0;++name=memdup(_name,(module-_name)+1);+if(!name)+return-ENOMEM;++name[module-_name]=0;++/* .. and only for trampolines and dispatchers */+if((sscanf(name,"bpf_trampoline_%lu",&id)==1)||+(sscanf(name,"bpf_dispatcher_%lu",&id)==1))+err=process_bpf_image(name,start,data);++free(name);+returnerr;+}+intperf_event__synthesize_bpf_events(structperf_session*session,perf_event__handler_tprocess,structmachine*machine,structrecord_opts*opts){+constchar*kallsyms_filename="/proc/kallsyms";+structkallsyms_parsearg;unionperf_event*event;__u32id=0;interr;
@@ -303,6 +382,8 @@ int perf_event__synthesize_bpf_events(struct perf_session *session,event=malloc(sizeof(event->bpf)+KSYM_NAME_LEN+machine->id_hdr_size);if(!event)return-1;++/* Synthesize all the bpf programs in system. */while(true){err=bpf_prog_get_next_id(id,&id);if(err){
@@ -335,6 +416,23 @@ int perf_event__synthesize_bpf_events(struct perf_session *session,break;}}++/* Synthesize all the bpf images - trampolines/dispatchers. */+if(symbol_conf.kallsyms_name!=NULL)+kallsyms_filename=symbol_conf.kallsyms_name;++arg=(structkallsyms_parse){+.event=event,+.process=process,+.machine=machine,+.tool=session->tool,+};++if(kallsyms__parse(kallsyms_filename,&arg,kallsyms_process_symbol)){+pr_err("%s: failed to synthesize bpf images: %s\n",+__func__,strerror(errno));+}+free(event);returnerr;}
From: Arnaldo Carvalho de Melo <hidden> Date: 2020-02-28 13:15:36
Em Wed, Feb 26, 2020 at 02:03:44PM +0100, Jiri Olsa escreveu:
There's no special load action for ksymbol data on
map__load/dso__load action, where the kernel is getting
loaded. It only gets confused with kernel kallsyms/vmlinux
load for bpf object, which fails and could mess up with
the map.
Disabling any further load of the map for ksymbol related dso/map.
From: Arnaldo Carvalho de Melo <hidden> Date: 2020-02-28 13:16:20
Em Wed, Feb 26, 2020 at 02:03:45PM +0100, Jiri Olsa escreveu:
Adding the DSO_BINARY_TYPE__BPF_IMAGE dso binary type
to recognize bpf images that carry trampoline or dispatcher.
Upcoming patches will add support to read the image data,
store it within the BPF feature in perf.data and display
it for annotation purposes.
Currently we only display following message:
From: Arnaldo Carvalho de Melo <hidden> Date: 2020-02-28 13:17:06
Em Thu, Feb 27, 2020 at 11:50:36AM -0800, Alexei Starovoitov escreveu:
On Wed, Feb 26, 2020 at 02:03:37PM +0100, Jiri Olsa wrote:
quoted
When bpf_prog is removed from kallsyms it's on the way
out to be removed, so we don't care about lnode state.
However the bpf_ksym_del will be used also by bpf_trampoline
and bpf_dispatcher objects, which stay allocated even when
they are not in kallsyms list, hence the lnode re-init.
The list_del_rcu commentary states that we need to call
synchronize_rcu, before we can change/re-init the list_head
pointers.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
kernel/bpf/core.c | 7 +++++++
1 file changed, 7 insertions(+)
I don't understand what this is for.
The comment made it even more confusing.
What kind of ksym reuse are you expecting?
Looking at trampoline and dispatcher patches I think cnt == 0
condition is unnecessary. Just add them to ksym at creation time
and remove from ksym at destroy. Both are executable code sections.
Though RIP should never point into them while there are no progs
I think it's better to keep them in ksym always.
Imagine sw race conditions in destruction. CPU bugs. What not.
In patch 3 the name
bpf_get_prog_addr_region(const struct bpf_prog *prog)
became wrong and 'const' pointer makes it even more misleading.
The function is not getting prog addr. It's setting ksym's addr.
I think it should be called:
bpf_ksym_set_addr(struct bpf_ksym *ksym);
__always_inline should be removed too.
Similar in patch 4:
static void bpf_get_prog_name(const struct bpf_prog *prog)
also is wrong for the same reasons.
It probably should be:
static void bpf_ksym_set_name(struct bpf_ksym *ksym);
I'm still not confortable with patch 15 sorting bit.
next = rb_next(&ksym->tnode.node[0]);
if (next)
is too tricky for me. I cannot wrap my head yet.
Since user space doesn't rely on sorted order could you drop it?
Do patches 16-18 strongly depend on patches 1-15 ?
We can take them via bpf-next tree. No problem. Just need Arnaldo's ack.
No problems, sent the acks, we can sort out problems later, but from the
top of my mind I can't antecipate any,
- Arnaldo
Overall looks great. All around important work.
Please address above and respin. I would like to land it soon.
From: Arnaldo Carvalho de Melo <hidden> Date: 2020-02-28 13:18:36
Em Fri, Feb 28, 2020 at 01:17:08PM +0100, Jiri Olsa escreveu:
On Thu, Feb 27, 2020 at 11:50:36AM -0800, Alexei Starovoitov wrote:
quoted
On Wed, Feb 26, 2020 at 02:03:37PM +0100, Jiri Olsa wrote:
Do patches 16-18 strongly depend on patches 1-15 ?
We can take them via bpf-next tree. No problem. Just need Arnaldo's ack.
actualy there're some changes on the list from this week, that touch
the same code, so we might need to take them through Arnaldo's code
Ravi's patches, yeah, will push them via perf/urgent now, since those
are fixes, but I guess those won't clash...
I'l double check
Please
quoted
Overall looks great. All around important work.
Please address above and respin. I would like to land it soon.
From: Jiri Olsa <hidden> Date: 2020-03-01 18:31:51
On Thu, Feb 27, 2020 at 10:59:57AM -0800, Song Liu wrote:
On Thu, Feb 27, 2020 at 12:50 AM Jiri Olsa [off-list ref] wrote:
quoted
On Wed, Feb 26, 2020 at 01:14:43PM -0800, Song Liu wrote:
quoted
On Wed, Feb 26, 2020 at 5:04 AM Jiri Olsa [off-list ref] wrote:
quoted
Adding name to 'struct bpf_ksym' object to carry the name
of the symbol for bpf_prog, bpf_trampoline, bpf_dispatcher.
The current benefit is that name is now generated only when
the symbol is added to the list, so we don't need to generate
it every time it's accessed.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
The patch looks good. But I wonder whether we want pay the cost of
extra 128 bytes per bpf program. Maybe make it a pointer and only
generate the string when it is first used?
I thought 128 would not be that bad, also the code is quite
simple because of that.. if that's really a concern I could
make the changes, but that would probably mean changing the
design
I guess this is OK. We can further optimize it if needed.
Acked-by: Song Liu <redacted>
ok, thanks for the review, I still have to make some changes,
so I'll keep your acked-by on patches that won't be changed,
please scream otherwise ;-)
thanks,
jirka