~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/translations/zh_CN/scheduler/sched-domains.rst

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 .. SPDX-License-Identifier: GPL-2.0
  2 .. include:: ../disclaimer-zh_CN.rst
  3 
  4 :Original: Documentation/scheduler/sched-domains.rst
  5 
  6 :翻译:
  7 
  8   唐艺舟 Tang Yizhou <tangyeechou@gmail.com>
  9 
 10 :校译:
 11 
 12   司延腾 Yanteng Si <siyanteng@loongson.cn>
 13 
 14 ======
 15 调度域
 16 ======
 17 
 18 每个CPU有一个“基”调度域(struct sched_domain)。调度域层次结构从基调度域构建而来,可
 19 通过->parent指针自下而上遍历。->parent必须以NULL结尾,调度域结构体必须是per-CPU的,
 20 因为它们无锁更新。
 21 
 22 每个调度域管辖数个CPU(存储在->span字段中)。一个调度域的span必须是它的子调度域span的
 23 超集(如有需求出现,这个限制可以放宽)。CPU i的基调度域必须至少管辖CPU i。每个CPU的
 24 顶层调度域通常将会管辖系统中的全部CPU,尽管严格来说这不是必须的,假如是这样,会导致某些
 25 CPU出现永远不会被指定任务运行的情况,直到允许的CPU掩码被显式设定。调度域的span字段意味
 26 着“在这些CPU中做进程负载均衡”。
 27 
 28 每个调度域必须具有一个或多个CPU调度组(struct sched_group),它们以单向循环链表的形式
 29 组织,存储在->groups指针中。这些组的CPU掩码的并集必须和调度域span字段一致。->groups
 30 指针指向的这些组包含的CPU,必须被调度域管辖。组包含的是只读数据,被创建之后,可能被多个
 31 CPU共享。任意两个组的CPU掩码的交集不一定为空,如果是这种情况,对应调度域的SD_OVERLAP
 32 标志位被设置,它管辖的调度组可能不能在多个CPU中共享。
 33 
 34 调度域中的负载均衡发生在调度组中。也就是说,每个组被视为一个实体。组的负载被定义为它
 35 管辖的每个CPU的负载之和。仅当组的负载不均衡后,任务才在组之间发生迁移。
 36 
 37 在kernel/sched/core.c中,sched_balance_trigger()在每个CPU上通过sched_tick()
 38 周期执行。在当前运行队列下一个定期调度再平衡事件到达后,它引发一个软中断。负载均衡真正
 39 的工作由sched_balance_softirq()->sched_balance_domains()完成,在软中断上下文中执行
 40 (SCHED_SOFTIRQ)。
 41 
 42 后一个函数有两个入参:当前CPU的运行队列、它在sched_tick()调用时是否空闲。函数会从
 43 当前CPU所在的基调度域开始迭代执行,并沿着parent指针链向上进入更高层级的调度域。在迭代
 44 过程中,函数会检查当前调度域是否已经耗尽了再平衡的时间间隔,如果是,它在该调度域运行
 45 sched_balance_rq()。接下来它检查父调度域(如果存在),再后来父调度域的父调度域,以此类推。
 46 
 47 起初,sched_balance_rq()查找当前调度域中最繁忙的调度组。如果成功,在该调度组管辖的全部CPU
 48 的运行队列中找出最繁忙的运行队列。如能找到,对当前的CPU运行队列和新找到的最繁忙运行
 49 队列均加锁,并把任务从最繁忙队列中迁移到当前CPU上。被迁移的任务数量等于在先前迭代执行
 50 中计算出的该调度域的调度组的不均衡值。
 51 
 52 实现调度域
 53 ==========
 54 
 55 基调度域会管辖CPU层次结构中的第一层。对于超线程(SMT)而言,基调度域将会管辖同一个物理
 56 CPU的全部虚拟CPU,每个虚拟CPU对应一个调度组。
 57 
 58 在SMP中,基调度域的父调度域将会管辖同一个结点中的全部物理CPU,每个调度组对应一个物理CPU。
 59 接下来,如果是非统一内存访问(NUMA)系统,SMP调度域的父调度域将管辖整个机器,一个结点的
 60 CPU掩码对应一个调度组。亦或,你可以使用多级NUMA;举例来说Opteron处理器,可能仅用一个
 61 调度域来覆盖它的一个NUMA层级。
 62 
 63 实现者需要阅读include/linux/sched/sd_flags.h的注释:读SD_*来了解具体情况以及调度域的
 64 SD标志位调节了哪些东西。
 65 
 66 体系结构可以把指定的拓扑层级的通用调度域构建器和默认的SD标志位覆盖掉,方法是创建一个
 67 sched_domain_topology_level数组,并以该数组作为入参调用set_sched_topology()。
 68 
 69 调度域调试基础设施可以通过CONFIG_SCHED_DEBUG开启,并在开机启动命令行中增加
 70 “sched_verbose”。如果你忘记调整开机启动命令行了,也可以打开
 71 /sys/kernel/debug/sched/verbose开关。这将开启调度域错误检查的解析,它应该能捕获(上文
 72 描述过的)绝大多数错误,同时以可视化格式打印调度域的结构。

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php