Skip to content

scx_layered: keep_running must account for local-DSQ-dispatched tasks#3709

Closed
ByteLab-David wants to merge 2 commits into
mainfrom
upstream/layered-keep-running-pcpu-kthread
Closed

scx_layered: keep_running must account for local-DSQ-dispatched tasks#3709
ByteLab-David wants to merge 2 commits into
mainfrom
upstream/layered-keep-running-pcpu-kthread

Conversation

@ByteLab-David

Copy link
Copy Markdown
Contributor

keep_running() is invoked on the dispatch path when deciding whether a CPU should continue running the task whose slice has expired, or should instead pick a different task.

It currently has a fairly serious bug in that it does not check whether there is a task queued on the CPU's local DSQ. Pinned tasks such as per-CPU kthreads are direct-inserted there and can run nowhere else. antistall can't rescue them either, since it only scans layer and fallback DSQs. Such a task can therefore starve until the runnable-stall watchdog trips and ejects the scheduler.

Let's therefore add a check in keep_running() for whether there is another task on the local DSQ. This fixes stalls that were observed in production in GKE and EKS scenarios experiencing sustained CPU pressure.

keep_running() is invoked on the dispatch path when deciding whether a
CPU should continue running the task whose slice has expired, or should
instead pick a different task.

It currently has a fairly serious bug in that it does not check whether
there is a task queued on the CPU's local DSQ. Pinned tasks such as
per-CPU kthreads are direct-inserted there and can run nowhere else.
antistall can't rescue them either, since it only scans layer and
fallback DSQs. Such a task can therefore starve until the runnable-stall
watchdog trips and ejects the scheduler.

Let's therefore add a check in keep_running() for whether there is
another task on the local DSQ. This fixes stalls that were observed in
production in GKE and EKS scenarios experiencing sustained CPU pressure.

Signed-off-by: David Vernet <void@mainfault.com>
@ByteLab-David
ByteLab-David requested review from etsal, htejun and kkdwvd July 15, 2026 15:57
@htejun

htejun commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Is this reproducible? keep_running() is only consulted if dispatch is invoked and if there's a task sitting in local DSQ, the kernel would just switch to that, right?

@ByteLab-David

Copy link
Copy Markdown
Contributor Author

Is this reproducible? keep_running() is only consulted if dispatch is invoked and if there's a task sitting in local DSQ, the kernel would just switch to that, right?

Hmm, I'm almost certain I saw this happen in some of the runs I was doing. I don't have the trace anymore but a latency-sensitive pcpu task got dispatched to the core and then got stuck behind the task that was currently on the CPU. Now that I'm looking at this more closely though, I think I must've conflated this with some other watchdog trigger I was trying to debug b/c I don't think a watchdog timeout should be possible. I think what might have happened is that there was a race between the rq lock being dropped on the dispatch path (e.g. from antistall_consume() when hitting the consume_dispatch_q() path), and a pcpu task being direct dispatched to the local DSQ in that window? Not sure, seems far fetched but I do explicitly remember it happening that a pcpu task woke up on the core and stayed runnable even though I'd have expected it to preempt the running task.

I wish I still had the trace. In any case I think the commit is way overstated as is and I don't see how this would result in a watchdog trip. Feel free to just close this, or if I'm not missing something and the above race is possible, I can reframe the summary + comment to be accurate.

@htejun htejun closed this Jul 18, 2026
@ByteLab-David
ByteLab-David deleted the upstream/layered-keep-running-pcpu-kthread branch July 19, 2026 00:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants