← Back to archive

Daily update · Oct 6–7, 2026

Linux mainline: sched_ext hotplug hang, cpuset races, and ATAPI fixes

A round of fixes for sched_ext, cpuset, workqueue, and libata, including CPU hotplug and workqueue NULL-pointer issues.

In brief

This update covers sched_ext fixes for a CPU hotplug hang, remote local-DSQ dequeue callbacks, and queue-sequence collisions. It also includes cpuset fixes for hotplug and v2-mode races, a workqueue NULL-pointer dereference fix, and a libata change that preserves CHECK CONDITION status for failed ATAPI commands.

Bug fixes

sched_ext: Fix CPU hotplug hang with BPF-held tasks

sched_ext is the BPF-based CPU scheduler extension. A CPU going offline must empty its run queue (rq), and the hotplug thread waits until that is done. With sched_ext, a task can remain counted on the dying CPU's rq while held by the BPF scheduler or placed in a user dispatch queue; once the CPU stops dispatching, the task may never be pulled back, so the hotplug wait can hang.

Why it matters: Avoids a CPU-offline hang on systems using the sched_ext BPF scheduler.

d35a535d3e3e

sched_ext: Correct ops.dequeue() for remote local-DSQ moves

When a task in BPF scheduler custody moves to another CPU's local dispatch queue (DSQ), ops.dequeue() was delayed until the task was picked and was called with a core-scheduling execution flag even though no core-scheduling pick occurred. The fix calls ops.dequeue() without flags when the task is inserted into the destination DSQ, matching same-rq behavior. A new selftest exercises both direct dispatch to a local DSQ and the move-to-local BPF helper.

Why it matters: BPF schedulers now receive accurate dequeue notifications for these cross-CPU moves.

af701b8d3238cc07fae1de5d

sched_ext: Avoid qseq collisions after task migration

sched_ext uses a sequence number in task state to tell whether a queued instance is the same one a BPF helper saw when inserting it into a dispatch queue. The old per-run-queue counters are independent, so a task dequeued and re-enqueued on a different CPU could receive the same sequence and be mistaken for the earlier instance. The sequence is now generated from a per-task counter.

Why it matters: Prevents stale dispatch-queue claims when tasks migrate between CPUs.

e6ac89b8b1c1

workqueue: Fix NULL current_pwq dereference in chained-work check

current_wq_worker() identifies kworkers but does not guarantee one is currently running a work item, because worker->current_pwq is set only while a work function executes. Queueing on a draining or destroying workqueue could reach the chained-work check from a kworker outside work execution and dereference NULL. The check now requires worker->current_pwq before proceeding.

Why it matters: Prevents a NULL-pointer fault during workqueue drain/destroy operations.

980db94e3eee

libata: Preserve CHECK CONDITION for failed ATAPI commands

ATAPI completion set the SCSI status to CHECK CONDITION only if the command's result field was zero, to preserve host bytes for timed-out or requeued commands. But a regular failed command completed through libata error handling can also have a non-zero result because the SCSI midlayer stores an internal byte for some sense codes, causing the error status to be lost. The fix avoids losing CHECK CONDITION in that case.

Why it matters: Failed ATAPI commands keep their error status when reported to the SCSI layer.

bc8ce2cea5f7

cpuset: Fix v2-mode and hotplug races

is_in_v2_mode() previously read a cpuset subsystem root pointer directly, which can become stale when a cgroup filesystem is rebound; it now uses a dedicated cpuset_v2_mode flag. The hotplug path also called is_in_v2_mode() before taking cpuset_mutex, leaving a race if the hierarchy switched between v1 and v2; the call now happens under the mutex. In addition, guarantee_active_cpus() had a race with CPU offline because the CPU active mask is updated before the cpuset hotplug handler runs.

Why it matters: Avoids cpuset use-after-free, mode-check races, and hotplug-related state corruption.

e06b678e3b4eb8eb5fd5bdb423b1ab15ca91

Source commits9 entries +
d35a535d3e3e

sched_ext: Fix CPU hotplug hang when a dying CPU's tasks sit in the BPF scheduler

Tejun Heo · Sep 23, 2026 · 4 files

980db94e3eee

workqueue: Fix NULL current_pwq deref in chained work check

Pavankumar Kondeti · Sep 28, 2026 · 1 files

bc8ce2cea5f7

ata: libata-scsi: do not lose CHECK CONDITION for failed ATAPI commands

Hengyu Liang · Sep 29, 2026 · 1 files

e06b678e3b4e

cgroup/cpuset: Don't access cpuset_cgrp_subsys.root in is_in_v2_mode()

Waiman Long · Sep 30, 2026 · 1 files

af701b8d3238

sched_ext: Call ops.dequeue() when a task arrives on a remote local DSQ

Kuba Piecuch · Sep 30, 2026 · 1 files

cc07fae1de5d

selftests/sched_ext: Add a test for ops.dequeue() on remote local DSQ moves

Kuba Piecuch · Sep 30, 2026 · 3 files

23b1ab15ca91

cgroup/cpuset: Handle cpu hotplug race in guarantee_active_cpus()

Waiman Long · Oct 2, 2026 · 1 files

e6ac89b8b1c1

sched_ext: Generate qseq from a per-task counter

Kuba Piecuch · Oct 3, 2026 · 4 files

b8eb5fd5bdb4

cgroup/cpuset: Call is_in_v2_mode() after acquiring cpuset_mutex in cpuset_handle_hotplug()

Waiman Long · Oct 5, 2026 · 1 files