* [RFC PATCH bpf-next v3 1/3] libbpf: Optimize kprobe.session attachment for exact function names
2026-02-27 20:40 [RFC PATCH bpf-next v3 0/3] Optimize kprobe.session attachment for exact function names Andrey Grodzovsky
@ 2026-02-27 20:40 ` Andrey Grodzovsky
2026-02-27 21:17 ` bot+bpf-ci
2026-02-27 20:40 ` [RFC PATCH bpf-next v3 2/3] ftrace: Use kallsyms binary search for single-symbol lookup Andrey Grodzovsky
` (3 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Andrey Grodzovsky @ 2026-02-27 20:40 UTC (permalink / raw)
To: bpf, linux-open-source
Cc: ast, daniel, andrii, jolsa, rostedt, linux-trace-kernel
Detect exact function names (no wildcards) in
bpf_program__attach_kprobe_multi_opts() and bypass kallsyms parsing,
passing the symbol directly to the kernel via syms[] array. This
benefits all callers, not just kprobe.session.
When the pattern contains no '*' or '?' characters, set syms to point
directly at the pattern string and cnt to 1, skipping the expensive
/proc/kallsyms or available_filter_functions parsing (~150ms per
function).
Error code normalization: the fast path returns ESRCH from kernel's
ftrace_lookup_symbols(), while the slow path returns ENOENT from
userspace kallsyms parsing. Convert ESRCH to ENOENT in the
bpf_link_create error path to maintain API consistency - both paths
now return identical error codes for "symbol not found".
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
---
tools/lib/bpf/libbpf.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 0be7017800fe..80278385bc9c 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -12041,7 +12041,15 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
if (addrs && syms)
return libbpf_err_ptr(-EINVAL);
- if (pattern) {
+ /*
+ * Exact function name (no wildcards): bypass kallsyms parsing
+ * and pass the symbol directly to the kernel via syms[] array.
+ * The kernel's ftrace_lookup_symbols() resolves it efficiently.
+ */
+ if (pattern && !strpbrk(pattern, "*?")) {
+ syms = &pattern;
+ cnt = 1;
+ } else if (pattern) {
if (has_available_filter_functions_addrs())
err = libbpf_available_kprobes_parse(&res);
else
@@ -12084,6 +12092,14 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
link_fd = bpf_link_create(prog_fd, 0, attach_type, &lopts);
if (link_fd < 0) {
err = -errno;
+ /*
+ * Normalize error code: when exact name bypasses kallsyms
+ * parsing, kernel returns ESRCH from ftrace_lookup_symbols().
+ * Convert to ENOENT for API consistency with the pattern
+ * matching path which returns ENOENT from userspace.
+ */
+ if (err == -ESRCH)
+ err = -ENOENT;
pr_warn("prog '%s': failed to attach: %s\n",
prog->name, errstr(err));
goto error;
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [RFC PATCH bpf-next v3 1/3] libbpf: Optimize kprobe.session attachment for exact function names
2026-02-27 20:40 ` [RFC PATCH bpf-next v3 1/3] libbpf: " Andrey Grodzovsky
@ 2026-02-27 21:17 ` bot+bpf-ci
2026-02-27 22:28 ` [External] " Andrey Grodzovsky
0 siblings, 1 reply; 14+ messages in thread
From: bot+bpf-ci @ 2026-02-27 21:17 UTC (permalink / raw)
To: andrey.grodzovsky, bpf, linux-open-source
Cc: ast, daniel, andrii, jolsa, rostedt, linux-trace-kernel, ast,
andrii, daniel, martin.lau, eddyz87, yonghong.song, clm,
ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 2490 bytes --]
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -12041,7 +12041,15 @@ struct kprobe_multi_resolve res = {
> if (addrs && syms)
> return libbpf_err_ptr(-EINVAL);
>
> - if (pattern) {
> + /*
> + * Exact function name (no wildcards): bypass kallsyms parsing
> + * and pass the symbol directly to the kernel via syms[] array.
> + * The kernel's ftrace_lookup_symbols() resolves it efficiently.
> + */
> + if (pattern && !strpbrk(pattern, "*?")) {
> + syms = &pattern;
> + cnt = 1;
> + } else if (pattern) {
When the fast path is taken here, unique_match is never checked.
The unique_match validation is inside the "else if (pattern)"
branch:
if (unique_match && res.cnt != 1) {
pr_warn("prog '%s': failed to find a unique match ...");
err = -EINVAL;
goto error;
}
Before this change, a caller passing an exact function name with
unique_match = true would go through kallsyms parsing, which could
find multiple addresses for same-named static functions across
different translation units, and the unique_match check would
correctly return an error.
With the fast path, the name goes directly to the kernel's
ftrace_lookup_symbols(), which resolves only the first match via
kallsyms_callback() skipping duplicates:
if (args->addrs[idx])
return 0;
Should the fast path condition also check unique_match, for
example:
if (pattern && !strpbrk(pattern, "*?") && !unique_match) {
This would preserve the optimization for the common case while
falling back to the slow path when unique_match is explicitly
requested.
> [ ... ]
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/22503275616
AI-authorship-score: medium
AI-authorship-explanation: Comments are unusually verbose for a simple optimization, and the commit message is well-structured with distinct sections, but the iterative v1-v3 refinement following reviewer feedback is typical of human development.
issues-found: 1
issue-severity-score: low
issue-severity-explanation: The fast path bypasses the unique_match check, which could silently attach to the wrong function among same-named statics, but requires the uncommon combination of unique_match=true with an exact name matching multiple kernel functions.
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [External] Re: [RFC PATCH bpf-next v3 1/3] libbpf: Optimize kprobe.session attachment for exact function names
2026-02-27 21:17 ` bot+bpf-ci
@ 2026-02-27 22:28 ` Andrey Grodzovsky
2026-03-02 10:58 ` Jiri Olsa
0 siblings, 1 reply; 14+ messages in thread
From: Andrey Grodzovsky @ 2026-02-27 22:28 UTC (permalink / raw)
To: bot+bpf-ci, yonghong.song
Cc: bpf, linux-open-source, ast, daniel, andrii, jolsa, rostedt,
linux-trace-kernel, martin.lau, eddyz87, clm, ihor.solodrai
On Fri, Feb 27, 2026 at 4:18 PM <bot+bpf-ci@kernel.org> wrote:
>
> > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> > --- a/tools/lib/bpf/libbpf.c
> > +++ b/tools/lib/bpf/libbpf.c
> > @@ -12041,7 +12041,15 @@ struct kprobe_multi_resolve res = {
> > if (addrs && syms)
> > return libbpf_err_ptr(-EINVAL);
> >
> > - if (pattern) {
> > + /*
> > + * Exact function name (no wildcards): bypass kallsyms parsing
> > + * and pass the symbol directly to the kernel via syms[] array.
> > + * The kernel's ftrace_lookup_symbols() resolves it efficiently.
> > + */
> > + if (pattern && !strpbrk(pattern, "*?")) {
> > + syms = &pattern;
> > + cnt = 1;
> > + } else if (pattern) {
>
> When the fast path is taken here, unique_match is never checked.
> The unique_match validation is inside the "else if (pattern)"
> branch:
>
> if (unique_match && res.cnt != 1) {
> pr_warn("prog '%s': failed to find a unique match ...");
> err = -EINVAL;
> goto error;
> }
>
> Before this change, a caller passing an exact function name with
> unique_match = true would go through kallsyms parsing, which could
> find multiple addresses for same-named static functions across
> different translation units, and the unique_match check would
> correctly return an error.
>
> With the fast path, the name goes directly to the kernel's
> ftrace_lookup_symbols(), which resolves only the first match via
> kallsyms_callback() skipping duplicates:
>
> if (args->addrs[idx])
> return 0;
>
> Should the fast path condition also check unique_match, for
> example:
>
> if (pattern && !strpbrk(pattern, "*?") && !unique_match) {
>
> This would preserve the optimization for the common case while
> falling back to the slow path when unique_match is explicitly
> requested.
>
I am not sure this makes sense, according to the original patchset [1]
this flag was specifically tailored for patterns with wildcards where
this indeed
makes sense. in our case, cnt == 1 from the get go since no wildcards so this
check can't ever fail.
Andrii, Yonghong - any suggestions ?
[1] - https://lore.kernel.org/bpf/20241218225246.3170300-1-yonghong.song@linux.dev/
Andrey
> > [ ... ]
>
>
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://urldefense.com/v3/__https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md__;!!BmdzS3_lV9HdKG8!z-aIXCz8YRZcraMmGI2bmb4YrDgW0brRTcX_BaJCWYwj7xfmkZL6qka6aqqIwzDPUjR1TxUU-Mc50s9AAYQf-vQMuPuGlVKW$
>
> CI run summary: https://urldefense.com/v3/__https://github.com/kernel-patches/bpf/actions/runs/22503275616__;!!BmdzS3_lV9HdKG8!z-aIXCz8YRZcraMmGI2bmb4YrDgW0brRTcX_BaJCWYwj7xfmkZL6qka6aqqIwzDPUjR1TxUU-Mc50s9AAYQf-vQMuGeekJPd$
>
> AI-authorship-score: medium
> AI-authorship-explanation: Comments are unusually verbose for a simple optimization, and the commit message is well-structured with distinct sections, but the iterative v1-v3 refinement following reviewer feedback is typical of human development.
> issues-found: 1
> issue-severity-score: low
> issue-severity-explanation: The fast path bypasses the unique_match check, which could silently attach to the wrong function among same-named statics, but requires the uncommon combination of unique_match=true with an exact name matching multiple kernel functions.
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [External] Re: [RFC PATCH bpf-next v3 1/3] libbpf: Optimize kprobe.session attachment for exact function names
2026-02-27 22:28 ` [External] " Andrey Grodzovsky
@ 2026-03-02 10:58 ` Jiri Olsa
2026-03-02 17:37 ` Andrey Grodzovsky
0 siblings, 1 reply; 14+ messages in thread
From: Jiri Olsa @ 2026-03-02 10:58 UTC (permalink / raw)
To: Andrey Grodzovsky
Cc: bot+bpf-ci, yonghong.song, bpf, linux-open-source, ast, daniel,
andrii, rostedt, linux-trace-kernel, martin.lau, eddyz87, clm,
ihor.solodrai
On Fri, Feb 27, 2026 at 05:28:05PM -0500, Andrey Grodzovsky wrote:
> On Fri, Feb 27, 2026 at 4:18 PM <bot+bpf-ci@kernel.org> wrote:
> >
> > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> > > --- a/tools/lib/bpf/libbpf.c
> > > +++ b/tools/lib/bpf/libbpf.c
> > > @@ -12041,7 +12041,15 @@ struct kprobe_multi_resolve res = {
> > > if (addrs && syms)
> > > return libbpf_err_ptr(-EINVAL);
> > >
> > > - if (pattern) {
> > > + /*
> > > + * Exact function name (no wildcards): bypass kallsyms parsing
> > > + * and pass the symbol directly to the kernel via syms[] array.
> > > + * The kernel's ftrace_lookup_symbols() resolves it efficiently.
> > > + */
> > > + if (pattern && !strpbrk(pattern, "*?")) {
> > > + syms = &pattern;
> > > + cnt = 1;
> > > + } else if (pattern) {
> >
> > When the fast path is taken here, unique_match is never checked.
> > The unique_match validation is inside the "else if (pattern)"
> > branch:
> >
> > if (unique_match && res.cnt != 1) {
> > pr_warn("prog '%s': failed to find a unique match ...");
> > err = -EINVAL;
> > goto error;
> > }
> >
> > Before this change, a caller passing an exact function name with
> > unique_match = true would go through kallsyms parsing, which could
> > find multiple addresses for same-named static functions across
> > different translation units, and the unique_match check would
> > correctly return an error.
> >
> > With the fast path, the name goes directly to the kernel's
> > ftrace_lookup_symbols(), which resolves only the first match via
> > kallsyms_callback() skipping duplicates:
> >
> > if (args->addrs[idx])
> > return 0;
> >
> > Should the fast path condition also check unique_match, for
> > example:
> >
> > if (pattern && !strpbrk(pattern, "*?") && !unique_match) {
> >
> > This would preserve the optimization for the common case while
> > falling back to the slow path when unique_match is explicitly
> > requested.
> >
>
> I am not sure this makes sense, according to the original patchset [1]
> this flag was specifically tailored for patterns with wildcards where
> this indeed
> makes sense. in our case, cnt == 1 from the get go since no wildcards so this
> check can't ever fail.
I think the problem is that it could now pass for cases where
function name has multiple instances in kallsyms .. while before
it would be caught in libbpf_available_kallsyms_parse and fail
jirka
>
> Andrii, Yonghong - any suggestions ?
>
> [1] - https://lore.kernel.org/bpf/20241218225246.3170300-1-yonghong.song@linux.dev/
>
> Andrey
>
>
> > > [ ... ]
> >
> >
> > ---
> > AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> > See: https://urldefense.com/v3/__https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md__;!!BmdzS3_lV9HdKG8!z-aIXCz8YRZcraMmGI2bmb4YrDgW0brRTcX_BaJCWYwj7xfmkZL6qka6aqqIwzDPUjR1TxUU-Mc50s9AAYQf-vQMuPuGlVKW$
> >
> > CI run summary: https://urldefense.com/v3/__https://github.com/kernel-patches/bpf/actions/runs/22503275616__;!!BmdzS3_lV9HdKG8!z-aIXCz8YRZcraMmGI2bmb4YrDgW0brRTcX_BaJCWYwj7xfmkZL6qka6aqqIwzDPUjR1TxUU-Mc50s9AAYQf-vQMuGeekJPd$
> >
> > AI-authorship-score: medium
> > AI-authorship-explanation: Comments are unusually verbose for a simple optimization, and the commit message is well-structured with distinct sections, but the iterative v1-v3 refinement following reviewer feedback is typical of human development.
> > issues-found: 1
> > issue-severity-score: low
> > issue-severity-explanation: The fast path bypasses the unique_match check, which could silently attach to the wrong function among same-named statics, but requires the uncommon combination of unique_match=true with an exact name matching multiple kernel functions.
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [External] Re: [RFC PATCH bpf-next v3 1/3] libbpf: Optimize kprobe.session attachment for exact function names
2026-03-02 10:58 ` Jiri Olsa
@ 2026-03-02 17:37 ` Andrey Grodzovsky
0 siblings, 0 replies; 14+ messages in thread
From: Andrey Grodzovsky @ 2026-03-02 17:37 UTC (permalink / raw)
To: Jiri Olsa
Cc: bot+bpf-ci, yonghong.song, bpf, linux-open-source, ast, daniel,
andrii, rostedt, linux-trace-kernel, martin.lau, eddyz87, clm,
ihor.solodrai
On Mon, Mar 2, 2026 at 5:58 AM Jiri Olsa <olsajiri@gmail.com> wrote:
>
> On Fri, Feb 27, 2026 at 05:28:05PM -0500, Andrey Grodzovsky wrote:
> > On Fri, Feb 27, 2026 at 4:18 PM <bot+bpf-ci@kernel.org> wrote:
> > >
> > > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> > > > --- a/tools/lib/bpf/libbpf.c
> > > > +++ b/tools/lib/bpf/libbpf.c
> > > > @@ -12041,7 +12041,15 @@ struct kprobe_multi_resolve res = {
> > > > if (addrs && syms)
> > > > return libbpf_err_ptr(-EINVAL);
> > > >
> > > > - if (pattern) {
> > > > + /*
> > > > + * Exact function name (no wildcards): bypass kallsyms parsing
> > > > + * and pass the symbol directly to the kernel via syms[] array.
> > > > + * The kernel's ftrace_lookup_symbols() resolves it efficiently.
> > > > + */
> > > > + if (pattern && !strpbrk(pattern, "*?")) {
> > > > + syms = &pattern;
> > > > + cnt = 1;
> > > > + } else if (pattern) {
> > >
> > > When the fast path is taken here, unique_match is never checked.
> > > The unique_match validation is inside the "else if (pattern)"
> > > branch:
> > >
> > > if (unique_match && res.cnt != 1) {
> > > pr_warn("prog '%s': failed to find a unique match ...");
> > > err = -EINVAL;
> > > goto error;
> > > }
> > >
> > > Before this change, a caller passing an exact function name with
> > > unique_match = true would go through kallsyms parsing, which could
> > > find multiple addresses for same-named static functions across
> > > different translation units, and the unique_match check would
> > > correctly return an error.
> > >
> > > With the fast path, the name goes directly to the kernel's
> > > ftrace_lookup_symbols(), which resolves only the first match via
> > > kallsyms_callback() skipping duplicates:
> > >
> > > if (args->addrs[idx])
> > > return 0;
> > >
> > > Should the fast path condition also check unique_match, for
> > > example:
> > >
> > > if (pattern && !strpbrk(pattern, "*?") && !unique_match) {
> > >
> > > This would preserve the optimization for the common case while
> > > falling back to the slow path when unique_match is explicitly
> > > requested.
> > >
> >
> > I am not sure this makes sense, according to the original patchset [1]
> > this flag was specifically tailored for patterns with wildcards where
> > this indeed
> > makes sense. in our case, cnt == 1 from the get go since no wildcards so this
> > check can't ever fail.
>
> I think the problem is that it could now pass for cases where
> function name has multiple instances in kallsyms .. while before
> it would be caught in libbpf_available_kallsyms_parse and fail
>
> jirka
Got you, you (and CI BOT originally) proposed with the unique_match guard:
fall back to slow path, preserving old behavior for this case.
Wiil do.
Andrey
>
>
> >
> > Andrii, Yonghong - any suggestions ?
> >
> > [1] - https://urldefense.com/v3/__https://lore.kernel.org/bpf/20241218225246.3170300-1-yonghong.song@linux.dev/__;!!BmdzS3_lV9HdKG8!xk626jLDdORTgQmachiRbRK_5oayjcFYNRm-SQS9q7EujjYI3PbN1x1jUehjPM_wsz6h8r0p9z39vc_VotgANU2nr_H3$
> >
> > Andrey
> >
> >
> > > > [ ... ]
> > >
> > >
> > > ---
> > > AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> > > See: https://urldefense.com/v3/__https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md__;!!BmdzS3_lV9HdKG8!z-aIXCz8YRZcraMmGI2bmb4YrDgW0brRTcX_BaJCWYwj7xfmkZL6qka6aqqIwzDPUjR1TxUU-Mc50s9AAYQf-vQMuPuGlVKW$
> > >
> > > CI run summary: https://urldefense.com/v3/__https://github.com/kernel-patches/bpf/actions/runs/22503275616__;!!BmdzS3_lV9HdKG8!z-aIXCz8YRZcraMmGI2bmb4YrDgW0brRTcX_BaJCWYwj7xfmkZL6qka6aqqIwzDPUjR1TxUU-Mc50s9AAYQf-vQMuGeekJPd$
> > >
> > > AI-authorship-score: medium
> > > AI-authorship-explanation: Comments are unusually verbose for a simple optimization, and the commit message is well-structured with distinct sections, but the iterative v1-v3 refinement following reviewer feedback is typical of human development.
> > > issues-found: 1
> > > issue-severity-score: low
> > > issue-severity-explanation: The fast path bypasses the unique_match check, which could silently attach to the wrong function among same-named statics, but requires the uncommon combination of unique_match=true with an exact name matching multiple kernel functions.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [RFC PATCH bpf-next v3 2/3] ftrace: Use kallsyms binary search for single-symbol lookup
2026-02-27 20:40 [RFC PATCH bpf-next v3 0/3] Optimize kprobe.session attachment for exact function names Andrey Grodzovsky
2026-02-27 20:40 ` [RFC PATCH bpf-next v3 1/3] libbpf: " Andrey Grodzovsky
@ 2026-02-27 20:40 ` Andrey Grodzovsky
2026-02-27 20:40 ` [RFC PATCH bpf-next v3 3/3] selftests/bpf: add tests for kprobe.session optimization Andrey Grodzovsky
` (2 subsequent siblings)
4 siblings, 0 replies; 14+ messages in thread
From: Andrey Grodzovsky @ 2026-02-27 20:40 UTC (permalink / raw)
To: bpf, linux-open-source
Cc: ast, daniel, andrii, jolsa, rostedt, linux-trace-kernel
When ftrace_lookup_symbols() is called with a single symbol (cnt == 1),
use kallsyms_lookup_name() for O(log N) binary search instead of the
full linear scan via kallsyms_on_each_symbol().
ftrace_lookup_symbols() was designed for batch resolution of many
symbols in a single pass. For large cnt this is efficient: a single
O(N) walk over all symbols with O(log cnt) binary search into the
sorted input array. But for cnt == 1 it still decompresses all ~200K
kernel symbols only to match one.
kallsyms_lookup_name() uses the sorted kallsyms index and needs only
~17 decompressions for a single lookup.
This is the common path for kprobe.session with exact function names,
where libbpf sends one symbol per BPF_LINK_CREATE syscall.
If binary lookup fails (duplicate symbol names where the first match
is not ftrace-instrumented), the function falls through to the existing
linear scan path.
Before (cnt=1, 50 kprobe.session programs):
Attach: 858 ms (kallsyms_expand_symbol 25% of CPU)
After:
Attach: 52 ms (16x faster)
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
---
kernel/trace/ftrace.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 827fb9a0bf0d..13906af8098a 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -9263,6 +9263,15 @@ static int kallsyms_callback(void *data, const char *name, unsigned long addr)
* @addrs array, which needs to be big enough to store at least @cnt
* addresses.
*
+ * For a single symbol (cnt == 1), uses kallsyms_lookup_name() which
+ * performs an O(log N) binary search via the sorted kallsyms index.
+ * This avoids the full O(N) linear scan over all kernel symbols that
+ * the multi-symbol path requires.
+ *
+ * For multiple symbols, uses a single-pass linear scan via
+ * kallsyms_on_each_symbol() with binary search into the sorted input
+ * array.
+ *
* Returns: 0 if all provided symbols are found, -ESRCH otherwise.
*/
int ftrace_lookup_symbols(const char **sorted_syms, size_t cnt, unsigned long *addrs)
@@ -9270,6 +9279,19 @@ int ftrace_lookup_symbols(const char **sorted_syms, size_t cnt, unsigned long *a
struct kallsyms_data args;
int found_all;
+ /* Fast path: single symbol uses O(log N) binary search */
+ if (cnt == 1) {
+ addrs[0] = kallsyms_lookup_name(sorted_syms[0]);
+ if (addrs[0] && ftrace_location(addrs[0]))
+ return 0;
+ /*
+ * Binary lookup can fail for duplicate symbol names
+ * where the first match is not ftrace-instrumented.
+ * Retry with linear scan.
+ */
+ }
+
+ /* Batch path: single-pass O(N) linear scan */
memset(addrs, 0, sizeof(*addrs) * cnt);
args.addrs = addrs;
args.syms = sorted_syms;
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* [RFC PATCH bpf-next v3 3/3] selftests/bpf: add tests for kprobe.session optimization
2026-02-27 20:40 [RFC PATCH bpf-next v3 0/3] Optimize kprobe.session attachment for exact function names Andrey Grodzovsky
2026-02-27 20:40 ` [RFC PATCH bpf-next v3 1/3] libbpf: " Andrey Grodzovsky
2026-02-27 20:40 ` [RFC PATCH bpf-next v3 2/3] ftrace: Use kallsyms binary search for single-symbol lookup Andrey Grodzovsky
@ 2026-02-27 20:40 ` Andrey Grodzovsky
2026-02-27 20:43 ` [RFC PATCH bpf-next v3 0/3] Optimize kprobe.session attachment for exact function names Alexei Starovoitov
2026-03-02 12:47 ` Jakub Sitnicki
4 siblings, 0 replies; 14+ messages in thread
From: Andrey Grodzovsky @ 2026-02-27 20:40 UTC (permalink / raw)
To: bpf, linux-open-source
Cc: ast, daniel, andrii, jolsa, rostedt, linux-trace-kernel
Extend existing kprobe_multi_test subtests to validate the
kprobe.session exact function name optimization:
In kprobe_multi_session.c, add test_kprobe_syms which attaches a
kprobe.session program to an exact function name (bpf_fentry_test1)
exercising the fast syms[] path that bypasses kallsyms parsing. It
calls session_check() so bpf_fentry_test1 is hit by both the wildcard
and exact probes, and test_session_skel_api validates
kprobe_session_result[0] == 4 (entry + return from each probe).
In test_attach_api_fails, add fail_7 and fail_8 verifying error code
consistency between the wildcard pattern path (slow, parses kallsyms)
and the exact function name path (fast, uses syms[] array). Both
paths must return -ENOENT for non-existent functions.
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
---
.../bpf/prog_tests/kprobe_multi_test.c | 33 +++++++++++++++++--
.../bpf/progs/kprobe_multi_session.c | 10 ++++++
2 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
index 9caef222e528..ea605245ba14 100644
--- a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
+++ b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
@@ -327,6 +327,30 @@ static void test_attach_api_fails(void)
if (!ASSERT_EQ(saved_error, -E2BIG, "fail_6_error"))
goto cleanup;
+ /* fail_7 - non-existent wildcard pattern (slow path) */
+ LIBBPF_OPTS_RESET(opts);
+
+ link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
+ "__nonexistent_func_xyz_*",
+ &opts);
+ saved_error = -errno;
+ if (!ASSERT_ERR_PTR(link, "fail_7"))
+ goto cleanup;
+
+ if (!ASSERT_EQ(saved_error, -ENOENT, "fail_7_error"))
+ goto cleanup;
+
+ /* fail_8 - non-existent exact name (fast path), same error as wildcard */
+ link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
+ "__nonexistent_func_xyz_123",
+ &opts);
+ saved_error = -errno;
+ if (!ASSERT_ERR_PTR(link, "fail_8"))
+ goto cleanup;
+
+ if (!ASSERT_EQ(saved_error, -ENOENT, "fail_8_error"))
+ goto cleanup;
+
cleanup:
bpf_link__destroy(link);
kprobe_multi__destroy(skel);
@@ -355,8 +379,13 @@ static void test_session_skel_api(void)
ASSERT_OK(err, "test_run");
ASSERT_EQ(topts.retval, 0, "test_run");
- /* bpf_fentry_test1-4 trigger return probe, result is 2 */
- for (i = 0; i < 4; i++)
+ /*
+ * bpf_fentry_test1 is hit by both the wildcard probe and the exact
+ * name probe (test_kprobe_syms), so entry + return fires twice: 4.
+ * bpf_fentry_test2-4 are hit only by the wildcard probe: 2.
+ */
+ ASSERT_EQ(skel->bss->kprobe_session_result[0], 4, "kprobe_session_result");
+ for (i = 1; i < 4; i++)
ASSERT_EQ(skel->bss->kprobe_session_result[i], 2, "kprobe_session_result");
/* bpf_fentry_test5-8 trigger only entry probe, result is 1 */
diff --git a/tools/testing/selftests/bpf/progs/kprobe_multi_session.c b/tools/testing/selftests/bpf/progs/kprobe_multi_session.c
index bd8b7fb7061e..d52a65b40bbf 100644
--- a/tools/testing/selftests/bpf/progs/kprobe_multi_session.c
+++ b/tools/testing/selftests/bpf/progs/kprobe_multi_session.c
@@ -76,3 +76,13 @@ int test_kprobe(struct pt_regs *ctx)
{
return session_check(ctx);
}
+
+/*
+ * Exact function name (no wildcards) - exercises the fast syms[] path
+ * in bpf_program__attach_kprobe_multi_opts() which bypasses kallsyms parsing.
+ */
+SEC("kprobe.session/bpf_fentry_test1")
+int test_kprobe_syms(struct pt_regs *ctx)
+{
+ return session_check(ctx);
+}
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [RFC PATCH bpf-next v3 0/3] Optimize kprobe.session attachment for exact function names
2026-02-27 20:40 [RFC PATCH bpf-next v3 0/3] Optimize kprobe.session attachment for exact function names Andrey Grodzovsky
` (2 preceding siblings ...)
2026-02-27 20:40 ` [RFC PATCH bpf-next v3 3/3] selftests/bpf: add tests for kprobe.session optimization Andrey Grodzovsky
@ 2026-02-27 20:43 ` Alexei Starovoitov
2026-02-27 21:15 ` [External] " Andrey Grodzovsky
2026-03-02 12:47 ` Jakub Sitnicki
4 siblings, 1 reply; 14+ messages in thread
From: Alexei Starovoitov @ 2026-02-27 20:43 UTC (permalink / raw)
To: Andrey Grodzovsky
Cc: bpf, DL Linux Open Source Team, Alexei Starovoitov,
Daniel Borkmann, Andrii Nakryiko, Jiri Olsa, Steven Rostedt,
linux-trace-kernel
On Fri, Feb 27, 2026 at 12:41 PM Andrey Grodzovsky
<andrey.grodzovsky@crowdstrike.com> wrote:
>
>
> Changes since v2 [2]:
> - Use if/else-if instead of goto (Jiri Olsa)
> - Use syms = &pattern directly (Jiri Olsa)
> - Drop unneeded pattern = NULL (Jiri Olsa)
> - Revert cosmetic rename in attach_kprobe_session (Jiri Olsa)
> - Remove "module symbols" from ftrace comment (CI bot)
RFC series are ignored by CI.
If you want things to land, drop RFC.
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [External] Re: [RFC PATCH bpf-next v3 0/3] Optimize kprobe.session attachment for exact function names
2026-02-27 20:43 ` [RFC PATCH bpf-next v3 0/3] Optimize kprobe.session attachment for exact function names Alexei Starovoitov
@ 2026-02-27 21:15 ` Andrey Grodzovsky
2026-03-02 19:25 ` Jakub Sitnicki
0 siblings, 1 reply; 14+ messages in thread
From: Andrey Grodzovsky @ 2026-02-27 21:15 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: bpf, DL Linux Open Source Team, Alexei Starovoitov,
Daniel Borkmann, Andrii Nakryiko, Jiri Olsa, Steven Rostedt,
linux-trace-kernel
Hey Alexei, just to be clear, do you mean drop the entire RFC letter or,
Drop the RFC prefix from the letter so the CI pipeline can be properly
triggered ?
Thanks,
Andrey
On Fri, Feb 27, 2026 at 3:43 PM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Fri, Feb 27, 2026 at 12:41 PM Andrey Grodzovsky
> <andrey.grodzovsky@crowdstrike.com> wrote:
> >
> >
> > Changes since v2 [2]:
> > - Use if/else-if instead of goto (Jiri Olsa)
> > - Use syms = &pattern directly (Jiri Olsa)
> > - Drop unneeded pattern = NULL (Jiri Olsa)
> > - Revert cosmetic rename in attach_kprobe_session (Jiri Olsa)
> > - Remove "module symbols" from ftrace comment (CI bot)
>
> RFC series are ignored by CI.
> If you want things to land, drop RFC.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [External] Re: [RFC PATCH bpf-next v3 0/3] Optimize kprobe.session attachment for exact function names
2026-02-27 21:15 ` [External] " Andrey Grodzovsky
@ 2026-03-02 19:25 ` Jakub Sitnicki
2026-03-02 19:47 ` Andrey Grodzovsky
0 siblings, 1 reply; 14+ messages in thread
From: Jakub Sitnicki @ 2026-03-02 19:25 UTC (permalink / raw)
To: Andrey Grodzovsky
Cc: Alexei Starovoitov, bpf, DL Linux Open Source Team,
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Jiri Olsa,
Steven Rostedt, linux-trace-kernel
On Fri, Feb 27, 2026 at 04:15 PM -05, Andrey Grodzovsky wrote:
> Hey Alexei, just to be clear, do you mean drop the entire RFC letter or,
> Drop the RFC prefix from the letter so the CI pipeline can be properly
> triggered ?
The prefix, not the cover letter.
Although I think swapping the word order might also work ("PATCH RFC").
I've seen CI run for my patch set when it was titled like that.
Kind reminder to not top-post :-)
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [External] Re: [RFC PATCH bpf-next v3 0/3] Optimize kprobe.session attachment for exact function names
2026-03-02 19:25 ` Jakub Sitnicki
@ 2026-03-02 19:47 ` Andrey Grodzovsky
0 siblings, 0 replies; 14+ messages in thread
From: Andrey Grodzovsky @ 2026-03-02 19:47 UTC (permalink / raw)
To: Jakub Sitnicki
Cc: Alexei Starovoitov, bpf, DL Linux Open Source Team,
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Jiri Olsa,
Steven Rostedt, linux-trace-kernel
On Mon, Mar 2, 2026 at 2:25 PM Jakub Sitnicki <jakub@cloudflare.com> wrote:
>
> On Fri, Feb 27, 2026 at 04:15 PM -05, Andrey Grodzovsky wrote:
> > Hey Alexei, just to be clear, do you mean drop the entire RFC letter or,
> > Drop the RFC prefix from the letter so the CI pipeline can be properly
> > triggered ?
>
> The prefix, not the cover letter.
>
> Although I think swapping the word order might also work ("PATCH RFC").
> I've seen CI run for my patch set when it was titled like that.
>
> Kind reminder to not top-post :-)
Yea, it actually did run for me anyway and your comment explains it.
Anyway, i am dropping the RFC prefix and sending V4 soon.
Andrey
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH bpf-next v3 0/3] Optimize kprobe.session attachment for exact function names
2026-02-27 20:40 [RFC PATCH bpf-next v3 0/3] Optimize kprobe.session attachment for exact function names Andrey Grodzovsky
` (3 preceding siblings ...)
2026-02-27 20:43 ` [RFC PATCH bpf-next v3 0/3] Optimize kprobe.session attachment for exact function names Alexei Starovoitov
@ 2026-03-02 12:47 ` Jakub Sitnicki
2026-03-02 18:00 ` [External] " Andrey Grodzovsky
4 siblings, 1 reply; 14+ messages in thread
From: Jakub Sitnicki @ 2026-03-02 12:47 UTC (permalink / raw)
To: Andrey Grodzovsky
Cc: bpf, linux-open-source, ast, daniel, andrii, jolsa, rostedt,
linux-trace-kernel, kernel-team
On Fri, Feb 27, 2026 at 03:40 PM -05, Andrey Grodzovsky wrote:
> - Patch 1: libbpf detects exact function names (no wildcards) in
> bpf_program__attach_kprobe_multi_opts() and bypasses kallsyms parsing,
> passing the symbol directly to the kernel via syms[] array.
> ESRCH is normalized to ENOENT for API consistency.
FWIW, Ivan was also trying to make it faster from the kernel side:
https://lore.kernel.org/bpf/20260129-ivan-bpf-ksym-cache-v1-1-ca503070dcc0@cloudflare.com/
But, IIUC, with this change we're not hitting get_ksymbol_bpf at all.
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [External] Re: [RFC PATCH bpf-next v3 0/3] Optimize kprobe.session attachment for exact function names
2026-03-02 12:47 ` Jakub Sitnicki
@ 2026-03-02 18:00 ` Andrey Grodzovsky
0 siblings, 0 replies; 14+ messages in thread
From: Andrey Grodzovsky @ 2026-03-02 18:00 UTC (permalink / raw)
To: Jakub Sitnicki
Cc: bpf, linux-open-source, ast, daniel, andrii, jolsa, rostedt,
linux-trace-kernel, kernel-team
On Mon, Mar 2, 2026 at 7:48 AM Jakub Sitnicki <jakub@cloudflare.com> wrote:
>
> On Fri, Feb 27, 2026 at 03:40 PM -05, Andrey Grodzovsky wrote:
> > - Patch 1: libbpf detects exact function names (no wildcards) in
> > bpf_program__attach_kprobe_multi_opts() and bypasses kallsyms parsing,
> > passing the symbol directly to the kernel via syms[] array.
> > ESRCH is normalized to ENOENT for API consistency.
>
> FWIW, Ivan was also trying to make it faster from the kernel side:
>
> https://urldefense.com/v3/__https://lore.kernel.org/bpf/20260129-ivan-bpf-ksym-cache-v1-1-ca503070dcc0@cloudflare.com/__;!!BmdzS3_lV9HdKG8!zla5HijIg6Vbdu0M8yoWocdwUD_o1-XyD5HUD7ZHbjKt9D846oT35Srz6_uXjkfS4eSc_i-lOw6IllBHvfaZgPHdXrKp$
>
> But, IIUC, with this change we're not hitting get_ksymbol_bpf at all.
Exactly. Also, note plz that patch [2/3] includes an extra
optimisation in the kernel ftrace path too.
Andrey
^ permalink raw reply [flat|nested] 14+ messages in thread