Re: [PATCH 0/3] zstd: probe the CPU for BMI2 support once, not per context
From: Eric Biggers
Date: Wed Aug 26 2026 - 22:41:59 EST
On Wed, Aug 26, 2026 at 05:25:35AM -0700, Usama Arif wrote:
> zstd picks between BMI2 and generic code paths at runtime, and issues
> CPUID to decide every time a compression or decompression context is set
> up. The answer cannot change while the kernel is running.
>
> It is not a cold path: squashfs calls zstd_init_dstream() for every block
> it decompresses, and erofs, btrfs, f2fs and crypto/zstd all initialise a
> context per operation. Each probe is two serializing CPUID instructions
> on x86.
>
> Patch 1 routes ZSTD_initStaticCCtx() through ZSTD_cpuSupportsBmi2()
> instead of open-coding the probe, which also fixes it testing for BMI2
> without BMI1 - the bodies it selects are tagged
> TARGET_ATTRIBUTE("lzcnt,bmi,bmi2"), so both are needed. No CPU in the
> field implements BMI2 without BMI1, so this is latent. Patch 2 skips the
> probe when DYNAMIC_BMI2 is 0, where every consumer ignores the flag
> anyway. Patch 3 caches the result.
>
> A 4 KiB crypto_acomp benchmark [1] in a one-vCPU KVM guest, twelve boots
> of nine 30,000-operation rounds, median per-round mean over 108 rounds:
>
> compress decompress
> unpatched 16,756 ns 3,455 ns
> patched 13,646 ns 1,002 ns
> -3,110 ns -2,452 ns
> (18.6%) (71.0%)
>
> The main reason is because CPUID is an unconditional VM exit.
>
> [1] https://gist.github.com/uarif1/5cf02f0e22c23f0d1b3d84348f12914c
>
> Usama Arif (3):
> zstd: use ZSTD_cpuSupportsBmi2() in ZSTD_initStaticCCtx()
> zstd: skip the BMI2 probe when dynamic BMI2 dispatch is disabled
> zstd: probe the CPU for BMI2 support only once
>
> lib/zstd/common/zstd_internal.h | 22 ++++++++++++++++++++--
> lib/zstd/compress/zstd_compress.c | 2 +-
> 2 files changed, 21 insertions(+), 3 deletions(-)
Why not just use cpu_feature_enabled(X86_FEATURE_BMI2), which compiles
down to a static branch? All these issues are caused by lib/zstd/ using
its own custom CPU feature detection code, instead of the normal CPU
feature detection code that the rest of the kernel uses.
- Eric