A three patch series posted to the Linux kernel mailing list on Wednesday, August twenty sixth, 2026 makes in-kernel zstd substantially faster by removing work that never needed doing twice. The kernel's zstd code checks at run time whether the processor supports BMI2 instructions, and it performs that check every single time a compression or decompression context is created. Usama Arif's patches probe once instead. On a crypto_acomp benchmark the result was a seventy one percent reduction in decompression time and an eighteen percent reduction in compression time. SquashFS, EROFS, Btrfs and F2FS are all affected, and virtualised systems most of all.
The short answer
Usama Arif posted a three patch series to the Linux kernel mailing list on August 26, 2026 that stops in-kernel zstd from re-detecting BMI2 processor support every time a compression or decompression context is created. The existing code path triggers two serialising CPUID instructions with unconditional VM exits, on every context. SquashFS does this for every block it decompresses, and EROFS, Btrfs and F2FS all create a context per operation. Probing once gave a 71 percent reduction in decompression time and 18 percent in compression time. The patches are under review and not yet merged.
Your processor is not going to lose BMI2 support while the machine is running. The kernel has been checking anyway, on every single zstd context it creates, and it turns out that check was costing rather a lot.
The bug that is not a bug
The in-kernel zstd library ships two code paths for entropy decoding: a generic one, and one that uses BMI2 bit manipulation instructions. BMI2 arrived with Intel Haswell in 2013 and AMD Excavator in 2015, and a single kernel image has to boot on hardware older than both, so choosing between the paths at run time is the right call.
The mistake is subtler. That choice is made inside context creation, which means it runs again for every context. And CPU feature support is not a property that changes between one context and the next.
Nothing here is incorrect. The code produces the right answer every time. It just produces it several million times more often than the question is asked.
Why a capability check turns into real time
Two things make CPUID unusually expensive for what it is.
The first is that CPUID is a serialising instruction. It drains the pipeline and forces the processor to abandon the out of order execution that carries most of its performance. Measured in cycles rather than instructions, it is far heavier than it looks.
The second is the one that matters in 2026: under virtualisation, CPUID causes an unconditional VM exit. The guest traps to the hypervisor, the hypervisor services the instruction, control returns. That round trip is orders of magnitude more expensive than any arithmetic the surrounding code is doing. The reported path fires two serialising CPUID instructions per context creation, so a virtual machine pays that cost twice, every time, forever.
Now count the contexts. SquashFS creates one for every block it decompresses, and SquashFS blocks are small by design. EROFS, Btrfs and F2FS each initialise a context per operation. On a container host reading a SquashFS or EROFS image inside a guest, the pattern is close to worst case: tiny units of work, high context churn, and a hypervisor exit stapled to each one.
The measurement, and how much of it to believe
The figures come from a crypto_acomp benchmark: a seventy one percent reduction in decompression time and an eighteen percent reduction in compression time.
The asymmetry between those two numbers is the part that makes the result credible. Compressing is genuinely hard work, so a fixed per context overhead is a small fraction of it and removing that overhead moves the total by eighteen percent. Decompressing zstd is fast, which means the same fixed overhead is a much larger share of the total, and removing it moves the number by seventy one percent. That is exactly the shape you would expect if the diagnosis is right.
It is also why you should not expect seventy one percent on your own storage. crypto_acomp exercises the compression path through the kernel crypto API with very little around it, which is ideal for isolating this overhead and unrepresentative of a running system. A real read does storage I/O, page allocation, and copies, all of which dilute the improvement. The gain will be largest where blocks are smallest and the machine is virtualised, and modest on a Btrfs volume doing large sequential reads on bare metal.
It fits a pattern the kernel has been having a good year at
There has been a run of changes lately that find large numbers by deleting redundant work rather than by adding cleverness. Btrfs in Linux 7.3 doubling direct I/O throughput and speeding fsync fivefold, a 705 millisecond KSM stall cut to 1.67 milliseconds, and Torvalds tracing an Xe black screen to a single round_up call all have the same character: a small, long standing assumption that stopped being true or never was, sitting on a hot path where nobody thought to look.
This one is a good example of why that keeps happening. The check was correct, cheap looking, and buried in an initialisation function. You only find it by profiling the caller rather than reading the code.
What to do
Nothing, which is the pleasant part.
The patches were posted for review on August 26, 2026 and are not merged. There is no tunable, no mount option, and no configuration change. The interface is unchanged and the fix is entirely internal, so when it lands it simply arrives.
If you run zstd compressed file systems inside virtual machines, particularly SquashFS or EROFS container images, this is worth watching in kernel changelogs, because your workload sits at the point where the change does the most. If you want to know whether your hardware even takes the BMI2 path in the first place, the flag is in /proc/cpuinfo, and on anything bought in the last decade the answer is yes.
Sources and further reading
- Patches Provide For Much Faster In-Kernel Zstd Due To Embarrassingly Bad Inefficiency, Phoronix, August 26, 2026
- zstd: probe BMI2 support only once, patch series by Usama Arif, LKML, August 26, 2026
- Discussion thread on the in-kernel zstd BMI2 probing patches, Linux.org
Frequently asked questions
What is BMI2 and why does the kernel check for it at all?
BMI2 is a bit manipulation instruction set extension, present on Intel Haswell and newer and on AMD Excavator and newer. Zstd's entropy decoding does a lot of bit field extraction, which is exactly what those instructions accelerate, so the library ships two code paths and picks the faster one when the hardware allows. Run time detection is the correct design here, because a single kernel binary has to boot on processors that predate 2013 as well as on current ones. The problem was never the check itself. It was the frequency: the kernel re-ran it on every context creation rather than once at initialisation.
Why is a CPUID check expensive enough to matter?
On bare metal it is merely wasteful. CPUID is a serialising instruction, meaning it drains the pipeline and blocks the reordering the processor relies on for speed, so it costs far more than its instruction count suggests. Under virtualisation it is much worse, because CPUID causes an unconditional VM exit: the guest traps into the hypervisor, the hypervisor handles it and returns. The reported code path triggered two serialising CPUID instructions per context. Doing that once at boot is invisible. Doing it for every block a file system decompresses turns a trivial capability check into a measurable share of the total work.
Which subsystems actually benefit?
The ones that create a zstd context per unit of work rather than once. SquashFS is the worst case named in the reporting, because it calls into this path for every block it decompresses, and SquashFS blocks are small. EROFS, Btrfs and F2FS all initialise a context per operation, so they pay the cost repeatedly too. The crypto/zstd code is in the same position, which is how the crypto_acomp benchmark used for the measurement exercises it. In practice that covers container images and read only system images on SquashFS and EROFS, Btrfs volumes mounted with zstd compression, and F2FS on flash.
Is the 71 percent figure something I will see on my own systems?
Treat it as an upper bound from a benchmark that isolates the affected path. crypto_acomp measures compression and decompression through the kernel crypto API with very little else happening around it, so the fixed per context overhead makes up an unusually large share of the total. A real workload also reads from storage, allocates pages, copies data and does something with the result, all of which dilutes the gain. The direction is reliable and the mechanism is sound, but a Btrfs volume under a mixed workload will show a smaller improvement than the headline. The gain should be largest on small blocks inside virtual machines.
When does this land, and is there anything to do now?
The patches were posted for review on August 26, 2026 and had not been merged at the time of writing, so no released kernel contains them. There is no configuration change to make and nothing to tune: the fix is entirely internal, it changes no interface, and it requires no action from anyone running zstd compressed file systems. The realistic path is review on the list, then a merge window, then arrival in a stable release, with a reasonable chance of a backport given how self contained the change is. Watch for it in kernel changelogs rather than planning around it.