Hi Sasha, On 3/11/26 22:49, Sasha Levin wrote: > Thanks for the review! > > On Wed, Mar 11, 2026 at 11:34:24AM +0800, Vivian Wang wrote: >> Hi Sasha, >> >> I've been trying this out and AFAICT this does work perfectly. Thank you >> for this. >> >> There are a few oddities I found: >> >> Firstly I've been building with something like O=_riscv out of >> convenience, and the file names have an extra ../ in the front. (This is >> just me exiting out of init=/bin/sh.) >> [ 2.317268] Kernel panic - not syncing: Attempted to kill init! >> exitcode=0x00000000 >> [ 2.320283] CPU: 0 UID: 0 PID: 1 Comm: sh Not tainted >> 7.0.0-rc3-00004-g8ad18f1a1a2f #31 PREEMPTLAZY >> [ 2.322048] Hardware name: riscv-virtio,qemu (DT) >> [ 2.323220] Call Trace: >> [ 2.324465] [<ffffffff800172a8>] dump_backtrace+0x1c/0x24 >> (../arch/riscv/kernel/stacktrace.c:150) >> [ 2.329061] [<ffffffff8000241e>] show_stack+0x2a/0x34 >> (../arch/riscv/kernel/stacktrace.c:156) >> [ 2.330334] [<ffffffff8000fe32>] dump_stack_lvl+0x4a/0x68 >> (../lib/dump_stack.c:122) >> [ 2.331462] [<ffffffff8000fe64>] dump_stack+0x14/0x1c >> (../lib/dump_stack.c:130) >> [ 2.332571] [<ffffffff80002a88>] vpanic+0x108/0x2bc >> (../kernel/panic.c:651) >> [ 2.333674] [<ffffffff80002c6e>] panic+0x32/0x34 (../kernel/panic.c:787) >> [ 2.334427] [<ffffffff8002e97a>] do_exit+0x7ee/0x7f4 >> (../kernel/exit.c:930) >> [ 2.335194] [<ffffffff8002eade>] do_group_exit+0x1a/0x88 >> (../kernel/exit.c:1099) >> [ 2.335945] [<ffffffff8002eb62>] __riscv_sys_exit_group+0x16/0x18 >> (../kernel/exit.c:1129) >> [ 2.336763] [<ffffffff80b3e868>] do_trap_ecall_u+0x260/0x45c >> (../arch/riscv/include/asm/syscall.h:112) >> [ 2.337765] [<ffffffff80b4c034>] handle_exception+0x168/0x174 >> (../arch/riscv/kernel/entry.S:233) >> This is fine by me, but I've seen mentions of O= builds but I'm not sure >> if it's expected. > > Could you try v2 and see if it makes it prettier? I tried to tackle > this :)
Thanks, I'll try it out and see. > >> Also, toggling CONFIG_KALLSYMS_LINEINFO seems to rebuild every single >> file. I haven't debugged why, but is this expected? > > I think that this is because we increase KSYM_SYMBOL_LEN when lineinfo is > enabled. I suppose we can just increase the size irregardless of whether > lineinfo is enabled and ignore the waste? > > Or, folks really won't be toggling this option too often for the > rebuilds to > matter too much, so we can just enjoy the savings? Yeah I understand now. The size affects some fundamental headers. I just thought it was odd. The current situation is fine by me - if I'm building a kernel and toggling configs, it means I have the vmlinux file and can use scripts/decode_stacktrace.sh :) >> I have a few ideas about the code as well. Since this patch 3 touches >> most of the files involved, I'll just dump my thoughts on the whole >> series here. I want to note that I haven't read the RFC thread too >> carefully, but I don't think there were many comments on the >> implementation. >> >> On 3/4/26 02:21, Sasha Levin wrote: >>> Replace the flat uncompressed parallel arrays (lineinfo_addrs[], >>> lineinfo_file_ids[], lineinfo_lines[]) with a block-indexed, >>> delta-encoded, ULEB128 varint compressed format. >>> >>> The sorted address array has small deltas between consecutive entries >>> (typically 1-50 bytes), file IDs have high locality (delta often 0, >>> same file), and line numbers change slowly. Delta-encoding followed >>> by ULEB128 varint compression shrinks most values from 4 bytes to 1. >>> >>> Entries are grouped into blocks of 64. A small uncompressed block >>> index (first addr + byte offset per block) enables O(log(N/64)) binary >>> search, followed by sequential decode of at most 64 varints within the >>> matching block. All decode state lives on the stack -- zero >>> allocations, still safe for NMI/panic context. >>> >>> Measured on a defconfig+debug x86_64 build (3,017,154 entries, 4,822 >>> source files, 47,144 blocks): >>> >>> Before (flat arrays): >>> lineinfo_addrs[] 12,068,616 bytes (u32 x 3.0M) >>> lineinfo_file_ids[] 6,034,308 bytes (u16 x 3.0M) >>> lineinfo_lines[] 12,068,616 bytes (u32 x 3.0M) >>> Total: 30,171,540 bytes (28.8 MiB, 10.0 bytes/entry) >>> >>> After (block-indexed delta + ULEB128): >>> lineinfo_block_addrs[] 188,576 bytes (184 KiB) >>> lineinfo_block_offsets[] 188,576 bytes (184 KiB) >>> lineinfo_data[] 10,926,128 bytes (10.4 MiB) >>> Total: 11,303,280 bytes (10.8 MiB, 3.7 bytes/entry) >>> >>> Savings: 18.0 MiB (2.7x reduction) >>> >>> Booted in QEMU and verified with SysRq-l that annotations still work: >>> >>> default_idle+0x9/0x10 (arch/x86/kernel/process.c:767) >>> default_idle_call+0x6c/0xb0 (kernel/sched/idle.c:122) >>> do_idle+0x335/0x490 (kernel/sched/idle.c:191) >>> cpu_startup_entry+0x4e/0x60 (kernel/sched/idle.c:429) >>> rest_init+0x1aa/0x1b0 (init/main.c:760) >>> >>> Suggested-by: Juergen Gross <[email protected]> >>> Assisted-by: Claude:claude-opus-4-6 >>> Signed-off-by: Sasha Levin <[email protected]> >>> --- >>> .../admin-guide/kallsyms-lineinfo.rst | 7 +- >>> include/linux/mod_lineinfo.h | 103 ++++++++-- >>> init/Kconfig | 8 +- >>> kernel/kallsyms.c | 91 +++++++-- >>> kernel/kallsyms_internal.h | 7 +- >>> kernel/module/kallsyms.c | 107 +++++++--- >>> scripts/gen_lineinfo.c | 192 ++++++++++++++---- >>> scripts/kallsyms.c | 7 +- >>> scripts/link-vmlinux.sh | 16 +- >>> 9 files changed, 423 insertions(+), 115 deletions(-) >>> >>> diff --git a/Documentation/admin-guide/kallsyms-lineinfo.rst >>> b/Documentation/admin-guide/kallsyms-lineinfo.rst >>> index 21450569d5324..fe92c5dde16b3 100644 >>> --- a/Documentation/admin-guide/kallsyms-lineinfo.rst >>> +++ b/Documentation/admin-guide/kallsyms-lineinfo.rst >>> @@ -76,10 +76,11 @@ Memory Overhead >>> =============== >>> >>> The vmlinux lineinfo tables are stored in ``.rodata`` and typically add >>> -approximately 44 MiB to the kernel image for a standard configuration >>> -(~4.6 million DWARF line entries, ~10 bytes per entry after deduplication). >>> +approximately 10-15 MiB to the kernel image for a standard configuration >>> +(~4.6 million DWARF line entries, ~2-3 bytes per entry after delta >>> +compression). >>> >>> -Per-module lineinfo adds approximately 10 bytes per DWARF line entry to >>> each >>> +Per-module lineinfo adds approximately 2-3 bytes per DWARF line entry to >>> each >>> ``.ko`` file. >> >> Maybe this could be given in terms of percentages? It wasn't obvious to >> me what 10-15 MiB amounts to. >> >> On riscv64, I'm seeing a 24.2 MiB to 30.2 MiB increase in >> arch/riscv/boot/Image size on an approximately defconfig+mod2noconfig >> build, which is about a 25% increase. I haven't checked yet, but if 25% >> is similar to what other archs get, that's a more useful figure than >> 10-15 MiB, given that the size increase is correlated to the total >> amount of code linked into the kernel/module. > > I ended up giving an example instead of percentages because it seemed > to vary > wildly between configs and archs. For example, defconfig on x86 yields > a 15% > increase compared to the 25% you see with your config on riscv, > compared to a > 39% increase with defconfig on riscv. That's fair. I guess it also depends on arch code density and compiler codegen. [...] >>> +/* >>> + * Read a ULEB128 varint from a byte stream. >>> + * Returns the decoded value and advances *pos past the encoded bytes. >>> + * If *pos would exceed 'end', returns 0 and sets *pos = end (safe for >>> + * NMI/panic context -- no crash, just a missed annotation). >> >> What does that last bit mean...? > > This goes back to your previous point about correctness and checks in the > lineinfo code :) > > It just means that this function never faults or allocates. On bad > input it > returns 0, so the worst case is a missing annotation, not a crash. Ah, right, it didn't occur to me it was "annotation" as in the lineinfo annotation in the stack trace. I thought it was something like noinstr or lockdep stuff at first. This checks out. Vivian "dramforever" Wang

