Re: [PATCH 0/3] zstd: probe the CPU for BMI2 support once, not per context
From: Nhat Pham
Date: Wed Aug 26 2026 - 13:18:14 EST
On Wed, Aug 26, 2026 at 5:26 AM Usama Arif <usama.arif@xxxxxxxxx> 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
Awesome! I'm no zstd expert, but this looks very nice. Thanks for
fixing it. I'll defer mostly to Nick (is the fb.com email still
working?) and Herbert for correctness checking.
BTW, I think this has been reported in the past:
https://lore.kernel.org/all/CAJxJ_jhvyMukPLThpgcdCMHwbp3b3bFvc4Va1cK79_3z6ubhwQ@xxxxxxxxxxxxxx/