sched/proxy:try_to_wake_up() 内联处理 return-migration — 代理调度唤醒路径去锁往返
💡 一句话总结
在启用代理调度(sched/proxy,一种让"阻塞在互斥锁上的任务"把 CPU 执行权让渡给锁持有者代为运行的调度机制)的内核上,一个被"代理迁移"到别的 CPU 的任务被唤醒时,需要返回迁移回它能运行的 CPU。补丁前这个动作发生在 __schedule() 深处的 proxy_force_return()——它要释放 rq 锁、重新拿 task_rq_lock(含 pi_lock)、重新校验、出队、选核、挂回目标 rq、再重新拿回 rq 锁,一轮锁往返外加一次强制重新选核。本补丁把这个返回迁移前移进 try_to_wake_up():唤醒路径发现任务被代理迁移过,就在try_to_wake_up() 已持有的 rq 锁下把它出队,随后的正常唤醒流程(select_task_rq() → ttwu_queue())自然把它放到一个能运行的 CPU 上——整段 proxy_force_return() 连同它的锁往返直接删除。补丁未提供基准数据,性能收益为逻辑分析(解读(AI 分析))。
📋 补丁基本信息
| 项目 | 内容 |
|---|---|
| 补丁类型 | 优化(performance)· 热路径减锁往返/减路径长度(hot-path) |
| 状态 | Merged(绿)· 合入版本:Linux 7.2(v7.2-rc1 已含) |
| 当前版本 | 主线合入版(本 commit 即最终版)· git.kernel.org 链接 |
| 版本演进 | 本 commit 为合入主线的最终版,无独立 v1/v2 演进。所属 sched/proxy(代理调度)系列由 John Stultz(Google)2026-05-12 在 LKML 发布,本补丁是系列第 6 补丁(Link 标签)。commit message 注明"本补丁从更大的 proxy 补丁中拆出并大幅重写",原始功绩归属 Peter Zijlstra / Juri Lelli / Valentin Schneider / Connor O'Brien 等多方。讨论/演进信息来自本地内核 git 的 commit message(Link + Signed-off-by 链),lore 索引不可用已如实标注。 |
| 作者机构 | John Stultz(Google);Signed-off-by: Peter Zijlstra (Intel) |
| 提交日期 | 2026-05-12 |
| 改动范围 | include/linux/sched.h、kernel/sched/core.c,+97/-100 行,2 文件 |
| 核心函数 | try_to_wake_up() / ttwu_runnable() / proxy_needs_return()(新增) / find_proxy_task() / proxy_deactivate();删除 proxy_force_return() |
| 原始链接 | commit f13beb010e4a(Link 标签:patch.msgid.link) |
📊 速览卡片
特性等级依据:优化方向明确(唤醒热路径整段删除 proxy_force_return() 的锁往返 + 选核循环)、代码纯内联删除、无 ABI/配置变更、落地零风险;但收益仅在 CONFIG_SCHED_PROXY_EXEC 编译开启且代理迁移发生时才体现(非 proxy 内核中 proxy_needs_return() 编译期恒 false、几乎免费),且补丁未提供任何量化数据、受益场景窄——综合 4 原则评 ★★★(解读(AI 分析))。
🎯 解决什么问题
sched/proxy(代理调度)系列整体解决的是调度器不感知"任务因互斥锁阻塞"的问题:传统上任务在互斥锁上阻塞,CPU 只能空转或换跑别的任务,锁持有者(往往是更高优先级的调度上下文)却可能被排在别处。代理调度让阻塞任务把自己的 CPU 执行权让渡(donate)给锁持有者,以阻塞任务的调度上下文代为运行,直到锁释放——这既避免 CPU 空转,也天然缓解优先级反转。系列由 Peter Zijlstra 长期开发、John Stultz(Google)主导上游化(与 ghOSt 的 mutex proxy execution 方向一致)。本补丁是系列中处理"代理迁移后的返回"的机制补丁:系列主体引入了 blocked_on 关联、find_proxy_task() 链式查找、proxy_migrate_task() 迁移、proxy_deactivate() 停用等机制,本补丁把其中最重的一段"返回迁移"处理(proxy_force_return())从 __schedule() 挪进 try_to_wake_up()。它依赖父提交 f0c1ecde6447(block_task() 可直调改造),也为后续优化(如 abc40cca0efd 移除唤醒路径防御性清理)提供了基础。与本站同日已有分析的关系:sched/proxy: Optimize try_to_wake_up()(abc40cca0efd) 是同一系列的后续优化——本补丁(f13beb010e4a)先加入 return-migration 处理并顺带在唤醒路径加了
if (task_is_blocked(p)) clear_task_blocked_on(p, NULL) 防御;abc40cca0efd 则通过让 proxy_deactivate() 保证 cleared blocked_on,把这个防御从句再从公共唤醒路径删掉。两者同机制、同系列、不同方面,本补丁在前(更早合入)、abc40cca0efd 在后(收尾瘦身)。
"This patch adds logic so try_to_wake_up() will notice if we are waking a task where blocked_on == PROXY_WAKING, and if necessary dequeue the task so the wakeup will naturally return-migrate the donor task back to a cpu it can run on. This helps performance as we do the dequeue and wakeup under the locks normally taken in the try_to_wake_up() and avoids having to do proxy_force_return() from __schedule(), which has to re-take similar locks and then force a pick again loop."
即:
try_to_wake_up() 唤醒一个 blocked_on == PROXY_WAKING 的任务时,应当在唤醒路径上就识别并出队它,让唤醒自然完成返回迁移;这样出队和唤醒都在 try_to_wake_up 已持有的锁下完成,避免了从 __schedule() 调用 proxy_force_return() 所必须的重取锁 + 强制重新选核循环。commit message 还注明本补丁从更大的 proxy 补丁中拆出并大幅重写。
p->wake_cpu(任务该在哪个 CPU 运行)与 task_cpu(p)(任务当前挂在哪)。正常情况下二者相等;但 proxy_set_task_cpu() 会保留原 wake_cpu、只改 task_cpu,把任务暂存到一个它可能无法真正运行的 rq 上(__set_task_cpu(p, cpu); p->wake_cpu = wake_cpu;,保留原值)。当这样的任务被唤醒时:
- 补丁前:
ttwu_runnable()看到任务已在 rq 上,直接返回"已可运行"(返回 1),不移动它。等这个 rq 后续执行__schedule()→pick_next_task()选中它、发现blocked_on == PROXY_WAKING时,才在find_proxy_task()里调用proxy_force_return():释放 rq 锁 → 重拿 task_rq_lock(rq 锁 + pi_lock)→ 重新校验任务还在同一 rq → deactivate → select_task_rq() 选核 → set_task_cpu() → attach 到目标 rq → 再重新拿回 rq 锁。这是"释放/重取锁 + 强制 pick again 循环"的完整往返。 - 补丁后:
ttwu_runnable()先调用新增的proxy_needs_return(),发现task_cpu(p) != p->wake_cpu(被代理迁移过)就在已持有的 rq 锁下清 blocked_on、若任务是 donor 则proxy_reset_donor()换回 idle、然后block_task(rq, p, TASK_WAKING)出队,返回 0。于是try_to_wake_up()走正常唤醒流程:select_task_rq(p, p->wake_cpu)选一个它能运行的 CPU,set_task_cpu()迁移、ttwu_queue()入队——返回迁移在try_to_wake_up()已持有的锁下一次性完成,proxy_force_return()整段删除。
- 构建前提:内核编译时打开
CONFIG_SCHED_PROXY_EXEC。只有这种构建里proxy_needs_return()才有实际逻辑(非 proxy 构建中它编译期恒false)。 - 负载场景:代理调度面向"任务频繁阻塞在互斥锁上、且锁持有者可能在别的 CPU"的用法——例如 Google 的 ghOSt 式用户态调度、实时/低延迟敏感负载、锁密集的并发计算。当锁持有者与等待者在不同 CPU 时,代理调度会把等待者(donor)的 CPU 让给持有者;持有者结束或释放锁、等待者被唤醒时,等待者需要从"暂存的 rq"回到它本来能运行的 CPU(
wake_cpu)。 - 触发条件:
task_cpu(p) != p->wake_cpu即发生代理迁移。跨核互斥锁传递越频繁、代理迁移越频繁,返回迁移发生得越多,锁往返路径被踩中的次数越多。 - 为什么该场景遇到上面的系统缺陷:跨核锁传递场景下任务频繁被代理迁移、频繁被唤醒,而补丁前的返回迁移要经过"释放 rq 锁 → 重拿 task_rq_lock → 重校验 → deactivate → select_task_rq → attach → 重拿 rq 锁"的完整锁往返,外加一次强制重新选核;唤醒越频繁,这段额外开销越明显。
🧩 核心机制
核心一句话:把"被代理迁移的任务返回它能运行的 CPU"这个动作,从 __schedule() 深处的 proxy_force_return()(要释放/重取 rq 锁 + pi_lock + 强制重选核)前移到 try_to_wake_up(),在唤醒路径已持有的锁下完成出队,让正常唤醒流程自然完成返回迁移。
① 判定(机制核心):新增
proxy_needs_return()——检查 task_cpu(p) != p->wake_cpu。正常任务二者相等;代理迁移时 proxy_set_task_cpu() 保留 wake_cpu 原值只改 task_cpu,所以不等即"被代理迁移、需要返回"。命中后:拿 p->blocked_lock 清 blocked_on;若 p 就是 rq 的 donor(正在让渡执行权),调 proxy_reset_donor() 把它换回 idle(put_prev_set_next_task + rq_set_donor + resched_curr);最后 block_task(rq, p, TASK_WAKING) 出队并返回 true。② 消费:
ttwu_runnable() 改为 guard 式拿锁,在 task_on_rq_queued(p) 确认后调用 proxy_needs_return()——若返回 true(已出队),ttwu_runnable() 返回 0,让 try_to_wake_up() 进入正常唤醒路径(select_task_rq → set_task_cpu → ttwu_queue)。③ 收尾:
try_to_wake_up() 正常路径尾部加 else if (cpu != p->wake_cpu) p->wake_cpu = cpu;——如果 select_task_rq() 选了与 wake_cpu 不同的 CPU 返回(而不是回原 CPU),就把 wake_cpu 修正为实际选中的 CPU,避免留下指向旧位置的过期 wake_cpu。④ 删除重路径:整段删除
proxy_force_return()(约 50 行)。find_proxy_task() 里原来 goto force_return 的两处改为 goto deactivate;deactivate: 标签处由"proxy_deactivate() 失败则 force_return"改为直接 proxy_deactivate(rq, p); return NULL。⑤ 配套语义修正:
proxy_deactivate() 从"返回 bool + try_to_block_task() 处理失败"改为"void + 直接调 block_task()(父提交 f0c1ecde6447 使 block_task() 可直调)",并用 WARN_ON_ONCE(state == TASK_RUNNING) 断言替代原来的提前返回;is_special_task_state() 加入 TASK_WAKING——因为现在 block_task(rq, p, TASK_WAKING) 会把 TASK_WAKING 当任务状态传入,须让它被识别为"特殊状态"(block_task() 里据此置 DEQUEUE_SPECIAL,豁免 DELAY_DEQUEUE 的延迟出队,避免特殊状态任务遭受伪唤醒延迟)。为什么能支撑场景提升:跨核锁传递场景下返回迁移高频发生,补丁把每次返回迁移的"锁往返 + 强制重选核"降为"在已持有的锁下顺手出队、唤醒流程自然迁移"——省掉的不是一条路径,而是每次返回迁移都要付的固定开销。
来源:基于 git show f13beb010e4a 真实 diff 绘制
| 步骤 | 操作 | 目的 |
|---|---|---|
| ① 判定 | proxy_needs_return() 检查 task_cpu(p) != p->wake_cpu | 识别"被代理迁移、需要返回"的任务 |
| ② 出队 | 在 rq 锁下 block_task(rq, p, TASK_WAKING)(必要时先 proxy_reset_donor()) | 让 ttwu_runnable 返回 0,唤醒流程接管返回迁移 |
| ③ 唤醒 | select_task_rq(p, p->wake_cpu) → set_task_cpu() → ttwu_queue() | 在能运行的 CPU 上入队,自然完成返回迁移 |
| ④ 收尾 | else if (cpu != p->wake_cpu) p->wake_cpu = cpu; | 修正过期 wake_cpu |
| ⑤ 删除 | 删除 proxy_force_return();goto force_return → goto deactivate | 移除 __schedule 侧的锁往返 + 强制重选核路径 |
@@ -3735,6 +3735,53 @@ void update_rq_avg_idle(struct rq *rq)
rq->idle_stamp = 0;
}
+#ifdef CONFIG_SCHED_PROXY_EXEC
+static void zap_balance_callbacks(struct rq *rq);
+
+static inline void proxy_reset_donor(struct rq *rq)
+{
+ WARN_ON_ONCE(rq->donor == rq->curr);
+
+ put_prev_set_next_task(rq, rq->donor, rq->curr);
+ rq_set_donor(rq, rq->curr);
+ zap_balance_callbacks(rq);
+ resched_curr(rq);
+}
+
+/*
+ * Checks to see if task p has been proxy-migrated to another rq
+ * and needs to be returned. If so, we deactivate the task here
+ * so that it can be properly woken up on the p->wake_cpu
+ * (or whichever cpu select_task_rq() picks at the bottom of
+ * try_to_wake_up()
+ */
+static inline bool proxy_needs_return(struct rq *rq, struct task_struct *p)
+{
+ if (!task_is_blocked(p))
+ return false;
+
+ scoped_guard(raw_spinlock, &p->blocked_lock) {
+ /* Task is waking up; clear any blocked_on relationship */
+ __clear_task_blocked_on(p, NULL);
+
+ /* If already current, don't need to return migrate */
+ if (task_current(rq, p))
+ return false;
+
+ /* If we're return migrating the rq->donor, switch it out for idle */
+ if (task_current_donor(rq, p))
+ proxy_reset_donor(rq);
+ }
+ block_task(rq, p, TASK_WAKING);
+ return true;
+}
+#else /* !CONFIG_SCHED_PROXY_EXEC */
+static inline bool proxy_needs_return(struct rq *rq, struct task_struct *p)
+{
+ return false;
+}
+#endif /* CONFIG_SCHED_PROXY_EXEC */▲ 这段是机制成立的关键:proxy_needs_return() 在 blocked_lock 保护下清掉 blocked_on,若任务恰好是 rq 的 donor(正在让渡执行权给锁持有者)则先用 proxy_reset_donor() 把它换回 idle,再 block_task(rq, p, TASK_WAKING) 出队。非 proxy 构建中该函数编译期恒 false——收益只在 CONFIG_SCHED_PROXY_EXEC 下有意义。
@@ -6747,71 +6811,6 @@ static void proxy_migrate_task(struct rq *rq, struct rq_flags *rf,
proxy_reacquire_rq_lock(rq, rf);
}
-static void proxy_force_return(struct rq *rq, struct rq_flags *rf,
- struct task_struct *p)
- __must_hold(__rq_lockp(rq))
-{
- struct rq *task_rq, *target_rq = NULL;
- int cpu, wake_flag = WF_TTWU;
-
- lockdep_assert_rq_held(rq);
- WARN_ON(p == rq->curr);
-
- if (p == rq->donor)
- proxy_resched_idle(rq);
-
- proxy_release_rq_lock(rq, rf);
- /*
- * We drop the rq lock, and re-grab task_rq_lock to get
- * the pi_lock (needed for select_task_rq) as well.
- */
- scoped_guard (task_rq_lock, p) {
- task_rq = scope.rq;
-
- /*
- * Since we let go of the rq lock, the task may have been
- * woken or migrated to another rq before we got the
- * task_rq_lock. So re-check we're on the same RQ. If
- * not, the task has already been migrated and that CPU
- * will handle any futher migrations.
- */
- if (task_rq != rq)
- break;
-
- /*
- * Similarly, if we've been dequeued, someone else will
- * wake us
- */
- if (!task_on_rq_queued(p))
- break;
-
- /*
- * Since we should only be calling here from __schedule()
- * -> find_proxy_task(), no one else should have
- * assigned current out from under us. But check and warn
- * if we see this, then bail.
- */
- if (task_current(task_rq, p) || task_on_cpu(task_rq, p)) {
- WARN_ONCE(1, "%s rq: %i current/on_cpu task %s %d on_cpu: %i\n",
- __func__, cpu_of(task_rq),
- p->comm, p->pid, p->on_cpu);
- break;
- }
-
- update_rq_clock(task_rq);
- deactivate_task(task_rq, p, DEQUEUE_NOCLOCK);
- cpu = select_task_rq(p, p->wake_cpu, &wake_flag);
- set_task_cpu(p, cpu);
- target_rq = cpu_rq(cpu);
- clear_task_blocked_on(p, NULL);
- }
-
- if (target_rq)
- attach_one_task(target_rq, p);
-
- proxy_reacquire_rq_lock(rq, rf);
-}
-
/*
* Find runnable lock owner to proxy for mutex blocked donor▲ 被删的 proxy_force_return() 正是 commit message 抱怨的"重取锁 + 强制 pick again 循环":它从 __schedule() 的 find_proxy_task() 里被调用,先 proxy_release_rq_lock() 释放 rq 锁,再 task_rq_lock 重拿(rq 锁 + pi_lock),校验任务还在同一 rq 后 deactivate、select_task_rq、set_task_cpu、attach 到目标 rq,最后 proxy_reacquire_rq_lock() 重新拿回 rq 锁。整段删除后,返回迁移由 try_to_wake_up() 的正常唤醒路径承担。
本补丁为中等改动(+97/-100 行,机制迁移 + 路径删除),核心机制是"返回迁移从 __schedule 侧移到 ttwu 侧"的流程变化,配图 1(before/after 流程对比)即可完整表达,机制部分不再额外加图(决策依据:单点路径迁移 + 两段关键 diff + 一张对比图已讲透)。
📈 性能影响
proxy_force_return() 里"释放 rq 锁 → 重拿 task_rq_lock(含 pi_lock)→ 重新校验 → deactivate → select_task_rq → attach → 重拿 rq 锁"的整段路径,以及在 find_proxy_task() 触发它之后 __schedule() 还要"force a pick again loop"(再次走 pick_next_task())的额外一轮选核。这些都在唤醒/调度线程自己的 CPU 上执行,属于典型的 on-CPU 指令与锁指令开销。次角度:off-CPU 锁等待(少拿一把 pi_lock + 少一次锁争用窗口)。原路径在释放 rq 锁后要重新获取
task_rq_lock(含 p->pi_lock),在锁被释放到重新获取之间的窗口里其他 CPU 可能争用这些锁;补丁后整个返回迁移都在 try_to_wake_up 已持有的 rq 锁下完成,不再额外获取/释放一把 pi_lock。Brendan Gregg 视角:优化的是唤醒路径中 on-CPU 的锁指令段,以及锁往返释放/重取窗口对应的 off-CPU 等待。
- 启用代理调度的构建:
CONFIG_SCHED_PROXY_EXEC=y。非 proxy 构建中proxy_needs_return()编译期false,本补丁为 no-op。 - 互斥锁跨核传递、代理迁移频繁的负载:锁持有者与等待者在不同 CPU、等待者被代理迁移到别的 rq 后又被唤醒的场景——每次这样的唤醒都省一轮锁往返 + 一次强制重选核。代理调度面向的用法(ghOSt 式用户态调度、实时/锁密集并发负载)正是此类。
- 返回迁移频率越高收益越大:迁移+唤醒次数与收益成正比;低频场景几乎无感。
| 场景/用例 | 运行环境 | 改进前 | 改进后 |
|---|---|---|---|
| 代理迁移任务被唤醒 | CONFIG_SCHED_PROXY_EXEC=y,跨核锁传递 | 唤醒后在 __schedule 走 proxy_force_return:释放/重取 rq 锁 + task_rq_lock + 强制重选核 | try_to_wake_up 已持锁下出队,正常唤醒流程返回迁移(无额外锁往返) |
| 非 proxy 构建 | CONFIG_SCHED_PROXY_EXEC=n | proxy_needs_return() 编译期 false | no-op(无行为变化) |
说明:补丁未提供基准数据——commit message 无任何 benchmark/数字,仅文字说明"helps performance"(避免 proxy_force_return 的重取锁 + 强制重选核)。上表为"改了什么、省了什么"的定性对比,属逻辑分析(解读(AI 分析)),无量化提升百分比。
① 每次返回迁移省一轮锁释放/重取往返:
proxy_force_return() 释放 rq 锁后要重新拿 task_rq_lock(rq 锁 + pi_lock),期间还有重新校验、select_task_rq、attach;补丁后这些都在 try_to_wake_up 已持有的锁下完成,省去锁的释放/重取以及 pi_lock 的一次额外获取(解读(AI 分析))。② 省一次强制重新选核(pick again loop):原路径触发
proxy_force_return() 后 __schedule() 会回到 pick_again 再次执行 pick_next_task();补丁后返回迁移随正常唤醒完成,不再有这轮额外选核(解读(AI 分析))。③ 对非 proxy 内核为 no-op:
proxy_needs_return() 在非 proxy 构建编译期恒 false,调用为内联折叠的死分支,无行为变化(事实,非推测)。
🔄 方案演进
本补丁是合入主线的最终版,无独立 v1/v2 演进。它属于 sched/proxy(代理调度)上游化系列,演进信息基于本地内核 git 的 commit message(lore 索引不可用,讨论来源为本地 git,已如实标注)。
父提交链:本补丁依赖 f0c1ecde6447(
sched: Rework block_task so it can be directly called,使 block_task() 可被直接调用、不必处理 try_to_block_task() 的失败分支)——这是本补丁能用 block_task(rq, p, TASK_WAKING) 直调出队的前提。2026-05-12:John Stultz(Google)发布代理调度系列(本补丁为系列第 6 补丁,Link 标签)。commit message 注明"本补丁从更大的 proxy 补丁中拆出并大幅重写",原始功绩归属 Peter Zijlstra、Juri Lelli、Valentin Schneider、Connor O'Brien。
后续优化(2026-05-26):系列后续的 abc40cca0efd(
sched/proxy: Optimize try_to_wake_up(),本站另有独立分析)把本补丁在唤醒路径加的防御从句(if (task_is_blocked(p)) clear_task_blocked_on(p, NULL))再删掉——通过让 proxy_deactivate() 保证 cleared blocked_on,把该防御从公共唤醒路径移除。合入:v7.2-rc1 已含本 commit(
git describe --contains 确认为 Linux 7.2)。
try_to_wake_up()(内核最热路径之一)上,但实际是删掉了更重的路径——proxy_force_return() 那轮锁往返 + 强制重选核,换成唤醒路径上一个 proxy_needs_return() 的快速判定(task_cpu(p) != p->wake_cpu,非代理迁移时几乎免费),命中时出队+唤醒在已持锁下完成。等价地,把"调度决策时发现任务不在能跑的核上再补救"换成"唤醒时就把它放到能跑的核上"。lore 不可用,无法回溯邮件列表上是否有更早版本或 review 讨论(解读(AI 分析):该权衡依据 commit message 与代码结构推断)。
注:本 commit 自身为合入主线的最终版,无独立 v1/v2 版本史;以上为"系列整体"的合入节奏与本补丁在系列中的位置。
⚠️ 风险与局限
- 编译前提:内核须
CONFIG_SCHED_PROXY_EXEC=y。非 proxy 构建中proxy_needs_return()编译期恒false,改动为 no-op(仅is_special_task_state()增加TASK_WAKING这一行对全内核生效,但 TASK_WAKING 只在唤醒路径短暂存在、此前本就不属于正常 wait-loop 状态,语义一致)。 - 负载前提:收益与"代理迁移 + 唤醒"频率成正比——跨核互斥锁传递频繁、代理迁移频繁的负载收益明显;低频场景几乎无感。
- 无新配置/无 ABI 变化:纯代码迁移 + 路径删除,升级无需任何操作。
- 唤醒路径多一次快速判定:
ttwu_runnable()现在每次都调用proxy_needs_return()(先task_is_blocked()快判),对非代理迁移任务仅一次静态分支 + 字段读取;命中才走出队。这是对最热路径增加的一点成本,换来的是删除更重的锁往返路径——净收益(解读(AI 分析))。 - 行为一致性:
proxy_deactivate()由"bool + try_to_block_task 失败降级"改为"void + WARN_ON(state==TASK_RUNNING)"——若未来出现 state==TASK_RUNNING 仍调 proxy_deactivate 的路径,会爆 WARN(开发期护栏);try_to_block_task()里也把set_task_blocked_on_waking(p, NULL)改为clear_task_blocked_on(p, NULL)(同一语义的更清晰表达)。
- 依赖系列前置:本补丁依赖代理调度主体机制(
blocked_on、find_proxy_task()、proxy_migrate_task())与父提交 f0c1ecde6447(block_task()可直调)已合入,不能独立回移植到无代理调度的老内核。 - 对用户态透明:无系统调用/API/sysctl 变更,工具链与用户态不受影响。
- 架构无关:改动不涉及任何硬件特性,全架构适用。
Signed-off-by: John Stultz (Google) + Signed-off-by: Peter Zijlstra (Intel);commit message 明确原始功绩归属 Peter Zijlstra / Juri Lelli / Valentin Schneider / Connor O'Brien(代理调度多方长期合作),并注明本补丁"从更大的 proxy 补丁中拆出并大幅重写"。未发现可呈现的公开 review 质疑(解读(AI 分析))。
ttwu_runnable() 热路径增加一次 proxy_needs_return() 快速判定,对非代理迁移任务近乎免费;is_special_task_state() 增加 TASK_WAKING 对全内核生效但语义一致)· 落地场景:最需要关注的是收益仅限 proxy 构建,非 proxy 内核升级无感🔗 交叉引用
try_to_block_task() 主要逻辑并入 block_task(),使本补丁能直调 block_task(rq, p, TASK_WAKING) 出队(本补丁依赖的前置)jstultz@google.com 代理调度系列第 6 补丁(2026-05-12) — 本补丁在邮件列表的入口(本 commit 的 Link 标签)
[日报] sched/proxy: Optimize try_to_wake_up()(abc40cca0efd) — 本站同日独立分析:同一系列的后续优化,移除本补丁加入的唤醒路径防御从句,与本补丁同机制互补
abc40cca0efd sched/proxy: Optimize try_to_wake_up() — 同一系列的后续优化 commit(git.kernel.org 规范链接)
f13beb010e4a 本补丁本体 — 本补丁(git.kernel.org 规范链接)
本站内容均由 AI 基于公开知识辅助生成,仅供学习参考,请勿直接引用作为依据。作者不对信息的准确性、完整性及适用性作保证,亦不对因使用本站内容产生的任何损失承担责任。