Skip to content

Comments

kallsyms: introduce 'reader', an efficient /proc/kallsyms line parser#1588

Merged
ti-mo merged 2 commits intocilium:mainfrom
ti-mo:tb/kallsyms-reader
Oct 17, 2024
Merged

kallsyms: introduce 'reader', an efficient /proc/kallsyms line parser#1588
ti-mo merged 2 commits intocilium:mainfrom
ti-mo:tb/kallsyms-reader

Conversation

@ti-mo
Copy link
Contributor

@ti-mo ti-mo commented Oct 17, 2024

This commit introduces kallsyms.reader, meant to address the performance
concerns caused by fmt.Sscanf and bytes.Fields. Both of these options
allocate heavily and aren't flexible in terms of avoiding unnecessary
work like skipping the remainder of a line if we're not interested in
the remainder of its contents.

This approach borrows the implementation for reader.Word() from
bufio.ScanWords, paying attention to handling utf-8 characters correctly.
Kernel modules (out-of-tree, at least) can contain international symbols
in exported global kernel variables, which show up in /proc/kallsyms. We
need to err on the side of caution since this is technically user input
that's beyond our control.

This commit renames kallsyms.LoadSymbolAddresses to AssignAddresses and
kallsyms.KernelModule to SymbolModule respectively. Both implementations
have been changed to use kallsyms.reader.

                   │   old.txt   │              new.txt               │
                   │   sec/op    │   sec/op     vs base               │
SymbolKmods-16       246.6m ± 1%   281.5m ± 2%  +14.16% (p=0.002 n=6)
AssignAddresses-16   734.9m ± 1%   299.4m ± 1%  -59.26% (p=0.002 n=6)
geomean              425.7m        290.3m       -31.80%

                   │    old.txt    │               new.txt               │
                   │     B/op      │     B/op      vs base               │
SymbolKmods-16        39.81Mi ± 0%   15.81Mi ± 0%  -60.27% (p=0.002 n=6)
AssignAddresses-16   60.622Mi ± 0%   9.881Mi ± 0%  -83.70% (p=0.002 n=6)
geomean               49.12Mi        12.50Mi       -74.55%

                   │   old.txt    │              new.txt               │
                   │  allocs/op   │  allocs/op   vs base               │
SymbolKmods-16        477.4k ± 0%   266.5k ± 0%  -44.18% (p=0.002 n=6)
AssignAddresses-16   2653.0k ± 0%   462.7k ± 0%  -82.56% (p=0.002 n=6)
geomean               1.125M        351.2k       -68.80%

The SymbolKmods-16 wall clock time took a small hit because bytes.Fields
has an ASCII fast-path. Still worth it in the bigger picture since the
allocation pressure dropped by a significant amount to compensate, and
future work will change how the caching layer works for both AssignAddresses
and SymbolModule.

cc @alban @patrickpichler

ti-mo added 2 commits October 17, 2024 09:42
This commit introduces kallsyms.reader, meant to address the performance
concerns caused by fmt.Sscanf and bytes.Fields. Both of these options
allocate heavily and aren't flexible in terms of avoiding unnecessary
work like skipping the remainder of a line if we're not interested in
the remainder of its contents.

This approach borrows the implementation for reader.Word() from
bufio.ScanWords, paying attention to handling utf-8 characters correctly.
Kernel modules (out-of-tree, at least) can contain international symbols
in exported global kernel variables, which show up in /proc/kallsyms. We
need to err on the side of caution since this is technically user input
that's beyond our control.

This commit renames kallsyms.LoadSymbolAddresses to AssignAddresses and
kallsyms.KernelModule to SymbolModule respectively. Both implementations
have been changed to use kallsyms.reader.

                   │   old.txt   │              new.txt               │
                   │   sec/op    │   sec/op     vs base               │
SymbolKmods-16       246.6m ± 1%   281.5m ± 2%  +14.16% (p=0.002 n=6)
AssignAddresses-16   734.9m ± 1%   299.4m ± 1%  -59.26% (p=0.002 n=6)
geomean              425.7m        290.3m       -31.80%

                   │    old.txt    │               new.txt               │
                   │     B/op      │     B/op      vs base               │
SymbolKmods-16        39.81Mi ± 0%   15.81Mi ± 0%  -60.27% (p=0.002 n=6)
AssignAddresses-16   60.622Mi ± 0%   9.881Mi ± 0%  -83.70% (p=0.002 n=6)
geomean               49.12Mi        12.50Mi       -74.55%

                   │   old.txt    │              new.txt               │
                   │  allocs/op   │  allocs/op   vs base               │
SymbolKmods-16        477.4k ± 0%   266.5k ± 0%  -44.18% (p=0.002 n=6)
AssignAddresses-16   2653.0k ± 0%   462.7k ± 0%  -82.56% (p=0.002 n=6)
geomean               1.125M        351.2k       -68.80%

The SymbolKmods-16 wall clock time took a small hit because bytes.Fields
has an ASCII fast-path. Still worth it in the bigger picture since the
allocation pressure dropped by a significant amount to compensate, and
future work will change how the caching layer works for both AssignAddresses
and SymbolModule.

Signed-off-by: Timo Beckers <[email protected]>
@alban
Copy link
Contributor

alban commented Jan 20, 2025

Hi @ti-mo,
Do you think the kallsyms package could be moved outside of "internal"?
I'm checking if the reader can be reused for some parts in github.com/inspektor-gadget/inspektor-gadget/pkg/kallsyms.

@ti-mo
Copy link
Contributor Author

ti-mo commented Feb 17, 2025

@alban I'm considering it, I'd like to use it for another project that I currently have no time to work on. Feel free to copy it in the meantime, you'll hear about it if we ever end up exporting it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants