当前位置: 首页 > news >正文

Linux sched_core核心调度cookie匹配与强制idle

Linux sched_core核心调度cookie匹配与强制idle

sched_core是CONFIG_SCHED_CORE引入的SMT同步调度机制,解决超线程环境下同核两个硬件线程执行不同trust domain任务的侧信道安全问题。每个task_struct携带一个unsigned long cookie(core_cookie),通过prctl(PR_SET_CORE_SCHED_CTX)或cgroup的cpu.core_tag接口设置。核心调度决策的核心约束是:同一个物理核心上的两个硬件线程(CPU)必须同时运行cookie相同的任务,否则其中一个线程必须强制idle。

```c
struct task_struct {
#ifdef CONFIG_SCHED_CORE
unsigned long core_cookie; /* 核心调度cookie */
#endif
};

struct rq {
#ifdef CONFIG_SCHED_CORE
unsigned int core_enabled; /* 该CPU是否开启了核心调度 */
unsigned int core_forceidle; /* 是否处于强制idle状态 */
unsigned int core_forceidle_occupation;
struct cpumask *core_pick_mask; /* 已挑选的任务集合 */
#endif
};
```

核心调度的任务选择入口在__schedule()的pick_next_task()中。标准pick_next_task经过stop_sched_class -> idle_sched_class -> ... -> fair_sched_class的优先级遍历,在sched_core模式下被替换为sched_core_pick_next_task()。该函数为同一个物理核心上的每个CPU选择任务时,强制校验cookie匹配约束。

```c
#ifdef CONFIG_SCHED_CORE
static struct task_struct *
sched_core_pick_next_task(struct rq *rq)
{
struct task_struct *next, *p;
struct rq *core_rq;
int cpu, core_cpu = cpu_of(rq);

if (!rq->core_enabled)
return pick_next_task(rq);

core_rq = rq->core_rq; /* 指向同核master rq */
if (rq != core_rq)
return core_rq->core_pick_task; /* 从伙伴CPU的pick结果获取 */

/* master CPU负责为整个核心做cookie匹配 */
for_each_cpu_and(cpu, cpu_smt_mask(core_cpu), cpu_online_mask) {
struct rq *sibling_rq = cpu_rq(cpu);
struct task_struct *sibling_curr = sibling_rq->curr;

/* 优先选择cookie匹配的任务 */
next = pick_next_task(sibling_rq);
if (next && next->core_cookie != sibling_curr->core_cookie) {
/* cookie不匹配:查找匹配cookie的任务 */
for_each_class(class) {
p = class->pick_task(sibling_rq);
if (p && p->core_cookie == sibling_curr->core_cookie) {
next = p;
break;
}
}
}

if (!next || next->core_cookie != core_rq->core_pick_cookie) {
/* 找不到匹配cookie的任务,强制idle */
next = idle_sched_class.pick_task(sibling_rq);
sibling_rq->core_forceidle = 1;
}

__set_bit(cpu, core_rq->core_pick_mask);
core_rq->core_pick_task = next;
}

return core_rq->core_pick_task;
}
```

sched_core强制idle的触发条件是:一个CPU选择了某个cookie的任务,但核心上其他CPU在各自runqueue中都找不到相同cookie的可运行任务。此时pick_result中的core_forceidle被置位。强制idle状态下,当前CPU的实际C-state不会进入深睡眠(因为核心上的另一个线程还在运行共享L1 cache),idle thread通过play_dead或mwait的c1e浅睡眠轮询等待cookie匹配的任务到达。

```c
/*
* sched_core的核心选择逻辑——pick_task迭代所有调度类
* 返回与给定cookie匹配的任务,找不到则返回NULL
*/
for_each_class(class) {
p = class->pick_task(rq);
if (p && (!cookie || p->core_cookie == cookie)) {
if (cookie)
cookie_found = true;
next = p;
break;
}
}

/* 如果找不到匹配cookie的任务,强制idle */
if (cookie && !cookie_found) {
rq->core_forceidle = 1;
next = idle_sched_class.pick_task(rq);
}
```

cookie匹配的粒度是per-task。当任务通过execve()执行新程序时,core_cookie不会被清除——它继承自父进程的prctl设置。但set_user()或seccomp事件可能通过security_task_alloc()钩子重置cookie。一个常见竞态是:核心上的CPU0持有cookie A的任务正在运行,CPU1的任务完成IO后wakeup但其cookie为B。此时CPU1在scheduler_tick的resched路径中检查到core力core_forceidle标记,选择idle线程。但CPU1的__schedule()需要等待CPU0先完成当前调度周期——因为sched_core要求核心上所有CPU的pick_task在同一个rq->lock临界区内进行。

core scheduler的deactivation路径也涉及cookie检查。当任务调用deactivate_task()(如退出或阻塞)时,如果该任务是核心上最后一个携带特定cookie的任务,则核心上所有CPU必须被重新pick_task——否则另一个CPU可能仍然拿着该cookie的idle强制并在等待一个已退出的任务。dequeue_task中通过sched_core_dequeue()检查是否需要触发core re-pick:

