From nobody Thu Sep 24 15:10:57 2026 Received: from mail-oi2-f13.google.com (mail-oi2-f13.google.com [74.125.231.205]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A22BA49BD90 for ; Tue, 22 Sep 2026 18:46:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.205 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790102775; cv=none; b=O9rrxEsHUnLcowmeEsOdGB3w06c0lIWk+CUNBktTSba5mDwg+PoryAKbuMDJEfIJFFyG+5Zz1/xSTNRy4ejJWu4B88wNJRiSwarQYE4FIsY24Rl2fo9fHGW6rTxoOxMdRGWvxlUqsqh1tNZU/jCq70z4oSdKL6BB+P2vkd7HPrM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790102775; c=relaxed/simple; bh=wMu9e2ocAIssLOg8yDp9YiXF/7/EC3BwAFjUqD8eS08=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kTifqivlL130Sz4A2mASznZoPYzq+THFM/Uw5USjOC2Y5Q/kqLNMNFpIobrUgvGJGJHWN8Y37j+xZUyIt5LHH7vJNZtJrqCX6Ee3+ad2BPzc5zTFEYF78r+1JokzBeebIJc+o5wkfdaRiGIJi6TBIY7fpwk5y8dXb7NRKJPe8h8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Ny3lPyLs; arc=none smtp.client-ip=74.125.231.205 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Ny3lPyLs" Received: by mail-oi2-f13.google.com with SMTP id 5614622812f47-4c4923c9429so150569b6e.1 for ; Tue, 22 Sep 2026 11:46:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790102764; x=1790707564; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=GUJfe26E2BoMxoZiIjfByPcanmFJtFYPWZqrgkocTRg=; b=Ny3lPyLsaOCDGV+uc4qfWUtwEnIWV3WOES+T8UkwcEPdhBdGo3ALdmqC+1O19A99fA +nEH2ant3HW0FfdUgrHWZMAnpGtEQTP40pBLaYWpGHA9p9NJXEoMwvsXQOtWx54U/Bii MGfCPnu1oUXJk2wilHdvklBwnsXdF8fsywS2wavRzEe1/umHTFtmC+UgfRseuuZDA5X8 e5uihT0EmhFDTjEZk8bKs4I7NlgmDuVWf4Rnb9kw/nZSJHEN3CA47E1uR3COyJ5nNGY7 Dd7Gnurdd6VJVizHAPwcJHx4oAAvwNirP7mEBMgi6grRQ2UAJVHl6EjVCtAGzr17yjza vq5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790102764; x=1790707564; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=GUJfe26E2BoMxoZiIjfByPcanmFJtFYPWZqrgkocTRg=; b=AceIp3P7m6ERomiQg/mtudm9oBb7cbgAlA7TJjuEAQoDZKDrqhaMx/0jBE6+nAXsDn afhBuM7i34p26OmXj4Wh5CrwBfBKXiZJfSOqhmR4Jv+cbPVm3dS88hcbbRqY33ONdmfD x5F9YitPm9HiG5oSJ1GyRDWxBu4EFwjRb4Zsy0T2RPt2vSb3KXssdTtIxtbXfaYQlV8e pO9JAIEEo3Ce8Fwi+BOmfKFeUk1/hXJEf2KEvBQggIcNjPYHvws2MGdRahnCy3jHLLLR F6qm38LRH0kFFyyGMXolhEnTeqDINmMJZcU563zuhJ+dkFlnzyyS462xetrgKaKdHsJN sIFw== X-Forwarded-Encrypted: i=1; AKwUvByMXcBKyZnwPhzC8RIsuL59BnBHpEQrzGxClVcEjPKEVMuYXh0bALQ24UhMiQHKTqzry9iwA+m9QZIl1qg=@vger.kernel.org X-Gm-Message-State: AFuF++krT3bbjOBvWwH30KAOlWNbbUOxDH+RozJySQeiElNOBfSv9JIg TBenWEd4lEmq8ziKYxXLm6f+bbXMvzdjexY0AIwkcQI64oVjct/vnxpM X-Gm-Gg: AYBFou2aaSZ3xuiqlq0hJQQFqdMFwz/866msD/YoWgGjXhFrbl7BhiewZbcN8b4cukO /UOGuO75Ubrv7qRChdT1yenRMthZbNAOWlqGFw5OrIptKWrdg+xs+4FtC7WyGGd4z4zWurtkPHN rhkqnYt0hlPgXpkTcmgE9plsPVcmntpMjjKWYrpH8QK/qpe40b1F8ZpebZtrhaQ9NRB9famJsFT St+RK8nUS8mANQwqfkKceBz3Ve46kiO2DW5Vweucmc/Mvx4kHoCn5SJRYGclfN42rVOH0z1r9NR 4yL5fKcIL23h6A0WzK7OzjJ8PSYAjzk+eY/qEgVQWhaDZZIcBq6r+Orxi8qYimVimgKZyJKdkDU 8Ik4iCica6pP3dKusOECuSEE/eR1tZRSUC4cgGxxIG1naTzP2mw6QVnvo7POSVrE0JbnAjP2SBw SVYKUUthU4pIA6+tNS3J9pSIwiRl6gphaWGGScCagTF1wdL1tY3sozJM5+WaU9Yre727rpKwKKV T5AFtkNdCjgP+PfhwFS+gvrEGzbPfxnhy4pDb4CnYsp65OvpalJMeg4UctPY+Yb5XxX/I2mTXLS 7rHu3/m4IlO4ZX7KliU= X-Received: by 2002:a05:6808:3c4e:b0:4bd:c9fa:b1b1 with SMTP id 5614622812f47-4d5b940da4fmr263959b6e.40.1790102764236; Tue, 22 Sep 2026 11:46:04 -0700 (PDT) Received: from [100.82.231.29] (c-98-38-17-99.hsd1.co.comcast.net. [98.38.17.99]) by smtp.googlemail.com with ESMTPSA id 5614622812f47-4d5c43a24bbsm147545b6e.7.2026.09.22.11.46.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 11:46:03 -0700 (PDT) From: Jim Cromie Date: Tue, 22 Sep 2026 12:45:55 -0600 Subject: [PATCH v3 1/4] kallsyms: Add test_kallsyms_perf module to benchmark lookup latency Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260922-ksyms-tune-v3-1-681a34ea05d9@gmail.com> References: <20260922-ksyms-tune-v3-0-681a34ea05d9@gmail.com> In-Reply-To: <20260922-ksyms-tune-v3-0-681a34ea05d9@gmail.com> To: Andrew Morton Cc: Lorenzo Stoakes , Kees Cook , David Laight , Masahiro Yamada , linux-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, bpf@vger.kernel.org, Jim Cromie X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790102761; l=9990; i=jim.cromie@gmail.com; s=20260203; h=from:subject:message-id; bh=wMu9e2ocAIssLOg8yDp9YiXF/7/EC3BwAFjUqD8eS08=; b=woZjuWDZnG/RH2ZnaizqyzADKXsGtbr+LDFN10w9+WJn0UpEFO+GTOu+gyrx+3b85W5vdhiVK kiI5f9jNsuICBkgh/omz/HgL1/3ssbu/2DhT+htkq4kieHAIxJdiM4s X-Developer-Key: i=jim.cromie@gmail.com; a=ed25519; pk=C6E5ODlPQo7ZBynATXH9wg7K6HxP0pIXyf4s38Qw0XE= To evaluate optimizations and measure performance regressions across kallsyms lookups, add a lightweight microbenchmark module in lib/. Configure CONFIG_TEST_KALLSYMS_PERF as a built-in test (bool) rather than a loadable module (tristate). Building the test directly into vmlinux allows exercising internal kallsyms traversal APIs without exporting internal symbol iterators (EXPORT_SYMBOL_GPL) to modules, preserving kernel symbol table encapsulation. The module exercises the primary kallsyms resolution paths: 0. Name-to-Address binary search: Benchmarks lookups across common kernel functions (hits) and non-existent symbol strings (misses, exercising the full binary search tree depth). 1. Address-to-Name resolution: Benchmarks address decoding latency via sprint_symbol() and sprint_symbol_no_offset(). 2. Sequential table scan: Measures complete table iteration latency via kallsyms_on_each_symbol(). The module exposes a num_iters parameter (default: 100,000) and a sysfs trigger to repeat benchmark runs on demand. Signed-off-by: Jim Cromie --- Changes in v3: - Convert CONFIG_TEST_KALLSYMS_PERF from tristate to bool and drop kallsyms iterator EXPORT_SYMBOL_GPL exports to preserve security encapsulation (addresses Sashiko AI review). - Drop 'default m' from lib/Kconfig.debug. - Add cond_resched() every 16k iterations to avoid soft lockups. - Replace direct 64-bit division with div_u64() to fix 32-bit builds. - Guard against divide-by-zero when num_iters=3D0. - Replace tcp_v4_rcv with panic in hit_symbols to prevent failures wo CONFIG_INET. - Switch to late_initcall for built-in invocation. --- lib/Kconfig.debug | 10 ++ lib/Makefile | 1 + lib/test_kallsyms_perf.c | 241 +++++++++++++++++++++++++++++++++++++++++++= ++++ 3 files changed, 252 insertions(+) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 134b15a44625..4b9669e64db9 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -3122,6 +3122,16 @@ config TEST_STATIC_KEYS =20 If unsure, say N. =20 +config TEST_KALLSYMS_PERF + bool "kallsyms performance benchmark test module" + depends on KALLSYMS + help + This builds test_kallsyms_perf to benchmark latency across + Name-to-Address binary search, Address-to-Name resolution, + and full table walks. + + If unsure, say N. + config TEST_DYNAMIC_DEBUG tristate "Test DYNAMIC_DEBUG" depends on DYNAMIC_DEBUG diff --git a/lib/Makefile b/lib/Makefile index dfab958327c5..149968ff3f6b 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -85,6 +85,7 @@ obj-$(CONFIG_TEST_RHASHTABLE) +=3D test_rhashtable.o obj-$(CONFIG_TEST_STATIC_KEYS) +=3D test_static_keys.o obj-$(CONFIG_TEST_STATIC_KEYS) +=3D test_static_key_base.o obj-$(CONFIG_TEST_DYNAMIC_DEBUG) +=3D test_dynamic_debug.o +obj-$(CONFIG_TEST_KALLSYMS_PERF) +=3D test_kallsyms_perf.o =20 obj-$(CONFIG_TEST_BITMAP) +=3D test_bitmap.o ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_KASAN),yy) diff --git a/lib/test_kallsyms_perf.c b/lib/test_kallsyms_perf.c new file mode 100644 index 000000000000..4d0c39c0a94f --- /dev/null +++ b/lib/test_kallsyms_perf.c @@ -0,0 +1,241 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Microbenchmark and correctness test module for kallsyms subsystem + * + * Measures CPU latency across: + * - Name-to-Address binary search (hits & misses) + * - Address-to-Name symbol resolution (sprint_symbol, buildid) + * - Full kernel symbol iteration (kallsyms_on_each_symbol) + */ + +#define pr_fmt(fmt) "test_kallsyms: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned int num_iters =3D 100000; +module_param(num_iters, uint, 0644); +MODULE_PARM_DESC(num_iters, "Number of iterations per microbenchmark"); + +static const char * const hit_symbols[] =3D { + "_printk", + "schedule", + "vfs_read", + "do_sys_openat2", + "kernel_clone", + "panic", + "kallsyms_lookup_names", + "vm_area_alloc", +}; + +static const char * const miss_symbols[] =3D { + "nonexistent_symbol_0001", + "xyz_dummy_missing_symbol", + "__never_compiled_in_kernel", + "ext4_nonexistent_func_xyz", + "bpf_not_real_helper_stub", + "vfs_missing_handler_probe", + "tcp_v4_unimplemented_path", + "driver_fake_init_routine", +}; + +static int match_cb(void *data, unsigned long addr) +{ + unsigned long *out =3D data; + + *out =3D addr; + return 1; +} + +static int count_cb(void *data, const char *name, unsigned long addr) +{ + unsigned long *cnt =3D data; + + (*cnt)++; + return 0; +} + +static void run_name_lookup_bench(void) +{ + u64 t0, t1, dt_hit, dt_miss; + unsigned long addr =3D 0; + unsigned int i, nr_hits, nr_misses; + + nr_hits =3D ARRAY_SIZE(hit_symbols); + nr_misses =3D ARRAY_SIZE(miss_symbols); + + /* 0. Correctness validation */ + for (i =3D 0; i < nr_hits; i++) { + const char *sym =3D hit_symbols[i]; + unsigned long a1 =3D 0; + + kallsyms_on_each_match_symbol(match_cb, sym, &a1); + if (!a1) + pr_err("CORRECTNESS FAILURE: hit sym '%s' not found\n", sym); + } + for (i =3D 0; i < nr_misses; i++) { + const char *sym =3D miss_symbols[i]; + unsigned long a1 =3D 0; + + kallsyms_on_each_match_symbol(match_cb, sym, &a1); + if (a1) + pr_err("CORRECTNESS FAILURE: miss sym '%s' unexpectedly found a1=3D%lx\= n", + sym, a1); + } + + /* 1. Name search: Existing symbols (Hits) */ + t0 =3D ktime_get_ns(); + for (i =3D 0; i < num_iters; i++) { + const char *sym =3D hit_symbols[i % nr_hits]; + + if (unlikely(!(i & 0x3fff))) + cond_resched(); + + kallsyms_on_each_match_symbol(match_cb, sym, &addr); + OPTIMIZER_HIDE_VAR(addr); + } + t1 =3D ktime_get_ns(); + dt_hit =3D t1 - t0; + + /* 2. Name search: Non-existent symbols (Misses - 17 bsearch probes) */ + t0 =3D ktime_get_ns(); + for (i =3D 0; i < num_iters; i++) { + const char *sym =3D miss_symbols[i % nr_misses]; + + if (unlikely(!(i & 0x3fff))) + cond_resched(); + + kallsyms_on_each_match_symbol(match_cb, sym, &addr); + OPTIMIZER_HIDE_VAR(addr); + } + t1 =3D ktime_get_ns(); + dt_miss =3D t1 - t0; + + pr_info("Name Search Hit: %llu ns/lookup (%llu ms total, %u iters)\n", + div_u64(dt_hit, num_iters), div_u64(dt_hit, 1000000), num_iters); + pr_info("Name Search Miss: %llu ns/lookup (%llu ms total, %u iters)\n", + div_u64(dt_miss, num_iters), div_u64(dt_miss, 1000000), num_iters); +} + +static void run_address_lookup_bench(void) +{ + u64 t0, t1, dt_sprint, dt_bldid; + char symname[KSYM_SYMBOL_LEN]; + unsigned long addrs[ARRAY_SIZE(hit_symbols)]; + unsigned int i, nr_addrs =3D 0; + + for (i =3D 0; i < ARRAY_SIZE(hit_symbols); i++) { + unsigned long addr =3D 0; + + kallsyms_on_each_match_symbol(match_cb, hit_symbols[i], &addr); + if (addr) + addrs[nr_addrs++] =3D addr; + } + + if (!nr_addrs) { + pr_warn("Address benchmark skipped: no test addresses resolved\n"); + return; + } + + /* 1. Address-to-name resolution (sprint_symbol) */ + t0 =3D ktime_get_ns(); + for (i =3D 0; i < num_iters; i++) { + unsigned long addr =3D addrs[i % nr_addrs]; + + if (unlikely(!(i & 0x3fff))) + cond_resched(); + + sprint_symbol(symname, addr); + barrier_data(symname); + } + t1 =3D ktime_get_ns(); + dt_sprint =3D t1 - t0; + + /* 2. Address without offset (sprint_symbol_no_offset) */ + t0 =3D ktime_get_ns(); + for (i =3D 0; i < num_iters; i++) { + unsigned long addr =3D addrs[i % nr_addrs]; + + if (unlikely(!(i & 0x3fff))) + cond_resched(); + + sprint_symbol_no_offset(symname, addr); + barrier_data(symname); + } + t1 =3D ktime_get_ns(); + dt_bldid =3D t1 - t0; + + pr_info("sprint_symbol: %llu ns/lookup (%llu ms total, %u iters= )\n", + div_u64(dt_sprint, num_iters), div_u64(dt_sprint, 1000000), num_iters); + pr_info("sprint_symbol_no_offset: %llu ns/lookup (%llu ms total, %u iters= )\n", + div_u64(dt_bldid, num_iters), div_u64(dt_bldid, 1000000), num_iters); +} + +static void run_table_walk_bench(void) +{ + u64 t0, t1, dt_walk; + unsigned long total_symbols =3D 0; + int iter =3D 50; + int i; + + t0 =3D ktime_get_ns(); + for (i =3D 0; i < iter; i++) { + total_symbols =3D 0; + kallsyms_on_each_symbol(count_cb, &total_symbols); + } + t1 =3D ktime_get_ns(); + dt_walk =3D t1 - t0; + + pr_info("Table Full Walk: %llu ns/sym (%llu us/pass, %lu symbols scanned= , %d passes)\n", + div_u64(div_u64(dt_walk, iter), total_symbols ? total_symbols : 1), + div_u64(div_u64(dt_walk, iter), 1000), total_symbols, iter); +} + +static int run_kallsyms_benchmark(void) +{ + if (!num_iters) { + pr_err("num_iters must be non-zero\n"); + return -EINVAL; + } + + pr_info("=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D\n"); + pr_info("Starting kallsyms performance benchmark (iters=3D%u)\n", num_ite= rs); + pr_info("=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D\n"); + + run_name_lookup_bench(); + run_address_lookup_bench(); + run_table_walk_bench(); + + pr_info("=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D\n"); + pr_info("kallsyms benchmark complete\n"); + pr_info("=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D\n"); + + return 0; +} + +static int param_set_trigger(const char *val, const struct kernel_param *k= p) +{ + return run_kallsyms_benchmark(); +} + +static const struct kernel_param_ops param_ops_trigger =3D { + .set =3D param_set_trigger, +}; +module_param_cb(run_test, ¶m_ops_trigger, NULL, 0200); +MODULE_PARM_DESC(run_test, "Write 1 to trigger kallsyms benchmark run"); + +static int __init test_kallsyms_init(void) +{ + return run_kallsyms_benchmark(); +} +late_initcall(test_kallsyms_init); + +MODULE_DESCRIPTION("Microbenchmark test module for kallsyms subsystem"); +MODULE_AUTHOR("Jim Cromie "); +MODULE_LICENSE("GPL"); --=20 2.55.0 From nobody Thu Sep 24 15:10:57 2026 Received: from mail-oi2-f13.google.com (mail-oi2-f13.google.com [74.125.231.205]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A214B49BD8A for ; Tue, 22 Sep 2026 18:46:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.205 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790102782; cv=none; b=hBnS5u8CwB1ksWTJn0AUEc1OCexRTr6FUfdZdr7NiTX66JrpX1XB829IEkwl4IpQbvadJnWa3Cbdj5QvdSS9JZjXEeEs5Qrtn8j0Oej5S+sOcZVoRa9EsiBzzxdBRXjcxaJgDTPBikIKBxUSDap1D2gffaVmA3MN4rlsaahixjE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790102782; c=relaxed/simple; bh=uSwF8oSlv0A6TNXHp0b7ZlXImXaVRQqeD6cloMWgLIg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RoQTexRvzFLBA8adADaKPWGnOl+ZVLjLLr8LUpgGAz24llUtSlJtdiZ9aj5vK9echOCyacBHfa9YyzYB61YxCDwxvx6f7sJlDwDphEvpFeJz7hKeW/iVSTRB75zIeJbqjs2ZDWD2UV2t9qbJAri4Mw8ysvAK+Pjm+Mu6B/hbKwk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=FGkzARcJ; arc=none smtp.client-ip=74.125.231.205 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FGkzARcJ" Received: by mail-oi2-f13.google.com with SMTP id 5614622812f47-4c0766cbe64so145007b6e.3 for ; Tue, 22 Sep 2026 11:46:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790102766; x=1790707566; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=hU8R4H4DyIVzYPzLtsXcibjq0wK/EbWMtmm1iMO2MGU=; b=FGkzARcJ8Tqf/wCPRmmnR6Ml81XhGhSv5nJEtw9hyNcOh8TVyWfA1Q6UzAmxwGRl1T Tm36kXbT24iJMGIbBy1Ppylyvs8wiJBzY8cHNRbj88DrD8pAvyR6RRFRIImTDKdRT+4G 0/vW84IMPKrQgScWdue6NzP1MQbpOWy1BduPvuypyyofRSUEPlaly56kRJ1Y6dM7Rbeh Y1are+of/VqjrRP19gtVaodW+Fba3+LAxoi4f6gTzTM8kgEi8TW8GacnbjWfgyd7yah5 Mvj9AJ6k1YBOhL7/Ch8X69Gv8putfUo2q2zgj7NABHnjOlYpDHW30uP4merB/bGGX7nf A16g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790102766; x=1790707566; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=hU8R4H4DyIVzYPzLtsXcibjq0wK/EbWMtmm1iMO2MGU=; b=xJw+PmLL+3qjT9kbSCNMrfgARL6LceSoRsQyV5QX+buarTW10PIon8QgNkB1r9+PwK Qewzir8VAMIfTbLnBe+8f0lZeT7nQQnBbLeapJBfQFvq52sC5XOymJ5sd8zQfOZwaW5R FSAaVWFOWp6VqJa+MCrn2eMTLoNZeFEkwDWiCz933vLW8WGUdGTGC47VscTY9QmhZV8K OKBbrpjnYDgIUdvtQI300l5fAUVluRsf1hlLTHeiTi4Jwb8Oa7puOgk4xN8iuGuupL2j TisiPx3o2ImvabgtdFxYsYDKjn3yYcur6GOiCrdQMTGfEl9Cub8zNPLsFa1TQxtIRVFh shqQ== X-Forwarded-Encrypted: i=1; AKwUvBxDeq4wlgogSg0susFx5xHYX7hmjF5egmXVnmcZRJgHVMUEwwUzcOA1+FE+h3oZVTieIU9bPGtmkMbVfws=@vger.kernel.org X-Gm-Message-State: AFuF++mMDvEuezUowuAh6GTN2RRzPDyO7b3u2ftS7SCfxKdgT2uvMIV1 s1gPG+wfYyOfC5BMVBaybqDF3M00EujG8P5hOSZbu5fXCmFB0UnlSpuJ X-Gm-Gg: AYBFou3xTjyeUE0Ws+xEnbbXKnr5M+i3uq7rJlS/bq8Bk4dEwgRQlX8AZLsWE+aNkss FXpIq/rqmOHFkVPtR9p9m737xnF0hBm0W9RWBcF6s41rJDlZPSdCEWDbErKqlHMS2MJIa8C71Me DNtVUitNdFBDld+LbjXni2lJmFqiLzRrZ6qVSSMAUagx6OS9eVJB4ckeI5Fv+LhfNVjhyMfJCXy 7XIkWvZYg4R1qBoYMvSwg3ZEpdgQqXVGgOFJJV1yqOwmhZ0LillhhWD0bmH/Euk9ADhMCWHQWOO Q9+nYSGEXD6s4RKyDLxF6uIZ7dmdubvcmdL/xbJJYO1xRgXpgDxO7RLtLXjz4pryjweQnaHOE+0 mU5nprCmtvohm5fwHyYDVE3rcSq3SDZ546+Ik0EC6UE0fHLDoYVpf3R8RbI1AZJtFrtSJPyH0Bn Kje/pcVHrl+hbKuSc2Ox6yETmeth0IEf0cR6LNMAYmpG9UL9WDMqaY9EDh4bXcGgwjiJLEWS6AO qcaJdVIcmdFZozq/AwMEqlqWWILT1KlIWYLZ87XcycmmrOe06x76vaQy/Xe77Ha7lFiH4DZjuIy 3YCyV18upR4o62uTjMU= X-Received: by 2002:a05:6808:2e4b:b0:4c5:a75f:c5e1 with SMTP id 5614622812f47-4d5b741218emr319290b6e.13.1790102765762; Tue, 22 Sep 2026 11:46:05 -0700 (PDT) Received: from [100.82.231.29] (c-98-38-17-99.hsd1.co.comcast.net. [98.38.17.99]) by smtp.googlemail.com with ESMTPSA id 5614622812f47-4d5c43a24bbsm147545b6e.7.2026.09.22.11.46.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 11:46:05 -0700 (PDT) From: Jim Cromie Date: Tue, 22 Sep 2026 12:45:56 -0600 Subject: [PATCH v3 2/4] kallsyms: Match compressed tokens on the fly during binary search Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260922-ksyms-tune-v3-2-681a34ea05d9@gmail.com> References: <20260922-ksyms-tune-v3-0-681a34ea05d9@gmail.com> In-Reply-To: <20260922-ksyms-tune-v3-0-681a34ea05d9@gmail.com> To: Andrew Morton Cc: Lorenzo Stoakes , Kees Cook , David Laight , Masahiro Yamada , linux-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, bpf@vger.kernel.org, Jim Cromie X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790102761; l=6596; i=jim.cromie@gmail.com; s=20260203; h=from:subject:message-id; bh=uSwF8oSlv0A6TNXHp0b7ZlXImXaVRQqeD6cloMWgLIg=; b=L+IqEDuVTiikfaFvoXKwSVD7EFUwRep8RiTSWjPH8o+efOSG3jXM2WysT+Om/XLuhiJpe+cDv ggBPtOgTLFyCKx3ETfwCUXH3c4A2qnvP2Ai2OGj+sETPWjJLSOl60/2 X-Developer-Key: i=jim.cromie@gmail.com; a=ed25519; pk=C6E5ODlPQo7ZBynATXH9wg7K6HxP0pIXyf4s38Qw0XE= kallsyms_lookup_names() runs a binary search across kallsyms_names[], a packed array of ~130k encoded kernel symbols. For each of the ~17 comparisons in the search, it currently decompresses the candidate symbol into a temporary buffer on the stack before calling strcmp(). Comparing raw tokens directly in compressed space is impossible. The BPE token table assigns values by frequency, not alphabetical order (e.g. token 0x05 might expand to "zebra" while 0x42 expands to "apple"), so comparing raw token values scrambles lexicographical order. However, full string expansion is equally wasteful: roughly 16 of the 17 binary search steps fail within the first two characters. Introduce kallsyms_strcmp_symbol() to compare ASCII queries against compressed tokens on the fly. It walks kallsyms_token_index and kallsyms_token_table incrementally, matching characters directly and bailing out on the first character mismatch without expanding subsequent tokens. This optimization: 0. Avoids decompressing non-matching tokens, short-circuiting ~94% of binary search character expansions without adding any tables in .rodata. 1. Drops the 512-byte namebuf buffer from the kernel stack in kallsyms_lookup_names(). 2. Cuts unindexed lookup latency by ~530 ns (~14% faster) while leaving sequential address ordering and kallsyms_expand_symbol() streaming invariants intact for /proc/kallsyms and table walks. Signed-off-by: Jim Cromie --- Changes in v3: - Reorder patch ahead of dynamic batch index in series, establishing an active proof of string matching savings on unindexed baseline (addresses David Laight review). - Optimize kallsyms_strcmp_symbol(): drop skipped_first tracking and test len at loop bottom (addresses David Laight review). - Guard first token with while (*tptr) to handle 1-byte type tokens. - Introduce get_symbol_data() helper in this patch for reuse in later subsystems. Changes in v2: - Rebase onto mainline v7.3-rc4, removing external dependencies on Lorenzo Stoakes' kbuild series. --- kernel/kallsyms.c | 94 ++++++++++++++++++++++++++++++++++-----------------= ---- 1 file changed, 59 insertions(+), 35 deletions(-) diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index aec2f06858af..d18d78e626db 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -34,6 +34,21 @@ =20 #include "kallsyms_internal.h" =20 +/* + * Get the compressed symbol length and data pointer. + */ +static inline const u8 *get_symbol_data(unsigned int off, unsigned int *le= n) +{ + const u8 *p =3D &kallsyms_names[off]; + unsigned int l =3D *p++; + + if (unlikely(l & 0x80)) + l =3D (l & 0x7F) | (*p++ << 7); + *len =3D l; + + return p; +} + /* * Expand a compressed symbol data into the resulting uncompressed string, * if uncompressed string is too long (>=3D maxlen), it will be truncated, @@ -42,28 +57,12 @@ static unsigned int kallsyms_expand_symbol(unsigned int off, char *result, size_t maxlen) { - int len, skipped_first =3D 0; + int skipped_first =3D 0; const char *tptr; - const u8 *data; + unsigned int len; + const u8 *data =3D get_symbol_data(off, &len); =20 - /* Get the compressed symbol length from the first symbol byte. */ - data =3D &kallsyms_names[off]; - len =3D *data; - data++; - off++; - - /* If MSB is 1, it is a "big" symbol, so needs an additional byte. */ - if ((len & 0x80) !=3D 0) { - len =3D (len & 0x7F) | (*data << 7); - data++; - off++; - } - - /* - * Update the offset to return the offset for the next symbol on - * the compressed stream. - */ - off +=3D len; + off =3D (data - kallsyms_names) + len; =20 /* * For every byte on the compressed symbol data, copy the table @@ -101,14 +100,43 @@ static unsigned int kallsyms_expand_symbol(unsigned i= nt off, */ static char kallsyms_get_symbol_type(unsigned int off) { - /* - * Get just the first code, look it up in the token table, - * and return the first char from this token. If MSB of length - * is 1, it is a "big" symbol, so needs an additional byte. - */ - if (kallsyms_names[off] & 0x80) - off++; - return kallsyms_token_table[kallsyms_token_index[kallsyms_names[off + 1]]= ]; + unsigned int len; + const u8 *data =3D get_symbol_data(off, &len); + + return kallsyms_token_table[kallsyms_token_index[*data]]; +} + +/* + * Compare an uncompressed ASCII string against a compressed symbol table = entry. + * Returns negative if name < sym, positive if name > sym, 0 if equal. + * Exits immediately on the first mismatched character without decompressi= ng + * the rest of the symbol name. + */ +static int kallsyms_strcmp_symbol(unsigned int off, const char *name) +{ + const char *tptr; + unsigned int len; + const u8 *data =3D get_symbol_data(off, &len); + + tptr =3D &kallsyms_token_table[kallsyms_token_index[*data++]] + 1; + while (*tptr) { + int diff =3D (unsigned char)*name++ - (unsigned char)*tptr++; + + if (diff) + return diff; + } + + while (--len) { + tptr =3D &kallsyms_token_table[kallsyms_token_index[*data++]]; + do { + int diff =3D (unsigned char)*name++ - (unsigned char)*tptr++; + + if (diff) + return diff; + } while (*tptr); + } + + return (unsigned char)*name; } =20 =20 @@ -174,7 +202,6 @@ static int kallsyms_lookup_names(const char *name, int ret; int low, mid, high; unsigned int seq, off; - char namebuf[KSYM_NAME_LEN]; =20 low =3D 0; high =3D kallsyms_num_syms - 1; @@ -183,8 +210,7 @@ static int kallsyms_lookup_names(const char *name, mid =3D low + (high - low) / 2; seq =3D get_symbol_seq(mid); off =3D get_symbol_offset(seq); - kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); - ret =3D strcmp(name, namebuf); + ret =3D kallsyms_strcmp_symbol(off, name); if (ret > 0) low =3D mid + 1; else if (ret < 0) @@ -200,8 +226,7 @@ static int kallsyms_lookup_names(const char *name, while (low) { seq =3D get_symbol_seq(low - 1); off =3D get_symbol_offset(seq); - kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); - if (strcmp(name, namebuf)) + if (kallsyms_strcmp_symbol(off, name) !=3D 0) break; low--; } @@ -212,8 +237,7 @@ static int kallsyms_lookup_names(const char *name, while (high < kallsyms_num_syms - 1) { seq =3D get_symbol_seq(high + 1); off =3D get_symbol_offset(seq); - kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf)); - if (strcmp(name, namebuf)) + if (kallsyms_strcmp_symbol(off, name) !=3D 0) break; high++; } --=20 2.55.0 From nobody Thu Sep 24 15:10:57 2026 Received: from mail-oi2-f13.google.com (mail-oi2-f13.google.com [74.125.231.205]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 59AC4491587 for ; Tue, 22 Sep 2026 18:46:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.205 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790102775; cv=none; b=Kq+p1V9HGUdtYu/BlUFAHfK+WbmN9Hg1dz1Ad1+2P2kfczsNHHcRbvG1VoAyfcXQGJUvmLkkpEXF0pY9MKmlIVQqdh0LKsUxdYoNl+gfKPAJVrbsPh59B3SvVkr4Ik371P/Qnh9wZIXY7Gnv+oEDJRyXhnIJNVKzZ8c13rEYyrI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790102775; c=relaxed/simple; bh=W1G8f3z87fRtdP3m4EwgGe3eSQQfVOfCvXJSmTGP2Fg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=H8t8WjpdKTC+qrtyje5GCDthKgyCqKxQOnG6/5NEv54+qwsyvYtYSRaQBPRdymHTAGv4BGhglKUTGewr5RY5CicmG4aXTALi1dl2C27XnUmIsZRDC7ZoLXGa3NJPMKV+VPbHlxZh4JNPE2lNQpjXaD8XMG+AJ2XUZnZeFTledxU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=IeoSAchH; arc=none smtp.client-ip=74.125.231.205 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IeoSAchH" Received: by mail-oi2-f13.google.com with SMTP id 5614622812f47-4c54eed93e4so123550b6e.3 for ; Tue, 22 Sep 2026 11:46:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790102767; x=1790707567; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Rf5xe6WUqCsXT+XF1tg4Kzzo4eg3jZJWfjIuxnrfwhA=; b=IeoSAchHXGXgR2rNtbdXCZZRLpxetq9NL7Iqt1AylJaGu/KHpbYH66259Mgv5Z1R0A 5JtYi3SBv+aR2O2M/iaSA2RSj0j/rPlC03soBdLFw5y5f//sEeMxjRdYVkOeBW5BljD9 0pWRaW1hUeuMhG70TRU+SvWJhHdH7yajUtCfe4SkFiY7Dc2V7M1m471fizCVGtUMqsID bhre55IWAA0M0Lc3DVr8Ug0MKnkF0QDOaXOJIZFsOvn1bRsVU+nd6lKoJhsKbaQ9X8Rr kt6Z+LR3teL9qcjormHf7lgmcB7rE8BbgiaXU8Bx7JOCR2EtF5YZ8Zmb8PJCOo8CBV4E OURg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790102767; x=1790707567; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=Rf5xe6WUqCsXT+XF1tg4Kzzo4eg3jZJWfjIuxnrfwhA=; b=Rif4A0b2Yqt3sgFWveFZ3o7sUQD5G2cN4DBPIWZHIW23cL0+u0VVLDQUrvbloLu21u Peg3lV9sHCtdHD+V9c6PHf4vhei3CTdvh3RjOicbPj+QRKTbeTuDy0SGy7PqvtMTZdAG IMxDsImjQDCTK7ZBrtDuJ1+od1BCZSzqyU2u6RzUrGme8I7EU5u3MJLfqZCcNoJ7Wm1V H39Sqymk3fP4+snol8/gwbGZydpNxPc3zZfgPSPFJV/flHTMUsTtYoz4ygAqWdQRjrSf EyPDRJRbnqYA8yoaPGF01r/FshRJeH6HUCMLp+MLEwPlSM5uPEXACJkRENjADCdiBQMT KcSw== X-Forwarded-Encrypted: i=1; AKwUvBwkLuwgzA6/nqQkZ2oNuYsWDGLMvMeW0Wk77neuegOYaBJDi2eSTOO01p4CO6BW9mo++JzDffZ3zlwrClI=@vger.kernel.org X-Gm-Message-State: AFuF++mxAP4ZufFwz3VTh8B652CUfBx6nMIWgoLyNY4DYWdQXY0qbOyA izh3uKElY5SVugjrKA4GHXthqCKlsOE9nx/ypoWi4ansWXThFy7N8uYi X-Gm-Gg: AYBFou0W/g2IPrwEFIU98RE2sw56fYErVOqdn2S0dOXZUq4gEWeWrtLk1pBU8aSx8HG ogrr/C9lnsnCN3YV5DgCqJzQ9qcrFQkphQrVs5TANOyrr2qLCFT4IPQVi6H9Ift4NC1WtKHOI7d 2/NLZz2b1Xu+Um8+nisuduDDf+IO65vebtaXSFj8WHWwwW7ykxXWyQZ/ZIJSwaNSkL3QcoALzZ7 43WTOuoSg2zTnhgZptmwr4k/4G+8jVKFa28noahuZ6ZnNO05SUt/x9Zpm17f+Tx9wkwTZXUnJmd l98Adwg0FheRDImXKBvXYctNXVpDHLbo6pSmCf1yi2exdu1YbyYIfhLlinMlm6kT1UGqvs5JssM BM51yAfurlGabnHo9+FgvqiPAS5j8F9rKUhnVJEco+vvEn6YZHfN5iUGs++K6cMKwyx+JIfmY4z y3qfMhGSFFj1KJ/Se80AeBA6vzT1fbTS1K8y5x6DHyt0lqjERjQwYUFhHK0pEpL9ExeNhPJ4jvI AVDSGvzFbWj4INd9WW7+g9XaH5JQ9mC+t5YJCzGCyubDN+ZFoHlFu1RGLfZUY1MWDkknvhVcC3g vJ63LbXRV0NUxuzE/Hk= X-Received: by 2002:a05:6808:4fe7:b0:4c3:b4b6:94a7 with SMTP id 5614622812f47-4d5b8ddbe7emr291892b6e.27.1790102767231; Tue, 22 Sep 2026 11:46:07 -0700 (PDT) Received: from [100.82.231.29] (c-98-38-17-99.hsd1.co.comcast.net. [98.38.17.99]) by smtp.googlemail.com with ESMTPSA id 5614622812f47-4d5c43a24bbsm147545b6e.7.2026.09.22.11.46.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 11:46:06 -0700 (PDT) From: Jim Cromie Date: Tue, 22 Sep 2026 12:45:57 -0600 Subject: [PATCH v3 3/4] kallsyms: Add dynamic lookup index for batch resolution Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260922-ksyms-tune-v3-3-681a34ea05d9@gmail.com> References: <20260922-ksyms-tune-v3-0-681a34ea05d9@gmail.com> In-Reply-To: <20260922-ksyms-tune-v3-0-681a34ea05d9@gmail.com> To: Andrew Morton Cc: Lorenzo Stoakes , Kees Cook , David Laight , Masahiro Yamada , linux-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, bpf@vger.kernel.org, Jim Cromie X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790102761; l=13282; i=jim.cromie@gmail.com; s=20260203; h=from:subject:message-id; bh=W1G8f3z87fRtdP3m4EwgGe3eSQQfVOfCvXJSmTGP2Fg=; b=IfOrtrq0UzVkxJKpV8/R78+muLZsk1WEpERC9teB3xt4JeEmf5KjOAIJSm5YJOrADlEORqJDN YrMXklh7YLFChbVPWHqoe0IN2ubW1FTM8X1hkieBRwJeNnKZrwk3/Pe X-Developer-Key: i=jim.cromie@gmail.com; a=ed25519; pk=C6E5ODlPQo7ZBynATXH9wg7K6HxP0pIXyf4s38Qw0XE= kallsyms_lookup_names() resolves symbol names to addresses using a binary search over kallsyms_seqs_of_names[]. In baseline, each step invokes get_symbol_offset(), which scans sequentially from the nearest 256-symbol marker in kallsyms_names[] (averaging ~128 ULEB128 header decodes per probe, ~2,176 decodes per lookup). During bulk symbol resolution workloads (e.g. BPF multi-kprobe / fprobe tracing attaching across tens of thousands of functions), this linear scan compounds into substantial kernel attach latency (~3.3 us per lookup). Baking a permanent direct index into .rodata accelerates lookups but consumes hundreds of KiB of unswappable kernel image memory, which is unjustified when bulk lookups are infrequent. Introduce a dynamic u32 lookup index populated on demand in transient RAM and discarded when the batch workload completes: 0. Expose kallsyms_lookup_batch_start() and kallsyms_lookup_batch_end() bracketed by a mutex and refcount. On the first caller, allocate a flat u32 table spanning all kallsyms_num_syms entries (~736 KiB in transient RAM for ~184k symbols) via kvmalloc_array() and populate the symbol offsets via a single sequential scan in ~150 us. 1. In get_symbol_offset(), when the dynamic table is active, return offsets[pos] directly as an O(1) array access with 0 hops, bracketed by rcu_read_lock() and rcu_read_unlock(). 2. If the dynamic table is unallocated (refcount 0), fall back to the legacy kallsyms_markers[] scan, preserving 100% safety for oops, panic, NMI, and low-memory environments without any .rodata bloat. 3. Wrap kallsyms_lookup_names() in rcu_read_lock() / rcu_read_unlock() to ensure lockless lifetime safety across multi-probe searches. 4. Update test_kallsyms_perf and kallsyms_selftest to benchmark both unindexed marker scans and the dynamic batch index side by side, reporting batch lookup performance alongside query amortization break-even points. Signed-off-by: Jim Cromie --- Changes in v3: - Reorder patch after on-the-fly token matching (patch 2) to cleanly isolate and measure the impact of the O(1) dynamic table on top of fast string matching (addresses David Laight review). - Consume get_symbol_data() helper introduced in patch 2 to preserve clean git bisectability (addresses Sashiko AI review). - Fix use-after-free race on dyn_kallsyms_offsets: bracket table dereference and array read with rcu_read_lock() and replace rcu_dereference_raw() with rcu_dereference() inside get_symbol_offset() to protect external readers (lookup_symbol_name, kallsyms_lookup_buildid, reset_iter) against concurrent batch teardown (addresses Sashiko AI review). - In kallsyms_selftest, add a second lookup pass bracketed by kallsyms_lookup_batch_start() and kallsyms_lookup_batch_end() to validate batch resolution in the in-tree selftest. - Move 24-bit loop unrolling in get_symbol_seq() to standalone patch 4 (addresses David Laight review). - Move David Laight to series-wide Cc on cover letter, dropping trailer from this patch. Changes in v2: - Rework from static build-time 3-byte table to dynamic u32 index allocated in transient RAM during batch sessions, dropping +573 KiB from .rodata to 0 bytes (addresses Kees Cook review). - Use native u32 indexing to eliminate 24-bit big-endian shifts and unaligned loads (addresses David Laight review). - Revert changes to scripts/kallsyms.c and kernel/kallsyms_internal.h, retaining legacy kallsyms_markers[] as fallback. --- include/linux/kallsyms.h | 13 ++++++ kernel/kallsyms.c | 112 +++++++++++++++++++++++++++++++++++++++++= +--- kernel/kallsyms_selftest.c | 16 +++++++ lib/test_kallsyms_perf.c | 52 ++++++++++++++++++--- 4 files changed, 181 insertions(+), 12 deletions(-) diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h index d5dd54c53ace..6e39795ac509 100644 --- a/include/linux/kallsyms.h +++ b/include/linux/kallsyms.h @@ -74,6 +74,10 @@ int kallsyms_on_each_symbol(int (*fn)(void *, const char= *, unsigned long), int kallsyms_on_each_match_symbol(int (*fn)(void *, unsigned long), const char *name, void *data); =20 +/* Transient dynamic lookup index bracketing */ +int kallsyms_lookup_batch_start(void); +void kallsyms_lookup_batch_end(void); + /* Lookup the address for a symbol. Returns 0 if not found. */ unsigned long kallsyms_lookup_name(const char *name); =20 @@ -164,6 +168,15 @@ static inline int kallsyms_on_each_match_symbol(int (*= fn)(void *, unsigned long) { return -EOPNOTSUPP; } + +static inline int kallsyms_lookup_batch_start(void) +{ + return 0; +} + +static inline void kallsyms_lookup_batch_end(void) +{ +} #endif /*CONFIG_KALLSYMS*/ =20 static inline void print_ip_sym(const char *loglvl, unsigned long ip) diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index d18d78e626db..06c79ad70cfd 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -22,6 +22,9 @@ #include /* for cond_resched */ #include #include +#include +#include +#include #include #include #include @@ -90,7 +93,7 @@ static unsigned int kallsyms_expand_symbol(unsigned int o= ff, if (maxlen) *result =3D '\0'; =20 - /* Return to offset to the next symbol. */ + /* Return offset to the next symbol. */ return off; } =20 @@ -139,12 +142,11 @@ static int kallsyms_strcmp_symbol(unsigned int off, c= onst char *name) return (unsigned char)*name; } =20 - /* - * Find the offset on the compressed stream given and index in the - * kallsyms array. + * Find the offset on the compressed stream given an index in the + * kallsyms array using legacy markers. */ -static unsigned int get_symbol_offset(unsigned long pos) +static unsigned int get_symbol_offset_marker(unsigned long pos) { const u8 *name; int i, len; @@ -177,6 +179,100 @@ static unsigned int get_symbol_offset(unsigned long p= os) return name - kallsyms_names; } =20 +/* + * Dynamic symbol offset table. + * Allocated on demand during high-volume lookup batches and reclaimed aft= er. + */ +static u32 *dyn_kallsyms_offsets __read_mostly; +static DEFINE_MUTEX(dyn_kallsyms_mutex); +static unsigned int dyn_kallsyms_refcnt; + +static u32 *kallsyms_build_offsets(void) +{ + const u8 *name =3D kallsyms_names; + u32 *offsets; + unsigned int i; + + offsets =3D kvmalloc_array(kallsyms_num_syms, sizeof(u32), GFP_KERNEL); + if (!offsets) + return NULL; + + for (i =3D 0; i < kallsyms_num_syms; i++) { + unsigned int len; + const u8 *data; + + offsets[i] =3D name - kallsyms_names; + data =3D get_symbol_data(offsets[i], &len); + name =3D data + len; + } + + return offsets; +} + +int kallsyms_lookup_batch_start(void) +{ + int ret =3D 0; + + mutex_lock(&dyn_kallsyms_mutex); + if (!dyn_kallsyms_refcnt) { + u32 *offsets =3D kallsyms_build_offsets(); + + if (!offsets) { + ret =3D -ENOMEM; + goto out; + } + rcu_assign_pointer(dyn_kallsyms_offsets, offsets); + } + dyn_kallsyms_refcnt++; +out: + mutex_unlock(&dyn_kallsyms_mutex); + return ret; +} +EXPORT_SYMBOL_GPL(kallsyms_lookup_batch_start); + +void kallsyms_lookup_batch_end(void) +{ + u32 *offsets =3D NULL; + + mutex_lock(&dyn_kallsyms_mutex); + if (WARN_ON(!dyn_kallsyms_refcnt)) + goto out; + + if (--dyn_kallsyms_refcnt =3D=3D 0) { + offsets =3D dyn_kallsyms_offsets; + rcu_assign_pointer(dyn_kallsyms_offsets, NULL); + } +out: + mutex_unlock(&dyn_kallsyms_mutex); + + if (offsets) { + synchronize_rcu(); + kvfree(offsets); + } +} +EXPORT_SYMBOL_GPL(kallsyms_lookup_batch_end); + +/* + * Find the offset on the compressed table given an index in the + * kallsyms array. + */ +static inline unsigned int get_symbol_offset(unsigned long pos) +{ + unsigned int off; + u32 *offsets; + + rcu_read_lock(); + offsets =3D rcu_dereference(dyn_kallsyms_offsets); + if (offsets) { + off =3D offsets[pos]; + rcu_read_unlock(); + return off; + } + rcu_read_unlock(); + + return get_symbol_offset_marker(pos); +} + unsigned long kallsyms_sym_address(int idx) { /* non-relocatable 32-bit kernels just embed the value directly */ @@ -206,6 +302,7 @@ static int kallsyms_lookup_names(const char *name, low =3D 0; high =3D kallsyms_num_syms - 1; =20 + rcu_read_lock(); while (low <=3D high) { mid =3D low + (high - low) / 2; seq =3D get_symbol_seq(mid); @@ -219,8 +316,10 @@ static int kallsyms_lookup_names(const char *name, break; } =20 - if (low > high) + if (low > high) { + rcu_read_unlock(); return -ESRCH; + } =20 low =3D mid; while (low) { @@ -243,6 +342,7 @@ static int kallsyms_lookup_names(const char *name, } *end =3D high; } + rcu_read_unlock(); =20 return 0; } diff --git a/kernel/kallsyms_selftest.c b/kernel/kallsyms_selftest.c index 8f6c4e9b3a1c..aedffc058c0e 100644 --- a/kernel/kallsyms_selftest.c +++ b/kernel/kallsyms_selftest.c @@ -178,6 +178,7 @@ static int lookup_name(void *data, const char *name, un= signed long addr) static void test_perf_kallsyms_lookup_name(void) { struct test_stat stat; + int ret; =20 memset(&stat, 0, sizeof(stat)); stat.min =3D INT_MAX; @@ -185,6 +186,21 @@ static void test_perf_kallsyms_lookup_name(void) pr_info("kallsyms_lookup_name() looked up %d symbols\n", stat.real_cnt); pr_info("The time spent on each symbol is (ns): min=3D%d, max=3D%d, avg= =3D%lld\n", stat.min, stat.max, div_u64(stat.sum, stat.real_cnt)); + + ret =3D kallsyms_lookup_batch_start(); + if (ret) { + pr_err("kallsyms_lookup_batch_start() failed: %d\n", ret); + return; + } + + memset(&stat, 0, sizeof(stat)); + stat.min =3D INT_MAX; + kallsyms_on_each_symbol(lookup_name, &stat); + kallsyms_lookup_batch_end(); + + pr_info("kallsyms_lookup_name() (batch) looked up %d symbols\n", stat.rea= l_cnt); + pr_info("The time spent on each symbol is (ns): min=3D%d, max=3D%d, avg= =3D%lld\n", + stat.min, stat.max, div_u64(stat.sum, stat.real_cnt)); } =20 static int find_symbol(void *data, const char *name, unsigned long addr) diff --git a/lib/test_kallsyms_perf.c b/lib/test_kallsyms_perf.c index 4d0c39c0a94f..6f74ade4a018 100644 --- a/lib/test_kallsyms_perf.c +++ b/lib/test_kallsyms_perf.c @@ -61,7 +61,7 @@ static int count_cb(void *data, const char *name, unsigne= d long addr) return 0; } =20 -static void run_name_lookup_bench(void) +static void run_name_lookup_bench(const char *mode, u64 *avg_hit_ns, u64 *= avg_miss_ns) { u64 t0, t1, dt_hit, dt_miss; unsigned long addr =3D 0; @@ -117,10 +117,15 @@ static void run_name_lookup_bench(void) t1 =3D ktime_get_ns(); dt_miss =3D t1 - t0; =20 - pr_info("Name Search Hit: %llu ns/lookup (%llu ms total, %u iters)\n", - div_u64(dt_hit, num_iters), div_u64(dt_hit, 1000000), num_iters); - pr_info("Name Search Miss: %llu ns/lookup (%llu ms total, %u iters)\n", - div_u64(dt_miss, num_iters), div_u64(dt_miss, 1000000), num_iters); + if (avg_hit_ns) + *avg_hit_ns =3D div_u64(dt_hit, num_iters); + if (avg_miss_ns) + *avg_miss_ns =3D div_u64(dt_miss, num_iters); + + pr_info("[%s] Name Search Hit: %llu ns/lookup (%llu ms total, %u iters)\= n", + mode, div_u64(dt_hit, num_iters), div_u64(dt_hit, 1000000), num_iters); + pr_info("[%s] Name Search Miss: %llu ns/lookup (%llu ms total, %u iters)\= n", + mode, div_u64(dt_miss, num_iters), div_u64(dt_miss, 1000000), num_iters); } =20 static void run_address_lookup_bench(void) @@ -199,6 +204,11 @@ static void run_table_walk_bench(void) =20 static int run_kallsyms_benchmark(void) { + u64 unindexed_hit =3D 0, unindexed_miss =3D 0; + u64 dyn_hit =3D 0, dyn_miss =3D 0; + u64 t0, t1, dt_start =3D 0, dt_end =3D 0; + int ret; + if (!num_iters) { pr_err("num_iters must be non-zero\n"); return -EINVAL; @@ -208,7 +218,37 @@ static int run_kallsyms_benchmark(void) pr_info("Starting kallsyms performance benchmark (iters=3D%u)\n", num_ite= rs); pr_info("=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D\n"); =20 - run_name_lookup_bench(); + /* 1. Benchmark baseline unindexed marker scan */ + run_name_lookup_bench("Unindexed (markers)", &unindexed_hit, &unindexed_m= iss); + + /* 2. Benchmark dynamic lookup index */ + t0 =3D ktime_get_ns(); + ret =3D kallsyms_lookup_batch_start(); + t1 =3D ktime_get_ns(); + dt_start =3D t1 - t0; + + if (ret) { + pr_err("Failed to start kallsyms lookup batch: %d\n", ret); + } else { + run_name_lookup_bench("Dynamic Index", &dyn_hit, &dyn_miss); + + t0 =3D ktime_get_ns(); + kallsyms_lookup_batch_end(); + t1 =3D ktime_get_ns(); + dt_end =3D t1 - t0; + + pr_info("[Dynamic Index] Batch setup: %llu us, teardown: %llu us\n", + div_u64(dt_start, 1000), div_u64(dt_end, 1000)); + + if (unindexed_hit > dyn_hit) { + u64 saved =3D unindexed_hit - dyn_hit; + + pr_info("[Dynamic Index] Amortization break-even: %llu queries (setup),= %llu queries (total)\n", + DIV_ROUND_UP_ULL(dt_start, saved), + DIV_ROUND_UP_ULL(dt_start + dt_end, saved)); + } + } + run_address_lookup_bench(); run_table_walk_bench(); =20 --=20 2.55.0 From nobody Thu Sep 24 15:10:57 2026 Received: from mail-oi2-f13.google.com (mail-oi2-f13.google.com [74.125.231.205]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1CA79497B9B for ; Tue, 22 Sep 2026 18:46:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.231.205 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790102778; cv=none; b=FrpQ4MqvfNy3rLwAx7Mkd1ARwoLzAJzPx4aiEd4zI/12PHuP8mMeUEeun/vMeGB31MjQx1Vcv3Ck4XdcnlfGMHomiqPp63SQWNF9zKDmst565m+9GJGVXSfm6fnVBkq+cQLAHWsNOEq0YS6rJLeBY4idolvt3fCLnYfLECr7hNU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790102778; c=relaxed/simple; bh=IuMpNgCx/wsRt/giACaxjy53WAUkwMR2mJuQ09sqhYU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SyP02XrefqdzpNhpzrK6V47GjclmgsTAGe7Nte3SgyfyYyuRvlWsd5tQVzOj6CAGMCdbK16LWlbpUyLCOo7MFb+uTY2FzsnqVznzoiLd9sYR+ExG16EK+1G+S9KJYPKzUtg8Xv1lk3yv+bFVyPXummTPBV7+kX9cxEj5Drt+C+g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=scCWnbb0; arc=none smtp.client-ip=74.125.231.205 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="scCWnbb0" Received: by mail-oi2-f13.google.com with SMTP id 5614622812f47-4b37a2c0356so157462b6e.2 for ; Tue, 22 Sep 2026 11:46:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790102769; x=1790707569; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=hvBW23f2UuBKO8svIifjsjiemFC1LwQ9bznHBbhEXQs=; b=scCWnbb0xhmsAtCfiaPQQ/PnR491Vl9Mgp36n3EjZOAeN9cpUrfc6YlI267aUQCQ+h Ycdr4njzS5rjrgnwDOVR2u8jSHx37FCQKlvJwxrwQgMqxjsbEuUsoAeFZDG3MY225Yhh ePDF3gnibux7M5Yz8RM77vJJ5iNtUA6AQs3OtCPKLlxZXqz5nmWyfYo+TlTyvUx24bZm PyWcj0GMGeogWSYhj4XvUumq5wkHOk9RhXGT/ctW1YMeEZEJDly5TqHf4U8o8KR4ytxG L1I9c4pt/BvCTUhWeA9qeIc7M3m0aQYq1X7vM3eR/FxIxkOLZgauIrDm+DOdLQ4IY4cW PDEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790102769; x=1790707569; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=hvBW23f2UuBKO8svIifjsjiemFC1LwQ9bznHBbhEXQs=; b=wg/gwpe4tXKNPKBZWdqSVwAwLYU2WldzZm8kdY5DP0ublyPlmzqY6MTon8VN/30qc4 F2RWNcL9zLeC+harHXSENk5IyPOEdrdFKOoZayH//xovvqMRstsZIe7h/ld9ye42Fq8k 3mzjRkQgEKy/K2KBh9EAep4cr/I2y+bx86ehfyf6MtpLRpxsZD5+JiCW8b7PPZjHr1ZY SLltgdNGRQqFRp5RIe+SWMwcS7dSik4ktF6jVVg/yeQ5Wd5U8APILQeR+vA2SLOSncSD QTbK03wJ5lyIIVA7irgIy1zpwxWPEHMZ5DS4NTWKRZkEEyt6Grhj2VPDRG7ALVLd2OML +Hhg== X-Forwarded-Encrypted: i=1; AKwUvBxJYz5fsCgL2gx27vod57NmT33VWCz4kpLCq5YdiWZXc4lpBNwgxFf4B6RtCo65PFJVSU++x2JPvaH7RTM=@vger.kernel.org X-Gm-Message-State: AFuF++m+nxlb2LyJ2f0aWzgBV4/Vwk3zAMZA9xZKWA4Q/fWOgWecHO4s 0velSpnYtQIIpzPntJRtMikWbej++BsZKWgp4XnMoia0VjA/QWKDgIpY X-Gm-Gg: AYBFou0bH+u2R15S0SlyJjG0qCoXIitC45EbFfNmHIRdP/EPWagcGVtP8ovCcM3jI4g ++9Ds4w7cNcJtIsstuqMW5UDwzJUmkewxCIikEgUJZ9sF0zhgob9SqJXJtkESeppgHCHjuiaW54 8QsXBilbeT1HE4kts77RDIEXLgIVNngR5X4WiOhcUpRclBCUORs94u5Y/4c31NzNsg7OwW56Pp/ P1YDB/SOdYlxthUlClhQRYOmX5F3GJ0AznLr+K9Ewe/3V/ZLDkSlTmbf/jbuGNTVEo9X4l7Yini I/ydSgzJwa5JsKacpjK2qaerCFttITzGZz4iKaRJSxaxdIsUeKZIbnfPKDXClC/STs21TaoU3WO YKrDf9cc6hrYpPVewcoMP+8bllXVCaVv/8AthsT3CxBwNkhoaSCd0VIg4htIUmkCws09H/GKH/8 pQpf9rwVju2ato0RWuWo4wEZbUUeXoVX6ypOykfE0IBzKd+174dQNfw1mrvOxL8SXKqTxL3rHCW J/vH+yiJR6uyJJaxATDDS3x7dsothvjQmEMmaDWHKofSWKJqzVEkbbC2vrH7Ns3QBWSsUGkslCM YT/MTtkx6TMoIHlW4j4TZ8Q+P2HrUnI= X-Received: by 2002:a05:6808:14d1:b0:4b9:e65b:8c33 with SMTP id 5614622812f47-4d5b8cd7d75mr333208b6e.33.1790102768645; Tue, 22 Sep 2026 11:46:08 -0700 (PDT) Received: from [100.82.231.29] (c-98-38-17-99.hsd1.co.comcast.net. [98.38.17.99]) by smtp.googlemail.com with ESMTPSA id 5614622812f47-4d5c43a24bbsm147545b6e.7.2026.09.22.11.46.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Sep 2026 11:46:08 -0700 (PDT) From: Jim Cromie Date: Tue, 22 Sep 2026 12:45:58 -0600 Subject: [PATCH v3 4/4] kallsyms: Unroll 24-bit sequence reconstruction in get_symbol_seq() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260922-ksyms-tune-v3-4-681a34ea05d9@gmail.com> References: <20260922-ksyms-tune-v3-0-681a34ea05d9@gmail.com> In-Reply-To: <20260922-ksyms-tune-v3-0-681a34ea05d9@gmail.com> To: Andrew Morton Cc: Lorenzo Stoakes , Kees Cook , David Laight , Masahiro Yamada , linux-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org, bpf@vger.kernel.org, Jim Cromie X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1790102761; l=1647; i=jim.cromie@gmail.com; s=20260203; h=from:subject:message-id; bh=IuMpNgCx/wsRt/giACaxjy53WAUkwMR2mJuQ09sqhYU=; b=yS/yGjzOac4hLV4AjSFZ5EelcHRPIABxP3zNa55tRBvDMQ9hjwXNYUKY/aAcVbDC1o5X/qkv+ VdoviOApkczAe37evfvRkm/lYAf+lj76e/eHBTzZCKBe70sD1vYOqhi X-Developer-Key: i=jim.cromie@gmail.com; a=ed25519; pk=C6E5ODlPQo7ZBynATXH9wg7K6HxP0pIXyf4s38Qw0XE= kallsyms_seqs_of_names[] stores 3-byte big-endian sequence indices that map alphabetical symbol positions to address-ordered symbol records. Currently, get_symbol_seq() reconstructs each 24-bit integer using a 3-iteration for-loop that shifts and bitwise-ORs each byte sequentially. During binary search in kallsyms_lookup_names() and duplicate boundary scans, this loop introduces branch and loop overhead on the hot lookup path. Mark get_symbol_seq() as static inline and unroll the 3-byte extraction into direct byte shifts: (p[0] << 16) | (p[1] << 8) | p[2]. This eliminates loop induction variable maintenance and allows the compiler to generate direct loads and constant shifts. Signed-off-by: Jim Cromie --- Changes in v3: - Added as a standalone micro-optimization patch (addresses David Laight review). --- kernel/kallsyms.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index 06c79ad70cfd..8f76403e0e7b 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -281,14 +281,11 @@ unsigned long kallsyms_sym_address(int idx) return (unsigned long)offset_to_ptr(kallsyms_offsets + idx); } =20 -static unsigned int get_symbol_seq(int index) +static inline unsigned int get_symbol_seq(int index) { - unsigned int i, seq =3D 0; + const u8 *p =3D &kallsyms_seqs_of_names[3 * index]; =20 - for (i =3D 0; i < 3; i++) - seq =3D (seq << 8) | kallsyms_seqs_of_names[3 * index + i]; - - return seq; + return (p[0] << 16) | (p[1] << 8) | p[2]; } =20 static int kallsyms_lookup_names(const char *name, --=20 2.55.0