Re: [PATCH 0/3] zstd: probe the CPU for BMI2 support once, not per context
From: Usama Arif
Date: Thu Aug 27 2026 - 10:27:25 EST
On 27/08/2026 03:39, Eric Biggers wrote:
> 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
The only issue I saw with that was that zstd is a standalone library that
is imported, so I am not sure how using cpu_feature_enabled() would work
for the maintainers. If the maintainers are happy with it, I think the
below patch is much better.