```c
static inline void sched_core_dequeue(struct rq *rq, struct task_struct *p)
{
if (!sched_core_enabled(rq))
return;

/*
* 如果该任务是当前核心上该cookie的唯一任务,
* 标记core resched让所有CPU重新pick
*/
if (p->core_cookie && task_on_rq_queued(p)) {
struct task_struct *tmp;
bool last = true;

for_each_online_cpu(cpu) {
if (cpu == cpu_of(rq))
continue;
tmp = cpu_rq(cpu)->curr;
if (tmp->core_cookie == p->core_cookie && task_on_rq_queued(tmp)) {
last = false;
break;
}
}

if (last || rq->core_forceidle) {
/* 唤醒所有SMT兄弟CPU重新选择 */
smt_mask = cpu_smt_mask(cpu_of(rq));
for_each_cpu_and(i, smt_mask, cpu_online_mask)
resched_curr(cpu_rq(i));
}
}
}
```

sched_core的migration偏移处理存在一个显著性能折衷。当任务从cookie A的CPU migrate到cookie B的CPU时(通过load balance),它必须等待核心上其他所有CPU的当前任务完成——因为pick_next_task时无法在同一核心上混合不同cookie。社区解决方向是引入core-wide wakeup,即wakeup路径检测到目标核心上正在运行不同cookie的任务时,不立即唤醒而延迟到核心空闲。这通过TTWU_QUEUED -> try_steal_cookie机制实现,但仍处于experimental状态。

另一个边界条件涉及PI优先级继承。持有mutex的任务cookie为A但被cookie B的高优先级任务等待时,核心调度无法直接进行——因为mutex unlock发生在不同cookie的上下文。sched_core通过core_waiters计数器追踪:当核心上等待锁的线程与持有者cookie不同时,强制idle策略不应生效(任务必须运行才能释放锁),否则会导致ABBA死锁。

http://www.jsqmd.com/news/1062107/

相关文章:

  • 2026杭州二手名表行业头部机构观察:综合实力对比与发展趋势 - 开心测评
  • 长三角水稻除草剂厂家推荐:江苏响当当农资专研产品「管大侠」直击农户痛点 - 小熊打盹
  • Kinetis SDK操作系统抽象层与FlexIO驱动跨RTOS移植实战
  • 计算机视觉中的天气分类:风格特征与多任务学习实践
  • 2026年支持回放功能的企业直播软件排行解析 - 互联网科技品牌测评
  • 2026依托1536笔成交档案:沈阳报价真实黄金回收机构榜单 - 奢品小当家
  • 2026年全国美容院直播平台排行:私域营销工具适配解析 - 互联网科技品牌测评
  • 从零搭建Robot Framework自动化测试环境:Python 3.8+VS Code实战指南
  • 终极Windows系统管理工具:WinUtil一键搞定软件安装与系统优化
  • 2026 杭州黄金回收防骗大全:实地走访 6 家正规机构拆解套路,黄金出手多卖几千块 - 开心测评
  • ESP32-C2在Arduino-ESP32中为何被隐藏?解锁低成本WiFi芯片的完整开发指南
  • 【2026年6月重磅速报】广州亨得利维修避坑最实用的技巧:正规流程vs非正规套路全对比 - 亨得利官方售后
  • 海口秀英区黄金回收指南:永兴、昌盛、奢佳美三大正规渠道实测 - 行行星
  • 2026年河北节水灌溉设备选购指南:智能水肥一体化方案深度横评 - 企业名录优选推荐
  • 3个革命性技巧:彻底改变你的Windows文件管理方式
  • 浙江企业必看!2026 宁波 / 嘉兴 / 温州GEO优化公司推荐 AI 搜索 SEO 落地服务商 - 商业新知
  • 低氘水生产线厂家有哪些?结合鲁齐天做设备选型解析,梳理多家供货企业 - 品牌推荐大师
  • 如何用AI一键生成爆款短视频?MoneyPrinterTurbo完整指南
  • 2026橡胶密封圈厂家推荐排行 品质标杆与定制化服务深度评测 - 极欧测评
  • ATmega406 TWI多主机系统设计:从I²C数据包解析到总线仲裁实战
  • 上海复印机打印机扫描仪上门维修全解析:沁暇办公专业服务体系与行业标准指南 - 资讯报道
  • Geoserver高危漏洞CVE-2023-51444复现:任意文件上传与Webshell利用分析
  • 非师范生跨专业考编结构化面试何时该报班?2026年备考决策与机构能力评估指南 - 科技焦点
  • ChatGPT+DataForSEO搜索数据集成实战指南
  • 2026年兰州商铺水晶卷帘门定制 临街门店电动卷闸门安装 - 企业名录优选推荐
  • 家庭/银发/暑期出游纯玩首选:2026最新云南旅游品质服务机构六维盘点 - 深度智识库
  • 2026年陕西商事纠纷律师怎么选?西安股权纠纷、建工合同与财税合规深度指南 - 优质企业观察收录
  • 2026年鞍山市本地人必选的水质检测专业机构TOP7推荐!生活饮用水检测、直饮水检测、污水废水检测、矿泉水检测,正规CMA资质检测公司排名推荐 (2026年7月水质检测最新深度调研方案) - 一休咨询
  • FastANI终极指南:5分钟掌握微生物基因组相似性快速分析
  • 押金收据丢了怎么登报?官方认可办理方法流程 - 速递信息