CFS Bandwidth Control
이 문서는 오직 SCHED_NORMAL의 CPU bandwidth 제어에 대해서만 다룬다. SCHED_RT의 경우는 Documentation/scheduler/sched-rt-group.txt에서 다룬다.
[ This document only discusses CPU bandwidth control for SCHED_NORMAL. The SCHED_RT case is covered in Documentation/scheduler/sched-rt-group.txt ]
CFS bandwidth 제어기능은 CONFIG_FAIR_GROUP_SCHED의 확장된 기능이며, 태스크 그룹이나 계층도가 사용가능한 최대 CPU bandwidth를 지정할 수 있게 해준다.
CFS bandwidth control is a CONFIG_FAIR_GROUP_SCHED extension which allows the specification of the maximum CPU bandwidth available to a group or hierarchy.
태스크그룹의 CPU bandwidth는 quota와 period를 사용해서 지정한다. 태스크 그룹은 주어진 period (ms)동안에 최대 quota ms만큼의 CPU 시간을 사용할 수 있다. 만약 태스크 그룹이 자신의 CPU bandwidth를 초과하면(period동안 사용할 quota를 다 사용했을 경우), 계층도에 속한 태스크들은 CPU 사용이 제한되며(be throttled) 다음 period가 돌아올 때까지는 다시 실행될 수 없다.
The bandwidth allowed for a group is specified using a quota and period. Within each given “period” (microseconds), a group is allowed to consume only up to “quota” microseconds of CPU time. When the CPU bandwidth consumption of a group exceeds this limit (for that period), the tasks belonging to its hierarchy will be throttled and are not allowed to run again until the next period.
태스크 그룹이 사용하지 못하고 남은 runtime은 전역적으로 관리되고 각 period의 끝에서 지정된 quota만큼 갱신된다. thread들이 사용한 bandwidth는 사용할 때마다 cpu-local “silos”에 전달된다. 매번 전달할 양은 조정가능하고 “slice”로 표현된다
A group’s unused runtime is globally tracked, being refreshed with quota units above at each period boundary. As threads consume this bandwidth it is transferred to cpu-local “silos” on a demand basis. The amount transferred within each of these updates is tunable and described as the “slice”.
Management
Quota와 Period는 cgroupfs의 cpu subsystem에서 관리된다.
Quota and period are managed within the cpu subsystem via cgroupfs.
- cpu.cfs_quoat_us: period동안 사용할 수 있는 시간(the total available run-time within a period(in microseconds))
- cpu.cfs_period_us: 실행하는 period(the length of a period (in microseconds))
- cpu.stat: throttling 통계(exports throttling statistics [explained further below])
기본값은 아래와 같다(The default values are):
cpu.cfs_period_us=100ms
cpu.cfs_quota_us=-1
cpu.cfs_quota_us 값이 -1이면 태스크 그룹에 bandwidth 제한이 없음을 나타내며, bandwidth 제약에서 자유로운 태스크 그룹으로 표현한다. 이것은 일이 없을때만 쉬는(work-conserving) CFS의 전통적인 동작을 나타낸다.
A value of -1 for cpu.cfs_quota_us indicates that the group does not have any bandwidth restriction in place, such a group is described as an unconstrained bandwidth group. This represents the traditional work-conserving behavior for CFS.
파일에 (유효한)양수 값을 쓰면 태스크그룹이 bandwidth 제한을 지정한 것처럼 동작한다. 최소한의 quota, period 값은 1ms이다. period의 최대값은 1초다. bandwidth 제한이 계층구조에 적용되면 추가적인 제한이 발생한다. 자세한 내용은 아래에서 설명하겠다.
Writing any (valid) positive value(s) will enact the specified bandwidth limit. The minimum quota allowed for the quota or period is 1ms. There is also an upper bound on the period length of 1s. Additional restrictions exist when bandwidth limits are used in a hierarchical fashion, these are explained in more detail below.
cpu.cfs_quota_us에 음수 값을 쓰면 bandwidth 제한이 없어지고 태스크 그룹은 다시 bandwidth 제한이 없는 자유로운 상태로 되돌아 간다. 태스크 그룹의 bandwidth 제한이 갱신되면 태스크 그룹에 걸린 제한은 해제된다.
Writing any negative value to cpu.cfs_quota_us will remove the bandwidth limit and return the group to an unconstrained state once more. Any updates to a group’s bandwidth specification will result in it becoming unthrottled if it is in a constrained state.
System wide settings
효율성을 위해 runtime은 global pool과 cpu local “silos” 사이에서 묶어서 보내는 방식으로 전달된다. 이런 방식은 큰 시스템에서의 전역적으로 가해지는 accounting pressure를 많이 줄여줬다. 매번 전달되는 총량은 slice로 나타낸다.
For efficiency run-time is transferred between the global pool and CPU local “silos” in a batch fashion. This greatly reduces global accounting pressure on large systems. The amount transferred each time such an update is required is described as the “slice”.
아래는 procfs에 있는 tunable이다.
This is tunable via procfs:
/proc/sys/kernel/sched_cfs_bandwidth_slice_us (default=5ms)
작은 값의 slice를 사용하면 더욱 세밀하게 bandwidth 사용을 제어할 수 있다. 반면에 큰 값의 slice는 전송시의 오버헤드를 줄여준다.
Larger slice values will reduce transfer overheads, while smaller values allow for more fine-grained consumption.
통계(Statistics)
태스크 그룹의 bandwidth 통계는 cpu.stat의 필드 3개를 통해 노출된다.
A group’s bandwidth statistics are exported via 3 fields in cpu.stat.
- cpu.stat:
- nr_periods: 지나간 주기의 전체 횟수(Number of enforcement intervals that have elapsed.)
- nr_throttled: 태스크 그룹에 throttling이 걸린 전체 횟수(Number of times the group has been throttled/limited.)
- throttled_time: 태스크 그룹의 entity들이 throttling된 전체 시간(ns)(The total time duration (in nanoseconds) for which entities of the group have been throttled.)
이 인터페이스는 읽기전용이다.
This interface is read-only.
계층구조에서의 고려사항(Hierarchical considerations)
인터페이스는 각 entity의 bandwidth 제한이 늘 달성되게 한다. 바로 제일 큰 자식의 bandwidth 가 부모의 bandwidth보다 크지 않도록 제한하는 방식을 쓴다. 하지만 전체 합이 부모의 것보다 큰 경우는 명시적으로 자식들의 bandwidth를 다 쓸 수 있는 방식으로 허용된다.
The interface enforces that an individual entity’s bandwidth is always attainable, that is: max(c_i) <= C. However, over-subscription in the aggregate case is explicitly allowed to enable work-conserving semantics within a hierarchy.
자식들의 bandwidth합이 부모의 것을 넘을 경우가 한 예이다.
e.g. \Sum (c_i) may exceed C
[ Where C is the parent’s bandwidth, and c_i its children ]
태스크 그룹이 throttling되는 경우에는 2가지가 있다.
There are two ways in which a group may become throttled:
- 주기동안 자신의 할당량을 전부 사용한 경우(it fully consumes its own quota within a period)
- 주기동안 부모가 할당량을 전부 사용한 경우(a parent’s quota is fully consumed within its period)
case b의 경우, 자식의 런타임이 남아있더라도 부모의 런타임이 재충전되기 전까지는 자식은 실행할 수 없다.
In case b) above, even though the child may have runtime remaining it will not
be allowed to until the parent’s runtime is refreshed.
예제(Examples)
1. 태스크 그룹의 runtime을 1개의 cpu에서 제한하는 방법(Limit a group to 1 CPU worth of runtime.)
만약 period가 250ms이고 quota 또한 250ms라면, 태스크 그룹은 매 250ms마다 1개의 CPU 시간을 얻을 것이다.
If period is 250ms and quota is also 250ms, the group will get 1 CPU worth of runtime every 250ms.
# echo 250000 > cpu.cfs_quota_us /* quota = 250ms */
# echo 250000 > cpu.cfs_period_us /* period = 250ms */
2. multi cpu 머신에서 태스크 그룹의 runtime을 2개의 cpu로 제한하는 방법.(Limit a group to 2 CPUs worth of runtime on a multi-CPU machine.)
period가 500ms이고 quota가 1000ms라면, 태스크 그룹은 매 500ms마다 2개의 cpu 시간을 얻을 수 있다.
With 500ms period and 1000ms quota, the group can get 2 CPUs worth of runtime every 500ms.
# echo 1000000 > cpu.cfs_quota_us /* quota = 1000ms */
# echo 500000 > cpu.cfs_period_us /* period = 500ms */
더 큰 값의 period를 사용하면 증가된 burst capacity를 가능케 한다.
The larger period here allows for increased burst capacity.
3. CPU 1개의 시간 20%를 사용하도록 태스크 그룹을 제한하는 방법(Limit a group to 20% of 1 CPU.)
period가 50ms일 때, 10ms의 quota는 CPU 1개의 20% 시간과 동일하다.
With 50ms period, 10ms quota will be equivalent to 20% of 1 CPU.
# echo 10000 > cpu.cfs_quota_us /* quota = 10ms */
# echo 50000 > cpu.cfs_period_us /* period = 50ms */
작은 값의 period를 사용하면 burst capacity를 포기하는 대신 일관된 응답시간을 보장할 수 있다.
By using a small period here we are ensuring a consistent latency response at the expense of burst capacity.
'커널 번역(기사,문서)' 카테고리의 다른 글
[번역] scheduler/sched-domains.txt (0) | 2018.09.07 |
---|---|
[번역] lwn - CFS bandwidth control (0) | 2018.09.07 |
[번역] vm/page_owner.txt (0) | 2018.09.05 |
[번역] lwn - Atomic context and kernel API design (0) | 2018.09.04 |
[번역] vm/slub.txt (0) | 2018.08.30 |