Executive brief
The Linux kernel's block I/O cost control subsystem (blk-iocost) failed to properly clear delay state when freeing policy data, causing block cgroups to remain permanently marked as congested. This caused all tasks in affected cgroups to experience reduced readahead, skipped readahead, and throttled memory allocation, degrading I/O and memory performance indefinitely.
Technical details
The vulnerability is a resource-state cleanup bug in the blk-iocost block I/O controller (block/blk-iocost.c). When iocg_kick_delay() marks a cgroup as congested by calling blkcg_set_delay(), the clearing of this state depends on iocg_kick_delay() being called again from timer or I/O paths. However, ioc_pd_free() removes the I/O cgroup queue from active processing and cancels its timer, preventing any future clearing of the congestion flag. This leaves blkcg->congestion_count permanently elevated. Consequently, blk_cgroup_congested() returns true indefinitely for all tasks in the cgroup and descendants, causing page_cache_sync_ra() to cut readahead to one page, page_cache_async_ra() to skip readahead entirely, and __folio_throttle_swaprate() to engage swap throttling. The fix explicitly clears the delay state (iocg->delay, iocg->indelay_since, and blkcg congestion flag) in ioc_pd_free() after list removal and timer cancellation, before RCU callback scheduling.
Affected products
- Linux Linux kernel 4.19+
Timeline
- 2026-09-17: disclosed
- 2026-08-15: patched: upstream patch merged
- 2026-09-14: patched: stable tree backport