
Linux Kernel v6.16 is Released: This is What's New for Compute Express Link (CXL)
- Steve Scargall
- Cxl
- July 27, 2025
The Linux Kernel v6.16 release brings several improvements and additions related to Compute Express Link (CXL) technology.
Release Highlights
Linux Kernel v6.16 includes 37 commits to the CXL and DAX subsystems:
| Category | Commits |
|---|---|
| New Features & Hardware | 2 |
| Bug Fixes | 6 |
| Refactoring & Cleanup | 8 |
| Documentation | 3 |
| Other | 18 |
The Linux v6.16 kernel cycle is dominated by one clear theme: hardening CXL memory device reliability and serviceability through the EDAC subsystem. Four new control features land in this release — patrol scrub, Error Check Scrub (ECS), soft Post Package Repair (PPR), and memory sparing — each exposing a distinct class of CXL 3.0 memory maintenance operations to userspace through a consistent sysfs interface. Alongside these, support for the PERFORM_MAINTENANCE command provides the underlying mechanism that drives scrub and repair operations on compliant devices. Taken together, this work moves CXL from a device class that Linux can merely enumerate and map to one where the kernel actively participates in proactive memory health management.
The EDAC additions are not without rough edges that needed immediate attention. Several fixes accompany the new code: a wrong repair type being passed when checking DRAM event records, a miscalculation in the minimum scrub cycle for a region, memory leaks in error paths, and a return value bug in cxlctl_validate_set_features(). This pattern of feature-plus-fixes in the same release reflects the pace at which CXL 3.0 RAS infrastructure is being built out — the plumbing is going in fast, and correctness gaps are being closed in the same merge window. The cxl/ras CPER handler also received a fix for device confusion, where error records were being attributed to the wrong device under certain topologies.
Outside of EDAC, the cxl/region code saw meaningful internal restructuring. Decoder lookup logic was factored into dedicated helpers (cxl_port_pick_region_decoder(), a new function to find a switch decoder by range, and root decoder extraction routines), reducing duplication and making the region assembly path easier to reason about. A correctness fix eliminates unnecessary interleave granularity constraints when ways=1, and the ACPI path now validates CHBS structure length for CXL 2.0 hosts. The CXL Maturity Map documentation was also updated, reflecting the growing breadth of what the driver actually implements.
Key Changes
Patrol scrub and ECS control features: New sysfs-exposed interfaces allow userspace to configure and trigger patrol scrub and Error Check Scrub on CXL memory devices, enabling scheduled background error detection without requiring a reboot or vendor-specific tooling.
Soft PPR and memory sparing control: Soft Post Package Repair and memory sparing can now be initiated through the kernel’s EDAC interface, giving RAS frameworks the ability to retire faulty DRAM rows or activate spare banks on CXL 3.0 devices in response to correctable error thresholds.
PERFORM_MAINTENANCEcommand support: The CXL mailbox command that drives scrub and repair operations is now wired up incxl/edac, providing the execution path that the patrol scrub and PPR control features depend on.Memory operation attribute discovery: The driver can now query a device’s current-boot memory operation attributes, allowing it to reconcile in-flight maintenance state across a kexec or driver reload rather than starting blind.
CPER handler device confusion fix: The
cxl/rasCPER error record handler was misidentifying the target device under multi-device topologies; the fix ensures correctable and uncorrectable errors are charged to the correct CXL endpoint.Region decoder lookup refactoring: Root and switch decoder selection logic in
cxl/regionhas been extracted into named helpers and deduplicated, removing a redundant call tocxl_port_pick_region_decoder()that could produce incorrect results during region assembly.Interleave granularity relaxed for single-way regions: When a CXL region uses only one interleave way, granularity constraints are now ignored during validation, unblocking configurations that were incorrectly rejected.
DAX kmem truncation warning: The DAX subsystem now emits a warning when a
kmemregion must be truncated to align with memory block boundaries, making a previously silent data-availability reduction visible to system administrators.
CXL related changes from Kernel v6.15 to v6.16
Here is the detailed list of all commits merged into the 6.16 Kernel for CXL and DAX. This list was generated by the Linux Kernel CXL Feature Tracker .
- cxl/edac: Fix using wrong repair type to check dram event record
- cxl/ras: Fix CPER handler device confusion
- cxl/edac: Fix potential memory leak issues
- cxl/edac: Fix the min_scrub_cycle of a region miscalculation
- cxl: fix return value in cxlctl_validate_set_features()
- Merge branch ‘for-6.16/cxl-features-ras’ into cxl-for-next
- cxl/edac: Add CXL memory device soft PPR control feature
- cxl/edac: Add CXL memory device memory sparing control feature
- cxl/edac: Support for finding memory operation attributes from the current boot
- cxl/edac: Add support for PERFORM_MAINTENANCE command
- cxl/edac: Add CXL memory device ECS control feature
- cxl/edac: Add CXL memory device patrol scrub control feature
- cxl: Update prototype of function get_support_feature_info()
- cxl/features: Remove the inline specifier from to_cxlfs()
- cxl/feature: Remove redundant code of get supported features
- Documentation: Update the CXL Maturity Map
- cxl: Sync up the driver-api/cxl documentation
- cxl/hdm: Clean up a debug printk
- Merge branch ‘for-6.16/cxl-cleanups’ into cxl-for-next
- cxl: Add a dev_dbg() when a decoder was added to a port
- cxl/region: Add a dev_err() on missing target list entries
- cxl/region: Add a dev_warn() on registration failure
- cxl/region: Add function to find a port’s switch decoder by range
- cxl/region: Factor out code to find a root decoder’s region
- cxl/region: Factor out code to find the root decoder
- cxl/port: Replace put_cxl_root() by a cleanup helper
- cxl/region: Move find_cxl_root() to cxl_add_to_region()
- cxl/region: Avoid duplicate call of cxl_port_pick_region_decoder()
- cxl/region: Rename function to cxl_port_pick_region_decoder()
- cxl: Introduce parent_port_of() helper
- cxl/pci: Add comments to cxl_hdm_decode_init()
- cxl/pci: Moving code in cxl_hdm_decode_init()
- cxl: Remove else after return
- cxl: core/region - ignore interleave granularity when ways=1
- cxl/acpi: Verify CHBS length for CXL2.0
- cxl: Remove always true condition for cxlctl_validate_hw_command()
- DAX: warn when kmem regions are truncated for memory block alignment

