From: Jiri Olsa <jolsa@redhat.com>
To: Jiri Olsa <jolsa@kernel.org>
Cc: "Alexei Starovoitov" <ast@kernel.org>,
"Daniel Borkmann" <daniel@iogearbox.net>,
"Andrii Nakryiko" <andriin@fb.com>,
netdev@vger.kernel.org, bpf@vger.kernel.org,
"Martin KaFai Lau" <kafai@fb.com>,
"Song Liu" <songliubraving@fb.com>, "Yonghong Song" <yhs@fb.com>,
"John Fastabend" <john.fastabend@gmail.com>,
"KP Singh" <kpsingh@chromium.org>, "Daniel Xu" <dxu@dxuuu.xyz>,
"Steven Rostedt" <rostedt@goodmis.org>,
"Jesper Brouer" <jbrouer@redhat.com>,
"Toke Høiland-Jørgensen" <toke@redhat.com>,
"Viktor Malik" <vmalik@redhat.com>
Subject: Re: [RFC bpf-next 07/16] kallsyms: Use rb tree for kallsyms name search
Date: Wed, 28 Oct 2020 19:25:34 +0100 [thread overview]
Message-ID: <20201028182534.GS2900849@krava> (raw)
In-Reply-To: <20201022082138.2322434-8-jolsa@kernel.org>
On Thu, Oct 22, 2020 at 10:21:29AM +0200, Jiri Olsa wrote:
> The kallsyms_expand_symbol function showed in several bpf related
> profiles, because it's doing linear search.
>
> Before:
>
> Performance counter stats for './src/bpftrace -ve kfunc:__x64_sys_s* \
> { printf("test\n"); } i:ms:10 { printf("exit\n"); exit();}' (5 runs):
>
> 2,535,458,767 cycles:k ( +- 0.55% )
> 940,046,382 cycles:u ( +- 0.27% )
>
> 33.60 +- 3.27 seconds time elapsed ( +- 9.73% )
>
> Loading all the vmlinux symbols in rbtree and and switch to rbtree
> search in kallsyms_lookup_name function to save few cycles and time.
>
> After:
>
> Performance counter stats for './src/bpftrace -ve kfunc:__x64_sys_s* \
> { printf("test\n"); } i:ms:10 { printf("exit\n"); exit();}' (5 runs):
>
> 2,199,433,771 cycles:k ( +- 0.55% )
> 936,105,469 cycles:u ( +- 0.37% )
>
> 26.48 +- 3.57 seconds time elapsed ( +- 13.49% )
>
> Each symbol takes 160 bytes, so for my .config I've got about 18 MBs
> used for 115285 symbols.
>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
FYI there's init_kprobes dependency on kallsyms_lookup_name in early
init call, so this won't work as it is :-\ will address this in v2
also I'll switch to sorted array and bsearch, because kallsyms is not
dynamically updated
jirka
> ---
> kernel/kallsyms.c | 95 ++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 86 insertions(+), 9 deletions(-)
>
> diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
> index 4fb15fa96734..107c8284170e 100644
> --- a/kernel/kallsyms.c
> +++ b/kernel/kallsyms.c
> @@ -50,6 +50,36 @@ extern const u16 kallsyms_token_index[] __weak;
>
> extern const unsigned int kallsyms_markers[] __weak;
>
> +static struct kmem_cache *symbol_cachep;
> +
> +struct symbol {
> + char name[KSYM_NAME_LEN];
> + unsigned long addr;
> + struct rb_node rb_node;
> +};
> +
> +static struct rb_root symbols_root = RB_ROOT;
> +
> +static struct symbol *find_symbol(const char *name)
> +{
> + struct symbol *sym;
> + struct rb_node *n;
> + int err;
> +
> + n = symbols_root.rb_node;
> + while (n) {
> + sym = rb_entry(n, struct symbol, rb_node);
> + err = strcmp(name, sym->name);
> + if (err < 0)
> + n = n->rb_left;
> + else if (err > 0)
> + n = n->rb_right;
> + else
> + return sym;
> + }
> + return NULL;
> +}
> +
> /*
> * Expand a compressed symbol data into the resulting uncompressed string,
> * if uncompressed string is too long (>= maxlen), it will be truncated,
> @@ -164,16 +194,12 @@ static unsigned long kallsyms_sym_address(int idx)
> /* Lookup the address for this symbol. Returns 0 if not found. */
> unsigned long kallsyms_lookup_name(const char *name)
> {
> - char namebuf[KSYM_NAME_LEN];
> - unsigned long i;
> - unsigned int off;
> + struct symbol *sym;
>
> - for (i = 0, off = 0; i < kallsyms_num_syms; i++) {
> - off = kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf));
> + sym = find_symbol(name);
> + if (sym)
> + return sym->addr;
>
> - if (strcmp(namebuf, name) == 0)
> - return kallsyms_sym_address(i);
> - }
> return module_kallsyms_lookup_name(name);
> }
>
> @@ -743,9 +769,60 @@ static const struct proc_ops kallsyms_proc_ops = {
> .proc_release = seq_release_private,
> };
>
> +static bool __init add_symbol(struct symbol *new)
> +{
> + struct rb_node *parent = NULL;
> + struct rb_node **p;
> + struct symbol *sym;
> + int err;
> +
> + p = &symbols_root.rb_node;
> +
> + while (*p != NULL) {
> + parent = *p;
> + sym = rb_entry(parent, struct symbol, rb_node);
> + err = strcmp(new->name, sym->name);
> + if (err < 0)
> + p = &(*p)->rb_left;
> + else if (err > 0)
> + p = &(*p)->rb_right;
> + else
> + return false;
> + }
> +
> + rb_link_node(&new->rb_node, parent, p);
> + rb_insert_color(&new->rb_node, &symbols_root);
> + return true;
> +}
> +
> +static int __init kallsyms_name_search_init(void)
> +{
> + bool sym_added = true;
> + struct symbol *sym;
> + unsigned int off;
> + unsigned long i;
> +
> + symbol_cachep = KMEM_CACHE(symbol, SLAB_PANIC|SLAB_ACCOUNT);
> +
> + for (i = 0, off = 0; i < kallsyms_num_syms; i++) {
> + if (sym_added) {
> + sym = kmem_cache_alloc(symbol_cachep, GFP_KERNEL);
> + if (!sym)
> + return -ENOMEM;
> + }
> + off = kallsyms_expand_symbol(off, sym->name, ARRAY_SIZE(sym->name));
> + sym->addr = kallsyms_sym_address(i);
> + sym_added = add_symbol(sym);
> + }
> +
> + if (!sym_added)
> + kmem_cache_free(symbol_cachep, sym);
> + return 0;
> +}
> +
> static int __init kallsyms_init(void)
> {
> proc_create("kallsyms", 0444, NULL, &kallsyms_proc_ops);
> - return 0;
> + return kallsyms_name_search_init();
> }
> device_initcall(kallsyms_init);
> --
> 2.26.2
>
next prev parent reply other threads:[~2020-10-28 22:27 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-22 8:21 [RFC bpf-next 00/16] bpf: Speed up trampoline attach Jiri Olsa
2020-10-22 8:21 ` [RFC bpf-next 01/16] ftrace: Add check_direct_entry function Jiri Olsa
2020-10-22 8:21 ` [RFC bpf-next 02/16] ftrace: Add adjust_direct_size function Jiri Olsa
2020-10-22 8:21 ` [RFC bpf-next 03/16] ftrace: Add get/put_direct_func function Jiri Olsa
2020-10-22 8:21 ` [RFC bpf-next 04/16] ftrace: Add ftrace_set_filter_ips function Jiri Olsa
2020-10-22 8:21 ` [RFC bpf-next 05/16] ftrace: Add register_ftrace_direct_ips function Jiri Olsa
2020-10-22 8:21 ` [RFC bpf-next 06/16] ftrace: Add unregister_ftrace_direct_ips function Jiri Olsa
2020-10-22 8:21 ` [RFC bpf-next 07/16] kallsyms: Use rb tree for kallsyms name search Jiri Olsa
2020-10-28 18:25 ` Jiri Olsa [this message]
2020-10-28 21:15 ` Alexei Starovoitov
2020-10-29 9:29 ` Jiri Olsa
2020-10-29 22:45 ` Andrii Nakryiko
2020-10-28 22:40 ` Andrii Nakryiko
2020-10-29 9:33 ` Jiri Olsa
2020-10-22 8:21 ` [RFC bpf-next 08/16] bpf: Use delayed link free in bpf_link_put Jiri Olsa
2020-10-23 19:46 ` Andrii Nakryiko
2020-10-25 19:02 ` Jiri Olsa
2020-10-22 8:21 ` [RFC bpf-next 09/16] bpf: Add BPF_TRAMPOLINE_BATCH_ATTACH support Jiri Olsa
2020-10-22 11:55 ` kernel test robot
2020-10-22 11:57 ` kernel test robot
2020-10-23 20:03 ` Andrii Nakryiko
2020-10-23 20:31 ` Steven Rostedt
2020-10-23 22:23 ` Andrii Nakryiko
2020-10-25 19:41 ` Jiri Olsa
2020-10-26 23:19 ` Andrii Nakryiko
2020-10-22 8:21 ` [RFC bpf-next 10/16] bpf: Add BPF_TRAMPOLINE_BATCH_DETACH support Jiri Olsa
2020-10-22 13:00 ` kernel test robot
2020-10-22 13:04 ` kernel test robot
2020-10-22 8:21 ` [RFC bpf-next 11/16] bpf: Sync uapi bpf.h to tools Jiri Olsa
2020-10-22 8:21 ` [RFC bpf-next 12/16] bpf: Move synchronize_rcu_mult for batch processing (NOT TO BE MERGED) Jiri Olsa
2020-10-22 8:21 ` [RFC bpf-next 13/16] libbpf: Add trampoline batch attach support Jiri Olsa
2020-10-23 20:09 ` Andrii Nakryiko
2020-10-25 19:11 ` Jiri Olsa
2020-10-26 23:15 ` Andrii Nakryiko
2020-10-27 19:03 ` Jiri Olsa
2020-10-22 8:21 ` [RFC bpf-next 14/16] libbpf: Add trampoline batch detach support Jiri Olsa
2020-10-22 8:21 ` [RFC bpf-next 15/16] selftests/bpf: Add trampoline batch test Jiri Olsa
2020-10-22 8:21 ` [RFC bpf-next 16/16] selftests/bpf: Add attach batch test (NOT TO BE MERGED) Jiri Olsa
2020-10-22 13:35 ` [RFC bpf-next 00/16] bpf: Speed up trampoline attach Steven Rostedt
2020-10-22 14:11 ` Jiri Olsa
2020-10-22 14:42 ` Steven Rostedt
2020-10-22 16:21 ` Steven Rostedt
2020-10-22 20:52 ` Steven Rostedt
2020-10-23 6:09 ` Jiri Olsa
2020-10-23 13:50 ` Steven Rostedt
2020-10-25 19:01 ` Jiri Olsa
2020-10-27 4:30 ` Alexei Starovoitov
2020-10-27 13:14 ` Steven Rostedt
2020-10-27 14:28 ` Jiri Olsa
2020-10-28 21:13 ` Alexei Starovoitov
2020-10-29 11:09 ` Jiri Olsa
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201028182534.GS2900849@krava \
--to=jolsa@redhat.com \
--cc=andriin@fb.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=dxu@dxuuu.xyz \
--cc=jbrouer@redhat.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=kafai@fb.com \
--cc=kpsingh@chromium.org \
--cc=netdev@vger.kernel.org \
--cc=rostedt@goodmis.org \
--cc=songliubraving@fb.com \
--cc=toke@redhat.com \
--cc=vmalik@redhat.com \
--cc=yhs@fb.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.