1*4788a136SYanteng Si.. include:: ../disclaimer-zh_CN.rst 2*4788a136SYanteng Si 3*4788a136SYanteng Si:Original: Documentation/scheduler/sched-bwc.rst 4*4788a136SYanteng Si 5*4788a136SYanteng Si:翻译: 6*4788a136SYanteng Si 7*4788a136SYanteng Si 司延腾 Yanteng Si <siyanteng@loongson.cn> 8*4788a136SYanteng Si 9*4788a136SYanteng Si:校译: 10*4788a136SYanteng Si 11*4788a136SYanteng Si 12*4788a136SYanteng Si 13*4788a136SYanteng Si============ 14*4788a136SYanteng SiCFS 带宽控制 15*4788a136SYanteng Si============ 16*4788a136SYanteng Si 17*4788a136SYanteng Si.. note:: 18*4788a136SYanteng Si 本文只讨论了SCHED_NORMAL的CPU带宽控制。 19*4788a136SYanteng Si SCHED_RT的情况在Documentation/scheduler/sched-rt-group.rst中有涉及。 20*4788a136SYanteng Si 21*4788a136SYanteng SiCFS带宽控制是一个CONFIG_FAIR_GROUP_SCHED扩展,它允许指定一个组或层次的最大CPU带宽。 22*4788a136SYanteng Si 23*4788a136SYanteng Si一个组允许的带宽是用配额和周期指定的。在每个给定的”周期“(微秒)内,一个任务组被分配多 24*4788a136SYanteng Si达“配额”微秒的CPU时间。当cgroup中的线程可运行时,该配额以时间片段的方式被分配到每个cpu 25*4788a136SYanteng Si运行队列中。一旦所有的配额被分配,任何额外的配额请求将导致这些线程被限流。被限流的线程将不 26*4788a136SYanteng Si能再次运行,直到下一个时期的配额得到补充。 27*4788a136SYanteng Si 28*4788a136SYanteng Si一个组的未分配配额是全局跟踪的,在每个周期边界被刷新为cfs_quota单元。当线程消耗这个带宽时, 29*4788a136SYanteng Si它以需求为基础被转移到cpu-local“筒仓”,在每次更新中转移的数量是可调整的,被描述为“片“(时 30*4788a136SYanteng Si间片)。 31*4788a136SYanteng Si 32*4788a136SYanteng Si突发特性 33*4788a136SYanteng Si-------- 34*4788a136SYanteng Si现在这个功能借来的时间是用于防范我们对未来的低估,代价是对其他系统用户的干扰增加。所有这些都 35*4788a136SYanteng Si有很好的限制。 36*4788a136SYanteng Si 37*4788a136SYanteng Si传统的(UP-EDF)带宽控制是这样的: 38*4788a136SYanteng Si 39*4788a136SYanteng Si (U = \Sum u_i) <= 1 40*4788a136SYanteng Si 41*4788a136SYanteng Si这既保证了每个最后期限的实现,也保证了系统的稳定。毕竟,如果U>1,那么每一秒钟的壁钟时间,我 42*4788a136SYanteng Si们就必须运行超过一秒钟的程序时间,显然会错过我们的最后期限,但下一个最后期限会更远,永远没有 43*4788a136SYanteng Si时间赶上,无边无界的失败。 44*4788a136SYanteng Si 45*4788a136SYanteng Si突发特性观察到工作负载并不总是执行全部配额;这使得人们可以将u_i描述为一个统计分布。 46*4788a136SYanteng Si 47*4788a136SYanteng Si例如,让u_i = {x,e}_i,其中x是p(95)和x+e p(100)(传统的WCET)。这实际上允许u更小,提 48*4788a136SYanteng Si高了效率(我们可以在系统中打包更多的任务),但代价是当所有的概率都一致时,会错过最后期限。然 49*4788a136SYanteng Si而,它确实保持了稳定性,因为只要我们的x高于平均水平,每一次超限都必须与低估相匹配。 50*4788a136SYanteng Si 51*4788a136SYanteng Si也就是说,假设我们有两个任务,都指定了一个p(95)值,那么我们有一个p(95)*p(95)=90.25%的机 52*4788a136SYanteng Si会,两个任务都在他们的配额内,一切都很好。同时,我们有一个p(5)p(5)=0.25%的机会,两个任务同 53*4788a136SYanteng Si时超过他们的配额(保证最后期限失败)。在这两者之间有一个阈值,其中一个超过了,而另一个没有不足, 54*4788a136SYanteng Si无法补偿;这取决于具体的CDFs。 55*4788a136SYanteng Si 56*4788a136SYanteng Si同时,我们可以说,最坏的情况下的截止日期失败,将是Sum e_i;也就是说,有一个有界的迟延(在假 57*4788a136SYanteng Si设x+e确实是WCET的情况下)。 58*4788a136SYanteng Si 59*4788a136SYanteng Si使用突发时的干扰是由错过最后期限的可能性和平均WCET来评价的。测试结果表明,当有许多cgroup或 60*4788a136SYanteng SiCPU未被充分利用时,干扰是有限的。更多的细节显示在: 61*4788a136SYanteng Sihttps://lore.kernel.org/lkml/5371BD36-55AE-4F71-B9D7-B86DC32E3D2B@linux.alibaba.com/ 62*4788a136SYanteng Si 63*4788a136SYanteng Si管理 64*4788a136SYanteng Si---- 65*4788a136SYanteng Si配额、周期和突发是在cpu子系统内通过cgroupfs管理的。 66*4788a136SYanteng Si 67*4788a136SYanteng Si.. note:: 68*4788a136SYanteng Si 本节描述的cgroupfs文件只适用于cgroup v1.对于cgroup v2,请参阅Control Group v2。 69*4788a136SYanteng Si :ref:`Documentation/admin-guide/cgroup-v2.rst <cgroup-v2-cpu>`. 70*4788a136SYanteng Si 71*4788a136SYanteng Si- cpu.cfs_quota_us:在一个时期内补充的运行时间(微秒)。 72*4788a136SYanteng Si- cpu.cfs_period_us:一个周期的长度(微秒)。 73*4788a136SYanteng Si- cpu.stat: 输出节流统计数据[下面进一步解释] 74*4788a136SYanteng Si- cpu.cfs_burst_us:最大累积运行时间(微秒)。 75*4788a136SYanteng Si 76*4788a136SYanteng Si默认值是:: 77*4788a136SYanteng Si 78*4788a136SYanteng Si cpu.cfs_period_us=100ms 79*4788a136SYanteng Si cpu.cfs_quota_us=-1 80*4788a136SYanteng Si cpu.cfs_burst_us=0 81*4788a136SYanteng Si 82*4788a136SYanteng Sicpu.cfs_quota_us的值为-1表示该组没有任何带宽限制,这样的组被描述为无限制的带宽组。这代表 83*4788a136SYanteng Si了CFS的传统工作保护行为。 84*4788a136SYanteng Si 85*4788a136SYanteng Si写入不小于cpu.cfs_burst_us的任何(有效的)正值将配发指定的带宽限制。该配额或周期允许的最 86*4788a136SYanteng Si小配额是1ms。周期长度也有一个1s的上限。当带宽限制以分层方式使用时,存在额外的限制,这些在下 87*4788a136SYanteng Si面有更详细的解释。 88*4788a136SYanteng Si 89*4788a136SYanteng Si向cpu.cfs_quota_us写入任何负值都会移除带宽限制,并使组再次回到无限制的状态。 90*4788a136SYanteng Si 91*4788a136SYanteng Sicpu.cfs_burst_us的值为0表示该组不能积累任何未使用的带宽。它使得CFS的传统带宽控制行为没有 92*4788a136SYanteng Si改变。将不大于 cpu.cfs_quota_us 的任何(有效的)正值写入 cpu.cfs_burst_us 将配发未使用 93*4788a136SYanteng Si带宽累积的上限。 94*4788a136SYanteng Si 95*4788a136SYanteng Si如果一个组处于受限状态,对该组带宽规格的任何更新都将导致其成为无限流状态。 96*4788a136SYanteng Si 97*4788a136SYanteng Si系统范围设置 98*4788a136SYanteng Si------------ 99*4788a136SYanteng Si为了提高效率,运行时间在全局池和CPU本地“筒仓”之间以批处理方式转移。这大大减少了大型系统的全 100*4788a136SYanteng Si局核算压力。每次需要进行这种更新时,传输的数量被描述为 "片"。 101*4788a136SYanteng Si 102*4788a136SYanteng Si这是可以通过procfs调整的:: 103*4788a136SYanteng Si 104*4788a136SYanteng Si /proc/sys/kernel/sched_cfs_bandwidth_slice_us (default=5ms) 105*4788a136SYanteng Si 106*4788a136SYanteng Si较大的时间片段值将减少传输开销,而较小的值则允许更精细的消费。 107*4788a136SYanteng Si 108*4788a136SYanteng Si统计 109*4788a136SYanteng Si---- 110*4788a136SYanteng Si一个组的带宽统计数据通过cpu.stat的5个字段导出。 111*4788a136SYanteng Si 112*4788a136SYanteng Sicpu.stat: 113*4788a136SYanteng Si 114*4788a136SYanteng Si- nr_periods:已经过去的执行间隔的数量。 115*4788a136SYanteng Si- nr_throttled: 该组已被节流/限制的次数。 116*4788a136SYanteng Si- throttled_time: 该组的实体被限流的总时间长度(纳秒)。 117*4788a136SYanteng Si- nr_bursts:突发发生的周期数。 118*4788a136SYanteng Si- burst_time: 任何CPU在各个时期使用超过配额的累计壁钟时间(纳秒)。 119*4788a136SYanteng Si 120*4788a136SYanteng Si这个接口是只读的。 121*4788a136SYanteng Si 122*4788a136SYanteng Si分层考虑 123*4788a136SYanteng Si-------- 124*4788a136SYanteng Si该接口强制要求单个实体的带宽总是可以达到的,即:max(c_i) <= C。然而,在总体情况下,是明确 125*4788a136SYanteng Si允许过度订阅的,以便在一个层次结构中实现工作保护语义: 126*4788a136SYanteng Si 127*4788a136SYanteng Si 例如,Sum (c_i)可能超过C 128*4788a136SYanteng Si 129*4788a136SYanteng Si[ 其中C是父方的带宽,c_i是其子方的带宽。 ] 130*4788a136SYanteng Si 131*4788a136SYanteng Si.. note:: 132*4788a136SYanteng Si 译文中的父亲/孩子指的是cgroup parent, cgroup children。 133*4788a136SYanteng Si 134*4788a136SYanteng Si有两种方式可以使一个组变得限流: 135*4788a136SYanteng Si 136*4788a136SYanteng Si a. 它在一段时期内完全消耗自己的配额 137*4788a136SYanteng Si b. 父方的配额在其期间内全部用完 138*4788a136SYanteng Si 139*4788a136SYanteng Si在上述b)情况下,即使孩子可能有剩余的运行时间,它也不会被允许,直到父亲的运行时间被刷新。 140*4788a136SYanteng Si 141*4788a136SYanteng SiCFS带宽配额的注意事项 142*4788a136SYanteng Si--------------------- 143*4788a136SYanteng Si一旦一个片断被分配给一个cpu,它就不会过期。然而,如果该cpu上的所有线程都无法运行,那么除了 144*4788a136SYanteng Si1ms以外的所有时间片都可以返回到全局池中。这是在编译时由min_cfs_rq_runtime变量配置的。这 145*4788a136SYanteng Si是一个性能调整,有助于防止对全局锁的额外争夺。 146*4788a136SYanteng Si 147*4788a136SYanteng Sicpu-local分片不会过期的事实导致了一些有趣的罕见案例,应该被理解。 148*4788a136SYanteng Si 149*4788a136SYanteng Si对于cgroup cpu限制的应用程序来说,这是一个相对有意义的问题,因为他们自然会消耗他们的全部配 150*4788a136SYanteng Si额,以及每个cpu-本地片在每个时期的全部。因此,预计nr_periods大致等于nr_throttled,并且 151*4788a136SYanteng Sicpuacct.用量的增加大致等于cfs_quota_us在每个周期的增加。 152*4788a136SYanteng Si 153*4788a136SYanteng Si对于高线程、非cpu绑定的应用程序,这种非过期的细微差别允许应用程序短暂地突破他们的配额限制, 154*4788a136SYanteng Si即任务组正在运行的每个cpu上未使用的片断量(通常每个cpu最多1ms或由min_cfs_rq_runtime定 155*4788a136SYanteng Si义)。这种轻微的突发只适用于配额已经分配给cpu,然后没有完全使用或在以前的时期返回。这个突发 156*4788a136SYanteng Si量不会在核心之间转移。因此,这种机制仍然严格限制任务组的配额平均使用量,尽管是在比单一时期更 157*4788a136SYanteng Si长的时间窗口。这也限制了突发能力,每个cpu不超过1ms。这为在高核数机器上有小配额限制的高线程 158*4788a136SYanteng Si应用提供了更好的更可预测的用户体验。它还消除了在使用低于配额的cpu时对这些应用进行节流的倾向。 159*4788a136SYanteng Si另一种说法是,通过允许一个片断的未使用部分在不同时期保持有效,我们减少了在不需要整个片断的cpu 160*4788a136SYanteng Si时间的cpu-local 筒仓上浪费配额的可能性。 161*4788a136SYanteng Si 162*4788a136SYanteng Si绑定cpu和非绑定cpu的交互式应用之间的互动也应该被考虑,特别是当单核使用率达到100%时。如果你 163*4788a136SYanteng Si给了这些应用程序一半的cpu-core,并且它们都被安排在同一个CPU上,理论上非cpu绑定的应用程序有 164*4788a136SYanteng Si可能在某些时期使用多达1ms的额外配额,从而阻止cpu绑定的应用程序完全使用其配额,这也是同样的数 165*4788a136SYanteng Si量。在这些情况下,将由CFS算法(见CFS调度器)来决定选择哪个应用程序来运行,因为它们都是可运行 166*4788a136SYanteng Si的,并且有剩余的配额。这个运行时间的差异将在接下来的交互式应用程序空闲期间得到弥补。 167*4788a136SYanteng Si 168*4788a136SYanteng Si例子 169*4788a136SYanteng Si---- 170*4788a136SYanteng Si1. 限制一个组的运行时间为1个CPU的价值:: 171*4788a136SYanteng Si 172*4788a136SYanteng Si 如果周期是250ms,配额也是250ms,那么该组将每250ms获得价值1个CPU的运行时间。 173*4788a136SYanteng Si 174*4788a136SYanteng Si # echo 250000 > cpu.cfs_quota_us /* quota = 250ms */ 175*4788a136SYanteng Si # echo 250000 > cpu.cfs_period_us /* period = 250ms */ 176*4788a136SYanteng Si 177*4788a136SYanteng Si2. 在多CPU机器上,将一个组的运行时间限制为2个CPU的价值 178*4788a136SYanteng Si 179*4788a136SYanteng Si 在500ms周期和1000ms配额的情况下,该组每500ms可以获得2个CPU的运行时间:: 180*4788a136SYanteng Si 181*4788a136SYanteng Si # echo 1000000 > cpu.cfs_quota_us /* quota = 1000ms */ 182*4788a136SYanteng Si # echo 500000 > cpu.cfs_period_us /* period = 500ms */ 183*4788a136SYanteng Si 184*4788a136SYanteng Si 这里较大的周期允许增加突发能力。 185*4788a136SYanteng Si 186*4788a136SYanteng Si3. 将一个组限制在1个CPU的20%。 187*4788a136SYanteng Si 188*4788a136SYanteng Si 在50ms周期内,10ms配额将相当于1个CPU的20%。:: 189*4788a136SYanteng Si 190*4788a136SYanteng Si # echo 10000 > cpu.cfs_quota_us /* quota = 10ms */ 191*4788a136SYanteng Si # echo 50000 > cpu.cfs_period_us /* period = 50ms */ 192*4788a136SYanteng Si 193*4788a136SYanteng Si 通过在这里使用一个小的周期,我们以牺牲突发容量为代价来确保稳定的延迟响应。 194*4788a136SYanteng Si 195*4788a136SYanteng Si4. 将一个组限制在1个CPU的40%,并允许累积到1个CPU的20%,如果已经累积了的话。 196*4788a136SYanteng Si 197*4788a136SYanteng Si 在50ms周期内,20ms配额将相当于1个CPU的40%。而10毫秒的突发将相当于1个 198*4788a136SYanteng Si CPU的20%:: 199*4788a136SYanteng Si 200*4788a136SYanteng Si # echo 20000 > cpu.cfs_quota_us /* quota = 20ms */ 201*4788a136SYanteng Si # echo 50000 > cpu.cfs_period_us /* period = 50ms */ 202*4788a136SYanteng Si # echo 10000 > cpu.cfs_burst_us /* burst = 10ms */ 203*4788a136SYanteng Si 204*4788a136SYanteng Si 较大的缓冲区设置(不大于配额)允许更大的突发容量。 205