Skip to content

Commit 93e8fd1

Browse files
andrey-grodzovskyrostedt
authored andcommitted
ftrace: Use kallsyms binary search for single-symbol lookup
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) Cc: <bpf@vger.kernel.org> Link: https://patch.msgid.link/20260302200837.317907-3-andrey.grodzovsky@crowdstrike.com Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
1 parent c369299 commit 93e8fd1

1 file changed

Lines changed: 22 additions & 0 deletions

File tree

kernel/trace/ftrace.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9267,13 +9267,35 @@ static int kallsyms_callback(void *data, const char *name, unsigned long addr)
92679267
* @addrs array, which needs to be big enough to store at least @cnt
92689268
* addresses.
92699269
*
9270+
* For a single symbol (cnt == 1), uses kallsyms_lookup_name() which
9271+
* performs an O(log N) binary search via the sorted kallsyms index.
9272+
* This avoids the full O(N) linear scan over all kernel symbols that
9273+
* the multi-symbol path requires.
9274+
*
9275+
* For multiple symbols, uses a single-pass linear scan via
9276+
* kallsyms_on_each_symbol() with binary search into the sorted input
9277+
* array.
9278+
*
92709279
* Returns: 0 if all provided symbols are found, -ESRCH otherwise.
92719280
*/
92729281
int ftrace_lookup_symbols(const char **sorted_syms, size_t cnt, unsigned long *addrs)
92739282
{
92749283
struct kallsyms_data args;
92759284
int found_all;
92769285

9286+
/* Fast path: single symbol uses O(log N) binary search */
9287+
if (cnt == 1) {
9288+
addrs[0] = kallsyms_lookup_name(sorted_syms[0]);
9289+
if (addrs[0] && ftrace_location(addrs[0]))
9290+
return 0;
9291+
/*
9292+
* Binary lookup can fail for duplicate symbol names
9293+
* where the first match is not ftrace-instrumented.
9294+
* Retry with linear scan.
9295+
*/
9296+
}
9297+
9298+
/* Batch path: single-pass O(N) linear scan */
92779299
memset(addrs, 0, sizeof(*addrs) * cnt);
92789300
args.addrs = addrs;
92799301
args.syms = sorted_syms;

0 commit comments

Comments
 (0)