Linux 内核调度子系统周报(2026-07-06 ~ 2026-07-12)
本期重点
- 1. sched_ext 子调度器 capability 系列一周迭代 v2→v3→v4→v5——上周的 32 补丁 v1/v2 本周发出 v3、v4、v5 三个版本,sashiko AI 的 review 下改动集中在硬化:cmask 存储校验、bypass 祖先拒绝挂载、pshard 先建后发布、remote-wakeup TOCTOU 用
p->scx.runnable_cpu 闭合、cid-form 调度器禁止直接写 slice/dsq_vtime。 - 2. proxy execution 与 sched_ext 共存方案推进到 v4——Andrea Righi 在上周 v2 基础上出 v3、v4,
SCX_OPS_ENQ_BLOCKED 设计稳定,本周新增 blocked donor 迁移、scheduler 切换时 retained donor 的处理,以及 rq->next_class 在 proxy_reset_donor() 的补设。 - 3. avruntime 单向漂移 RFC 得到 maintainer 回复——上周华为的报告本周 Vincent Guittot 回复,指出
entity_lag() 的 clamp 理论上不该发生、已有一批 queued 改动确保 vlag 不超理论 limit,并提示即便无 clamp div64_long 本身也会丢 vlag;作者补充了精确的 cgroup 布局复现细节。 - 4. sched_domain_shared kmemleak 定位到根因并验证修复——上周 Breno Leitao 报告的 arm64 cpuset rebuild 泄漏,K Prateek Nayak 本周定位到根因(最后一个 SD_SHARE_LLC 与首个 SD_ASYM_CPUCAPACITY_FULL 重叠时
init_sched_domain_shared() 覆盖了 asym 赋值),修复 diff 经 Breno 和 Dietmar Eggemann(Juno 板)验证通过。 - 5. sched_ext 新增一批稳定性修复——PSI trigger 创建死锁(cgroup_mutex/scx_fork_rwsem 锁序反转)、nohz_full 上 finite-slice tick 不恢复、local DSQ dispatch 与 consume 路径的 rq tracking 失同步、
ops.set_weight() 在 ops.disable() 之后被调用。
一、核心进展
子调度器 capability 系列:一周 v2→v5 的 review 硬化
原文[1]
上周 Tejun Heo 的 capability-based CPU 委派模型以 32 补丁 v1/v2 起步(设计见上期周报:把 enqueue/dispatch/occupancy/kick/idle 五条路径统一成 SCX_CAP_ENQ_IMMED/ENQ/PREEMPT 三级能力位,cap 状态按拓扑对齐的 shard 切分,核心侧用 reject DSQ 强制执行)。本周发出 v3、v4、v5,设计本身没有再动,改动集中在 sashiko AI 和 Andrea Righi 的 review 反馈带来的边界硬化。(Tejun Heo,v5 系列)
v3 的改动集中在 BPF 可写面的防越界:scx_cmask_ref 在 _init() 校验声明的 alloc_words 存储并去掉 __counted_by(alloc_words)(编译器会去 bounds-check 一个 BPF 可写的 count);拒绝把子调度器链到处于 bypass 的祖先下,改返回 -EBUSY 而非继承 bypass_depth;pshard 数组先完整构建再发布、读取用 READ_ONCE;ops.sub_caps_updated() 申请私有栈、其输出 cmask 经 scx_cmask_ref 构建而非重读 BPF 可写的 arena header。offline-rq 和 migration_pending 的 insert 强制 admit 到 local DSQ 并清 SCX_ENQ_PREEMPT,消掉一次 reject-DSQ 重入和一个 WARN。原文[2]
v4 推进了上期周报"下周关注点"列出的强制语义验收:新增 patch 把 errno-only 的 sub-enable 失败也记录错误,让 disable 路径跑起来拆除半初始化子调度器(即上期 David Carlier 报的那个 bug,这里 split 出来带 Fixes);阻止 scx_prog_sched() 解析已 disable 的调度器——一个 outlive disable 的程序(它 armed 的 timer、它 loaded 的 tracing 程序)仍可能操作已拆除的 generation,堵住一个 choke point 关闭跨代 pshard[] 越界;新增 prep patch 跟踪任务可运行的 cpu(p->scx.runnable_cpu,rq 锁下盖戳),slice 写路径用它测 rq 归属,闭合一个 remote-wakeup TOCTOU——缓存的 task_rq() 可能 stale-match 一个已迁移的睡眠任务。teardown 路径在 free_kick_syncs() 清 per-cpu kick 状态前 flush pending kick irq_work,让迟到 kick 干净 unlink。原文[3]
v5 在 v4 基础上补两点硬化:新增 patch 在 per-task op 被发到非 owner 调度器时 WARN,两个本就有意的非 owner 调用点改为显式 dispatch(来自 v4 placer-vs-owner review 讨论);新增 prep patch 处理 in-place SAVE/RESTORE requeue 重跑 cid admission 时把任务弹到 reject DSQ 的问题(调度器只持 SCX_CAP_ENQ_IMMED 时),用内部 IGNORE_CAPS 标记免 cap 检查。CONFIG_EXT_SUB_SCHED=n 的 scx_prog_sched() stub 也拒绝 dead root 调度器,与 =y 对齐。v4 的前 9 个补丁已 apply 到 sched_ext/for-7.2-fixes 和 sched_ext/for-7.3 并 drop。原文[1]
一个 review 副产品:sashiko AI 在 review v4 的 08/40(cid-form 调度器禁止直接写 slice/dsq_vtime)时,标出一个 pre-existing Critical 问题——bpf_scx_btf_struct_access_common 对 PTR_TO_BTF_ID | PTR_UNTRUSTED 指针允许 BPF_WRITE,理论上可经伪造地址写内核内存,建议显式检查 PTR_UNTRUSTED flag。原文[4]
proxy execution 与 sched_ext 共存:v3→v4
原文[5]
上周 Andrea Righi 的 v2(10 补丁)确定了 SCX_OPS_ENQ_BLOCKED 的设计:donor→owner 交接建模成函数调用,donor 仍是 BPF 选中的运行调度实体、owner 仅作核心内部执行上下文替换,调度状态记 rq->donor、rq->curr 标识执行上下文,kselftest enq_blocked 用三任务优先级反转验证。本周 v3、v4 设计未变,改动在补全边界。(Andrea Righi,v4 系列)
v3(7 月 6 日)和 v4(7 月 10 日)的关键新补丁:blocked donor 的迁移处理——proxy execution 下 donor 被阻塞后可能需要迁到 owner 所在 CPU,补丁处理这条迁移路径与 sched_ext DSQ/rq 跟踪的交互(原文[6]);scheduler 切换时的 retained donor——donor 已阻塞时若 root 调度器 enable 或任务在 root/sub 调度器间移动,incoming 调度器没设 SCX_OPS_ENQ_BLOCKED 就把 retained donor 移出运行队列走正常 mutex 等待,否则保持 BPF 准入资格。proxy_reset_donor() 里补设 rq->next_class(这个一周前 John Stultz 在 proxy-exec v30 系列里单独发过,见 Fixes: f13beb010e4a,原文[7])。scx_qmap 加 -B 选项演示队列化 mutex-blocked 任务。
mutex owner 的 CPU 可经 scx_bpf_task_proxy_cpu(p) / scx_bpf_task_proxy_cid(p) 查询,BPF 决定怎么用。本周 v4 的 cover letter 把 kselftest 的实测数据贴全了:SCX_OPS_ENQ_BLOCKED 关时 nr_blocked_enqueues=0、mutex hold/wait 平均都在 254ms;开后验证 blocked donor 到达 ops.enqueue() 且 scx_bpf_task_proxy_cpu() 报告共享 CPU。原文[5]
avruntime 单向漂移 RFC:maintainer 回复
原文[8]
上周华为 Chen Jinghuang 的 RFC 指出 reweight_entity() 里 entity_lag() 的边界 limit 在频繁 cgroup reweight 下累积非对称截断误差,导致 curr vruntime 单向下移、全局 avruntime 漂移、极端情况下抑制 entity_tick 抢占(背景见上期周报二、)。本周 Vincent Guittot 回复。
Vincent 的判断是 clamp 理论上不该发生,已有一批 queued 改动确保 vlag 不超理论 limit。他同时提示即便没有 clamp,div64_long(se->vlag * old_weight, weight) 这一步本身就会丢一部分 vlag。他问作者用的内核版本、CPU 数、cgroup 里是否还有其他任务、share 是否设了特定值、slice 是否改过,并建议先关 RUN_TO_PARITY(echo NO_RUN_TO_PARITY > /sys/kernel/debug/sched/features)测试。原文[8]
作者随后补充了精确复现布局:cgroup A 除绑核 CPU 0 的 A1 外,还有 20 个任务在其余 CPU 上频繁 sleep/wake,用来持续触发 A1 的权重调整;cgroup B 只有绑核 CPU 0 的 B1,长睡短醒竞争 A1。作者确认 vlag 确实在 CPU 0 上被 clamp(不是理论上的"不该发生"),并更正了首帖图里 cgroup B 在其他 CPU 也有任务的画法错误。讨论仍在进行,待确认的是 clamp 在该场景下实际发生与 maintainer "理论不该发生" 判断之间的差异,以及 queued 的 vlag limit 改动能否覆盖这条路径。
sched_domain_shared kmemleak:根因定位与修复验证
原文[9]
上周 Breno Leitao 在 arm64 非对称容量系统上用 cpuset 触发 sched-domain rebuild 时复现 struct sched_domain_shared 的 kmemleak(背景:K Prateek Nayak/Andrea Righi 5 月的补丁把 shared 对象从 sd_llc 挪到 sd_asym_cpucapacity,见上期周报一、)。本周 K Prateek 定位到根因。
根因是最后一个 SD_SHARE_LLC 与第一个 SD_ASYM_CPUCAPACITY_FULL 重叠时,init_sched_domain_shared() 对 SD_SHARE_LLC 的赋值覆盖了 claim_asym_sched_domain_shared() 的赋值,留下一个 refcount 非零、不被任何地方使用、又逃过 claim_allocations() 回收的 shared 对象——这就是 kmemleak 看到的 32 字节泄漏。K Prateek 给出修复 diff,Breno 测试通过(Tested-by: Breno Leitao)。Dietmar Eggemann 在 Arm Juno 板({L B B L L L} 拓扑)上确认 boot 阶段(rebuild sched domain 在 CPU capacity setup 和 EAS bringup 之后)和简单 CPU 热插拔都能稳定复现,附加 printks 显示了 shared 分配/覆盖的过程。K Prateek 表示会在 Peter 度假回来后发正式补丁。原文[9]
上周既有线索的本周状态
上周已展开的几条线索本周以 review 为主、无实质新代码:
- • PREEMPT_DYNAMIC 简化(Mark Rutland,5 补丁):上周已发,本周无新版本,等 maintainer 取。
- • EAS 解除 schedutil 硬依赖(Lucas de Lima Nóbrega):上周 Rafael Wysocki 就
sched_energy sysfs 开关语义和文档措辞做多轮 review,本周 Christian Loehle 加入讨论(围绕 artificial EM 语义),作者据反馈出下一版仍在路上。 - • cpu_preferred_mask + steal backoff v6(Shrikanth Hegde):上周已出 v6,本周无新版本,MAINTAINERS 归属(
drivers/virt/steal_monitor 落点)仍待定。
二、重要 Bug 修复
sched_ext:PSI trigger 创建死锁
原文[10]
【问题】scx_root_enable_workfn() 先拿 scx_fork_rwsem 写锁再拿 cgroup_mutex。commit a5b98009f16d ("sched/psi: fix race between file release and pressure write") 之后,pressure_write() 持 cgroup_mutex 跨 psi_trigger_create(),后者可能 kthread_create() 创建 psimon 内核线程;kthreadd 的 fork 进入 scx_pre_fork() 等 scx_fork_rwsem 读侧。
【根因】锁序反转形成三方死锁:enable worker 持 scx_fork_rwsem 等 cgroup_mutex,PSI writer 持 cgroup_mutex 等 psimon 创建完成,任意并发 fork 在 scx_pre_fork() 上阻塞。hung-task 捕获到三方栈:scx_enable_help(等 mutex)、systemd(等 completion,psi_trigger_create→kthread_create_on_node)、python3(等 percpu_rwsem 读侧,scx_pre_fork→sched_fork→copy_process)。
【修复方案】在 scx_root_enable_workfn() 里把 cgroup_mutex(scx_cgroup_lock())提到 scx_fork_rwsem 写锁之前,释放顺序反转,保留 cgroup/task 初始化的互斥。
【影响范围】作者在 128-CPU AMD EPYC 7713 上并发启用 scx_lavd 与写 cgroup PSI trigger 文件复现,无关任务堆在 scx_pre_fork()、进程创建停止。Fixes: a5b98009f16d,Cc: stable,已发补丁。(Matt Fleming / Cloudflare)
sched_ext:nohz_full 上 finite-slice tick 不恢复
原文[11]
【问题】finite slice 的 EXT 任务调度到 nohz_full CPU 上时,调度器错误地保持 tick 关闭。
【根因】set_next_task_scx() 在 __schedule() 更新 rq->curr 之前更新 tick 依赖。从非 EXT 任务(如 idle)切到 finite-slice EXT 任务时,sched_update_tick_dependency() 看到的还是 outgoing 任务(idle),tick 不开,incoming 任务跑过它的 slice。
【修复方案】对 finite-slice EXT 任务总是开启调度 tick。附 kselftest nohz_tick 复现并验证:修复前 worker 只收到 1 个 scheduler tick(测试 FAIL),修复后 CPU 1 收到 4 个 finite-slice tick(PASS)。一周内出到 v3(for-7.2-fixes)。(Andrea Righi,2 补丁系列)原文[12]
sched_ext:local DSQ dispatch 与 consume 路径的 rq tracking
原文[13]
【问题】dispatch_to_local_dsq() 从 scx_bpf_dsq_move_to_local() 在 ops.dispatch() 已记录当前 rq 时运行。把任务移到 local DSQ 可能在同步调 ops.dequeue() 前切到源或目的 rq,嵌套回调保存并恢复记录的 rq,若中途换了锁,恢复的是不再持有的 rq,update_locked_rq() 触发 lockdep assertion。
ops.dispatch()
scx_bpf_dsq_move_to_local()
finish_dispatch()
dispatch_to_local_dsq() ← 这里可能切 rq 锁
scx_dispatch_enqueue()
call_task_dequeue()
SCX_CALL_OP_TASK(dequeue, locked_rq, ...) ← 嵌套回调恢复一个已不持有的 rq
【修复方案】切锁前清掉 tracked rq(update_locked_rq(NULL)),重新拿到原 rq 后才恢复。Fixes: 7fb39e4eb4c3,Cc: stable # 7.1+。原文[13]
consume 路径有同类问题(consume_remote_task() 在从 DSQ 摘除远程任务并锁 src_rq 前就释放 this_rq,scx_locked_rq() 一直指向 this_rq,随后的 switch_rq_lock(src_rq, this_rq) 因 guard 不匹配无法更新 tracking,src_rq 持有期间 tracking stale)。修复改用 unlink_dsq_and_switch_rq_lock() 保持 this_rq 锁直到任务摘除、DSQ 锁释放,再 switch_rq_lock() 直接切 src_rq,丢失 dequeue 竞争时同样用该 helper 恢复。Suggested-by: Tejun Heo。原文[14]
两条根因相同:嵌套 callback 在换 rq 锁时 tracked rq 失同步,统一为切锁前清 tracking、重新持锁后恢复。
sched_ext:ops.set_weight() 在 ops.disable() 之后被调用
原文[15]
【问题】从 sched_ext 切走 sched_class 时,__sched_setscheduler() 里 scx_disable_task()(调 ops.disable())发生在 reweight_task_scx()(调 ops.set_weight())之前。
sched_change_begin()
switched_from_scx() → scx_disable_task(p) → ops.disable(p)
__setscheduler_params()
set_load_weight() → reweight_task_scx(p) → ops.set_weight(p) ← 在 disable 之后
p->sched_class = next_class
【根因】违反 callback 语义——ops.disable() 之后应只跟 ops.exit_task() 或 ops.enable(),不应再回 ops.set_weight()。
【修复方案】reweight_task_scx() 对 SCX_TASK_ENABLED 之外的状态跳过 ops.set_weight(),任务重返 SCX 时 scx_enable_task() 会重算 weight。Tejun Heo 已 apply 到 sched_ext/for-7.2-fixes。
【影响范围】Fixes: 637b0682821b ("sched: Fold sched_class::switch{ing,ed}_{to,from}() into the change pattern"),Cc: stable # v6.19+,属 v6.19 起的回归。(Kuba Piecuch)
proxy execution:__clear_task_blocked_on() WARNING
原文[16]
【问题】arm64、内核 6.18.21(android17-6.18)、开启 proxy execution 支持,probe 阶段触发 kernel panic:__clear_task_blocked_on() 的 WARN_ON_ONCE 命中,因 panic_on_warn 直接 panic。调用栈从 modprobe → device_create → kernfs_link_sibling → up_write → rwsem_mark_wake 命中告警。
【根因】__clear_task_blocked_on() 检查 m && p->blocked_on.lock && p->blocked_on.lock != m && p->blocked_on.lock != PROXY_WAKING,即清空的 blocked_on 关系与传入的锁不一致。该检查属于 proxy execution 引入的 blocked_on 机制(与上期周报一、的 proxy-exec 系列同源)。
【影响范围】报告者列出 v7.2 mainline 里两个尚未回到 6.18.21 的 sched.h 相关 commit(f13beb010e4a、4c2a20413d7f)询问是否相关。当前是 bug 报告阶段(报告者用 android17-6.18 + proxy exex support),主线修复尚未确认。
sched_ext:子调度器 enable 失败未 arm exit
原文[17]
这条上期周报二、已展开。本周的进展是 Tejun Heo 回复确认诊断正确,并指该修复已折进 capability v2 系列的第 19 个补丁(per-shard cap delegation for sub-schedulers)。它随 capability 系列一起进入 v3→v4→v5 的迭代,并在 v4 被 split 成独立 patch 带 Fixes: tag(见上文 v4 changelog 的 patch 01)。原文[18]
三、sched_ext 进展
核心功能演进
本周核心演进的主线是上面两节展开的 capability 系列(v2→v5)和 proxy execution 共存(v3→v4)。承接上期周报的判断——sched_ext 正从"单个 root 调度器"走向"层级化、可在子调度器间按 capability 划分 CPU、并能与 proxy execution 共存"——本周两条线继续迭代,设计层面没有再动,改动集中在 review 反馈的硬化。
Add tracepoint for scheduler exit(Pat Somaru)——sched_ext 调度器退出(SCX 退出/unload)时,scx_dump 提供的是静态的 kernel + BPF 程序状态。补丁在 scx_claim_exit() 加 sched_ext_exit tracepoint,让 BPF 程序能在退出时刻动态观测调度器自身状态。Tejun Heo 在 review 中建议 hook 点放在 scx_claim_exit() 路径,并讨论了放在哪一层更合适。原文[19]
稳定性修复
本周 sched_ext 稳定性修复集中在两条主题:nohz_full 的 tick 行为(见二、nohz_full finite-slice tick),和 rq lock tracking(见二、local DSQ + consume 路径)。再加上 PSI 死锁(见二、)、set_weight/disable 顺序(见二、)、子调度器 enable 失败 arm exit(已折进 capability 系列)。本周修复数量多于上周,多数带 Fixes: 和 Cc: stable,集中在 dispatch/consume/enable/teardown 路径的边界条件。
生态与工具改进
selftests/sched_ext: Fix bpf_link leak on early return in prog_run(Liang Luo,KylinOS)——prog_run 的 run() 里 bpf_link 早 attach、只在成功路径 destroy,三条 SCX_EQ 断言展开成直接 return SCX_TEST_FAIL,任一触发就跳过 bpf_link__destroy(),BPF 调度器保持 loaded,后续测试因 SCX 不在 DISABLED 状态全 attach 失败。改成显式检查跳到统一 out label 做清理,匹配 cyclic_kick_wait.c 的写法。原文[20]
Documentation: Fix ops table header reference(luoliang,KylinOS)——修 sched_ext 文档里 ops 表头引用。原文[21]
Fix typo in scx_bpf_dsq_insert() comment(luoliang,KylinOS)——注释笔误。原文[22]
四、工具链与调试
cpufreq: schedutil: 修复 sugov_iowait_apply() 自相矛盾的注释(Zhongqiu Han,高通)——上周已发,本周 Rafael Wysocki 给意见、Christian Loehle 已 Reviewed-by。kerneldoc 说 IO boost 值在 sugov_iowait_apply() 里既增又减,自相矛盾且前半错:该函数只减,增加发生在 sugov_iowait_boost()。改注释指向正确函数。Fixes: fd7d5287fd65,无功能改动。原文[23]
sched: Remove unused tryget_task_struct()(Zhan Xusheng,小米)——该 helper 当初为 sched_ext 加(a8532fac7b5d),所有用户后被改成 get_task_struct()(fbe3fb103596),已无调用方,删除。无功能改动。原文[24]
五、下周关注点
- 1. capability 系列 v6 或合入——v5 已把 v4 review 的硬化点(placer-vs-owner WARN、IGNORE_CAPS)落地,按本周的迭代节奏,下周可能见 v6 或开始进
for-7.3。关注 sashiko AI 标出的 bpf_scx_btf_struct_access_common PTR_UNTRUSTED 问题是否有独立修复。 - 2. proxy execution + sched_ext v4 之后——donor 生命周期补全后,Peter Zijlstra 是否接受函数调用模型;以及
__clear_task_blocked_on() WARNING 在主线的对应修复是否随 proxy-exec 系列进来。 - 3. avruntime 漂移 RFC 的走向——maintainer "clamp 理论不该发生" 与作者实测 "clamp 确实发生" 的差异如何解决:是 queued vlag limit 改动覆盖,还是
div64_long 精度损失需要单独处理。 - 4. sched_domain_shared kmemleak 正式补丁——K Prateek 说在 Peter 度假回来后发,关注补丁形态和是否标
Fixes/Cc: stable、port 到哪些 stable 版本。 - 5. sched_ext rq tracking 的统一硬化——local DSQ 和 consume 路径两条同根因修复之后,rq 锁的跨回调跟踪是否还有其他路径暴露同类问题。
引用链接
[1] 原文: https://lore.kernel.org/all/20260709225041.1695495-1-tj@kernel.org/
[2] 原文: https://lore.kernel.org/all/20260707001229.1410929-1-tj@kernel.org/
[3] 原文: https://lore.kernel.org/all/20260708212429.3405787-1-tj@kernel.org/
[4] 原文: https://lore.kernel.org/all/20260708214121.ABDD61F000E9@smtp.kernel.org/
[5] 原文: https://lore.kernel.org/all/20260710083913.30573-1-arighi@nvidia.com/
[6] 原文: https://lore.kernel.org/all/20260706070410.282826-9-arighi@nvidia.com/
[7] 原文: https://lore.kernel.org/all/20260701214615.3773339-5-jstultz@google.com/
[8] 原文: https://lore.kernel.org/all/CAKfTPtDB7ET=Ae8bdOFpzds6oWd8BukJtku1oTtC=T2KUJCa6Q@mail.gmail.com/
[9] 原文: https://lore.kernel.org/all/fc6fe063-2983-4d1c-b317-382d153601bb@amd.com/
[10] 原文: https://lore.kernel.org/all/20260710100441.2653477-1-matt@readmodwrite.com/
[11] 原文: https://lore.kernel.org/all/20260706162819.650155-1-arighi@nvidia.com/
[12] 原文: https://lore.kernel.org/all/20260706162819.650155-2-arighi@nvidia.com/
[13] 原文: https://lore.kernel.org/all/20260707135854.1379730-1-arighi@nvidia.com/
[14] 原文: https://lore.kernel.org/all/20260709051708.306636-1-arighi@nvidia.com/
[15] 原文: https://lore.kernel.org/all/20260710144342.3802587-1-jpiecuch@google.com/
[16] 原文: https://lore.kernel.org/all/20260708135054.GA1793@KORCO121415.samsungds.net/
[17] 原文: https://lore.kernel.org/all/20260703191002.804763-1-devnexen@gmail.com/
[18] 原文: https://lore.kernel.org/all/9fd7850724a5993f7ef8e151374f72b4@kernel.org/
[19] 原文: https://lore.kernel.org/all/20260512055632.1096713-1-patso@likewhatevs.io/
[20] 原文: https://lore.kernel.org/all/20260709100340.706670-1-luoliang@kylinos.cn/
[21] 原文: https://lore.kernel.org/all/20260707094538.3033292-1-luoliang@kylinos.cn/
[22] 原文: https://lore.kernel.org/all/20260709080205.534892-1-luoliang@kylinos.cn/
[23] 原文: https://lore.kernel.org/all/20260703092433.4080165-1-zhongqiu.han@oss.qualcomm.com/
[24] 原文: https://lore.kernel.org/all/20260708023011.652637-1-zhanxusheng@xiaomi.com/