Skip to content

sched: honor CPU binding of per-CPU kernel threads - #111

Merged
FengHeting merged 3 commits into
ViudiraTech:developfrom
JiTianYu391:codex/fix-kthread-cpu-binding
Oct 22, 2026
Merged

FengHeting merged 3 commits into
ViudiraTech:developfrom
JiTianYu391:codex/fix-kthread-cpu-binding

Conversation

@JiTianYu391

Copy link
Copy Markdown
Contributor

kthread_create_on_cpu() / kthread_run_on_cpu() 只初始化 cpu_id,唤醒放置和负载均衡仍会迁移任务,实际不履行绑定 API 的承诺。新增 cpu_pinned,唤醒保持目标 CPU,newidle/periodic stealing 的候选扫描跳过它。

复现:将两个 kbench worker 都请求放在 CPU 1,比较 same-cpu 行的实际 CPU 和任务迁移次数。现有 fix2-1.log 中,wq same-cpu 一轮为 [1>0m61214,1>4m55566];修后 pin.log 及本轮 30 轮输出均为 [1>1,1>1]。

绑定行为 修前实测 修后实测
请求 CPU 1 的两个 wq worker 结束在 CPU 0/4,迁移 61214/55566 次 均留在 CPU 1,任务迁移为 0
same-cpu 的含义 请求被迁移破坏 请求得到遵守

这改变基准实际执行位置,修前修后的耗时不能当成同一放置条件下的性能 A/B。因此本 PR 以正确性和迁移字段验证,不声称跨核延迟降低。

验证环境:5 vCPU、KVM、2 GiB、每次 QEMU 超时 60 秒。所有独立分支直接从 origin/develop@153578b5 开出,目标均为 develop;每个分支均独立完成 GCC 16.2 / LTO 构建,构建源只取 git ls-files '*.c',切分支后清除对应 .o/.d。按已知基线问题临时关闭 CONFIG_VIRTIO_GPU。除 strcpy PR 自身外,独立构建在链接命令临时加 -Wl,-u,strcpy,绕过原始 develop 的已复现 LTO 缺陷;没有把其他 PR 的源码带进分支。

运行基准时明确使用独立 sched 修复、strcpy 修复、kbench 和 kthread 绑定的共同测试覆盖层,以免把已知调度崩溃或实际 CPU 不符误算成待测修改的效果。覆盖层仅用于测试镜像,不构成提交依赖。

已否决方案:把偷取限制为源 rq 至少两个任务,曾使 ping-pong 约 3 µs 恶化到 7.8 µs;轮询 idle 无明显收益。这些改动均未采用。宿主负载高,仅把交替多次中位数中超过 20% 的差异视为性能结论。

🤖 Generated with ClaudeCode

kthread_create_on_cpu() and kthread_run_on_cpu() promise a thread bound
to one CPU, but create_kthread() only seeded task->cpu_id.  Nothing in
the scheduler remembered the request, so the first wakeup could place
the thread elsewhere through select_wakeup_cpu_locked(), and newidle or
periodic balancing could pull it to any CPU.

Record the binding in task->cpu_pinned and honour it in the two places
that pick a different CPU for an existing task: wakeup placement keeps a
pinned task on its CPU, and the steal-candidate scan skips it, which
covers both newidle and periodic balancing.

Reproduce with two kbench same-CPU workers requested on CPU 1. Before
this fix, wake placement and stealing can send either worker elsewhere;
afterwards same-CPU rows consistently report [1>1,1>1]. The pin.log and
heap A/B logs retain the CPU and migration evidence. This is a binding
correctness fix, not a claim that cross-CPU ping-pong is faster.

Validation: standalone origin/develop branch, GCC LTO build with virtio-gpu
disabled and -Wl,-u,strcpy for the unrelated existing link defect; 5-vCPU
runtime suites with the separately documented scheduler/kbench overlays.
No source-runqueue minimum-size or idle-polling policy is introduced.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Validate the target CPU before queueing a pinned kthread creation
request, so an invalid CPU is rejected instead of silently binding the
thread to CPU 0.

Honor the pin in wake placement even before sched_start(), where the
BSP-only fallback would otherwise move a pinned thread to CPU 0 and
rewrite its cpu_id permanently.

Skip pinned entities in the steal scan without spending the movable
candidate budget, and refuse explicit migration of a pinned task in
task_set_cpu(), mirroring PF_NO_SETAFFINITY.

Signed-off-by: MicroFish <2609948707@qq.com>
@FengHeting
FengHeting merged commit 66ee4ca into ViudiraTech:develop Oct 22, 2026
2 checks passed
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