← Documents Documentation/timers/no_hz.rst GitHub 원문 ↗

Linux 6.18.37 · Timers

NO_HZ scheduling tick 제어

Periodic tick, NO_HZ_IDLE과 NO_HZ_FULL의 차이, housekeeping CPU, RCU 영향과 검증 방법을 설명합니다.

Source pathDocumentation/timers/no_hz.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

세 가지 scheduling tick mode

no_hz.rst:1-32
KconfigTick 생략 범위주요 목적
CONFIG_HZ_PERIODIC생략하지 않음단순성과 예측 가능한 periodic accounting
CONFIG_NO_HZ_IDLEidle CPU에서 생략일반 server와 mobile의 전력 절감
CONFIG_NO_HZ_FULL선택 CPU에 runnable task 하나일 때도 생략HPC와 real-time workload의 OS jitter 감소

Periodic와 idle dynticks

no_hz.rst:33-103

Periodic mode는 모든 CPU에 HZ 주기의 scheduling-clock interrupt를 보냅니다. 단순하지만 idle CPU를 불필요하게 깨워 power state를 방해합니다. NO_HZ_IDLE은 idle 진입 시 다음 timer deadline까지 tick을 멈추고 exit 때 elapsed tick accounting을 보정합니다.

Idle dynticks는 일반 workload의 기본 선택이지만 tick stop과 restart 계산 비용이 있습니다. 매우 짧게 idle을 반복하는 workload에서는 절감보다 overhead가 클 수 있어 boot parameter와 trace로 비교합니다.

Adaptive ticks와 housekeeping CPU

no_hz.rst:104-176

NO_HZ_FULL은 지정 CPU에 runnable task가 하나뿐일 때 scheduler tick을 대부분 멈춰 application jitter를 줄입니다. 최소 한 CPU는 periodic timekeeping과 kernel housekeeping을 담당해야 하며 모든 CPU를 adaptive tick 대상으로 둘 수 없습니다.

nohz_full= CPU list, isolcpus와 IRQ affinity만 설정한다고 완전한 isolation이 되지는 않습니다. Workqueue, timer, unbound kthread, perf event와 device interrupt를 housekeeping CPU로 옮기고 target CPU에서 둘 이상의 runnable task가 생기지 않게 해야 합니다.

RCU quiescent state와 callback offload

no_hz.rst:177-198

RCU는 tick을 이용해 CPU 상태를 관찰해 왔으므로 full dynticks CPU가 user mode에서 오래 실행될 때 quiescent state 추적이 정확해야 합니다. rcu_nocbs로 callback processing을 housekeeping CPU에 offload하면 isolated CPU의 jitter를 더 줄일 수 있습니다.

Tick이 실제로 멈췄는지 검증

no_hz.rst:199-222
  • Kernel config와 boot command line에서 대상 CPU list를 확인한다.
  • trace_irqsoff, timer, sched와 power tracepoint로 periodic interrupt를 관찰한다.
  • IRQ affinity, workqueue cpumask와 kernel thread placement를 확인한다.
  • Application p99와 maximum latency를 periodic mode와 비교한다.

알려진 제한과 trade-off

no_hz.rst:223-318

POSIX CPU timer, perf sampling, scheduler load balancing과 여러 runnable task는 tick을 다시 필요하게 만들 수 있습니다. Full dynticks는 throughput을 자동으로 높이는 기능이 아니라 kernel activity를 다른 CPU와 시점으로 옮기는 isolation 기법입니다.

Housekeeping CPU 수가 너무 적으면 offload된 work와 interrupt가 그곳에 몰려 전체 성능이 떨어집니다. Target latency와 시스템 처리량을 함께 측정하여 CPU partition을 정합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ======================================
2 NO_HZ: Reducing Scheduling-Clock Ticks
3 ======================================
4
5
6 This document describes Kconfig options and boot parameters that can
7 reduce the number of scheduling-clock interrupts, thereby improving energy
8 efficiency and reducing OS jitter. Reducing OS jitter is important for
9 some types of computationally intensive high-performance computing (HPC)
10 applications and for real-time applications.
11
12 There are three main ways of managing scheduling-clock interrupts
13 (also known as "scheduling-clock ticks" or simply "ticks"):
14
15 1. Never omit scheduling-clock ticks (CONFIG_HZ_PERIODIC=y or
16 CONFIG_NO_HZ=n for older kernels). You normally will -not-
17 want to choose this option.
18
19 2. Omit scheduling-clock ticks on idle CPUs (CONFIG_NO_HZ_IDLE=y or
20 CONFIG_NO_HZ=y for older kernels). This is the most common
21 approach, and should be the default.
22
23 3. Omit scheduling-clock ticks on CPUs that are either idle or that
24 have only one runnable task (CONFIG_NO_HZ_FULL=y). Unless you
25 are running realtime applications or certain types of HPC
26 workloads, you will normally -not- want this option.
27
28 These three cases are described in the following three sections, followed
29 by a third section on RCU-specific considerations, a fourth section
30 discussing testing, and a fifth and final section listing known issues.
31
32
33 Never Omit Scheduling-Clock Ticks
34 =================================
35
36 Very old versions of Linux from the 1990s and the very early 2000s
37 are incapable of omitting scheduling-clock ticks. It turns out that
38 there are some situations where this old-school approach is still the
39 right approach, for example, in heavy workloads with lots of tasks
40 that use short bursts of CPU, where there are very frequent idle
41 periods, but where these idle periods are also quite short (tens or
42 hundreds of microseconds). For these types of workloads, scheduling
43 clock interrupts will normally be delivered any way because there
44 will frequently be multiple runnable tasks per CPU. In these cases,
45 attempting to turn off the scheduling clock interrupt will have no effect
46 other than increasing the overhead of switching to and from idle and
47 transitioning between user and kernel execution.
48
49 This mode of operation can be selected using CONFIG_HZ_PERIODIC=y (or
50 CONFIG_NO_HZ=n for older kernels).
51
52 However, if you are instead running a light workload with long idle
53 periods, failing to omit scheduling-clock interrupts will result in
54 excessive power consumption. This is especially bad on battery-powered
55 devices, where it results in extremely short battery lifetimes. If you
56 are running light workloads, you should therefore read the following
57 section.
58
59 In addition, if you are running either a real-time workload or an HPC
60 workload with short iterations, the scheduling-clock interrupts can
61 degrade your applications performance. If this describes your workload,
62 you should read the following two sections.
63
64
65 Omit Scheduling-Clock Ticks For Idle CPUs
66 =========================================
67
68 If a CPU is idle, there is little point in sending it a scheduling-clock
69 interrupt. After all, the primary purpose of a scheduling-clock interrupt
70 is to force a busy CPU to shift its attention among multiple duties,
71 and an idle CPU has no duties to shift its attention among.
72
73 An idle CPU that is not receiving scheduling-clock interrupts is said to
74 be "dyntick-idle", "in dyntick-idle mode", "in nohz mode", or "running
75 tickless". The remainder of this document will use "dyntick-idle mode".
76
77 The CONFIG_NO_HZ_IDLE=y Kconfig option causes the kernel to avoid sending
78 scheduling-clock interrupts to idle CPUs, which is critically important
79 both to battery-powered devices and to highly virtualized mainframes.
80 A battery-powered device running a CONFIG_HZ_PERIODIC=y kernel would
81 drain its battery very quickly, easily 2-3 times as fast as would the
82 same device running a CONFIG_NO_HZ_IDLE=y kernel. A mainframe running
83 1,500 OS instances might find that half of its CPU time was consumed by
84 unnecessary scheduling-clock interrupts. In these situations, there
85 is strong motivation to avoid sending scheduling-clock interrupts to
86 idle CPUs. That said, dyntick-idle mode is not free:
87
88 1. It increases the number of instructions executed on the path
89 to and from the idle loop.
90
91 2. On many architectures, dyntick-idle mode also increases the
92 number of expensive clock-reprogramming operations.
93
94 Therefore, systems with aggressive real-time response constraints often
95 run CONFIG_HZ_PERIODIC=y kernels (or CONFIG_NO_HZ=n for older kernels)
96 in order to avoid degrading from-idle transition latencies.
97
98 There is also a boot parameter "nohz=" that can be used to disable
99 dyntick-idle mode in CONFIG_NO_HZ_IDLE=y kernels by specifying "nohz=off".
100 By default, CONFIG_NO_HZ_IDLE=y kernels boot with "nohz=on", enabling
101 dyntick-idle mode.
102
103
104 Omit Scheduling-Clock Ticks For CPUs With Only One Runnable Task
105 ================================================================
106
107 If a CPU has only one runnable task, there is little point in sending it
108 a scheduling-clock interrupt because there is no other task to switch to.
109 Note that omitting scheduling-clock ticks for CPUs with only one runnable
110 task implies also omitting them for idle CPUs.
111
112 The CONFIG_NO_HZ_FULL=y Kconfig option causes the kernel to avoid
113 sending scheduling-clock interrupts to CPUs with a single runnable task,
114 and such CPUs are said to be "adaptive-ticks CPUs". This is important
115 for applications with aggressive real-time response constraints because
116 it allows them to improve their worst-case response times by the maximum
117 duration of a scheduling-clock interrupt. It is also important for
118 computationally intensive short-iteration workloads: If any CPU is
119 delayed during a given iteration, all the other CPUs will be forced to
120 wait idle while the delayed CPU finishes. Thus, the delay is multiplied
121 by one less than the number of CPUs. In these situations, there is
122 again strong motivation to avoid sending scheduling-clock interrupts.
123
124 By default, no CPU will be an adaptive-ticks CPU. The "nohz_full="
125 boot parameter specifies the adaptive-ticks CPUs. For example,
126 "nohz_full=1,6-8" says that CPUs 1, 6, 7, and 8 are to be adaptive-ticks
127 CPUs. Note that you are prohibited from marking all of the CPUs as
128 adaptive-tick CPUs: At least one non-adaptive-tick CPU must remain
129 online to handle timekeeping tasks in order to ensure that system
130 calls like gettimeofday() returns accurate values on adaptive-tick CPUs.
131 (This is not an issue for CONFIG_NO_HZ_IDLE=y because there are no running
132 user processes to observe slight drifts in clock rate.) Note that this
133 means that your system must have at least two CPUs in order for
134 CONFIG_NO_HZ_FULL=y to do anything for you.
135
136 Finally, adaptive-ticks CPUs must have their RCU callbacks offloaded.
137 This is covered in the "RCU IMPLICATIONS" section below.
138
139 Normally, a CPU remains in adaptive-ticks mode as long as possible.
140 In particular, transitioning to kernel mode does not automatically change
141 the mode. Instead, the CPU will exit adaptive-ticks mode only if needed,
142 for example, if that CPU enqueues an RCU callback.
143
144 Just as with dyntick-idle mode, the benefits of adaptive-tick mode do
145 not come for free:
146
147 1. CONFIG_NO_HZ_FULL selects CONFIG_NO_HZ_COMMON, so you cannot run
148 adaptive ticks without also running dyntick idle. This dependency
149 extends down into the implementation, so that all of the costs
150 of CONFIG_NO_HZ_IDLE are also incurred by CONFIG_NO_HZ_FULL.
151
152 2. The user/kernel transitions are slightly more expensive due
153 to the need to inform kernel subsystems (such as RCU) about
154 the change in mode.
155
156 3. POSIX CPU timers prevent CPUs from entering adaptive-tick mode.
157 Real-time applications needing to take actions based on CPU time
158 consumption need to use other means of doing so.
159
160 4. If there are more perf events pending than the hardware can
161 accommodate, they are normally round-robined so as to collect
162 all of them over time. Adaptive-tick mode may prevent this
163 round-robining from happening. This will likely be fixed by
164 preventing CPUs with large numbers of perf events pending from
165 entering adaptive-tick mode.
166
167 5. Scheduler statistics for adaptive-tick CPUs may be computed
168 slightly differently than those for non-adaptive-tick CPUs.
169 This might in turn perturb load-balancing of real-time tasks.
170
171 Although improvements are expected over time, adaptive ticks is quite
172 useful for many types of real-time and compute-intensive applications.
173 However, the drawbacks listed above mean that adaptive ticks should not
174 (yet) be enabled by default.
175
176
177 RCU Implications
178 ================
179
180 There are situations in which idle CPUs cannot be permitted to
181 enter either dyntick-idle mode or adaptive-tick mode, the most
182 common being when that CPU has RCU callbacks pending.
183
184 Avoid this by offloading RCU callback processing to "rcuo" kthreads
185 using the CONFIG_RCU_NOCB_CPU=y Kconfig option. The specific CPUs to
186 offload may be selected using The "rcu_nocbs=" kernel boot parameter,
187 which takes a comma-separated list of CPUs and CPU ranges, for example,
188 "1,3-5" selects CPUs 1, 3, 4, and 5. Note that CPUs specified by
189 the "nohz_full" kernel boot parameter are also offloaded.
190
191 The offloaded CPUs will never queue RCU callbacks, and therefore RCU
192 never prevents offloaded CPUs from entering either dyntick-idle mode
193 or adaptive-tick mode. That said, note that it is up to userspace to
194 pin the "rcuo" kthreads to specific CPUs if desired. Otherwise, the
195 scheduler will decide where to run them, which might or might not be
196 where you want them to run.
197
198
199 Testing
200 =======
201
202 So you enable all the OS-jitter features described in this document,
203 but do not see any change in your workload's behavior. Is this because
204 your workload isn't affected that much by OS jitter, or is it because
205 something else is in the way? This section helps answer this question
206 by providing a simple OS-jitter test suite, which is available on branch
207 master of the following git archive:
208
209 git://git.kernel.org/pub/scm/linux/kernel/git/frederic/dynticks-testing.git
210
211 Clone this archive and follow the instructions in the README file.
212 This test procedure will produce a trace that will allow you to evaluate
213 whether or not you have succeeded in removing OS jitter from your system.
214 If this trace shows that you have removed OS jitter as much as is
215 possible, then you can conclude that your workload is not all that
216 sensitive to OS jitter.
217
218 Note: this test requires that your system have at least two CPUs.
219 We do not currently have a good way to remove OS jitter from single-CPU
220 systems.
221
222
223 Known Issues
224 ============
225
226 * Dyntick-idle slows transitions to and from idle slightly.
227 In practice, this has not been a problem except for the most
228 aggressive real-time workloads, which have the option of disabling
229 dyntick-idle mode, an option that most of them take. However,
230 some workloads will no doubt want to use adaptive ticks to
231 eliminate scheduling-clock interrupt latencies. Here are some
232 options for these workloads:
233
234 a. Use PMQOS from userspace to inform the kernel of your
235 latency requirements (preferred).
236
237 b. On x86 systems, use the "idle=mwait" boot parameter.
238
239 c. On x86 systems, use the "intel_idle.max_cstate=" to limit
240 ` the maximum C-state depth.
241
242 d. On x86 systems, use the "idle=poll" boot parameter.
243 However, please note that use of this parameter can cause
244 your CPU to overheat, which may cause thermal throttling
245 to degrade your latencies -- and that this degradation can
246 be even worse than that of dyntick-idle. Furthermore,
247 this parameter effectively disables Turbo Mode on Intel
248 CPUs, which can significantly reduce maximum performance.
249
250 * Adaptive-ticks slows user/kernel transitions slightly.
251 This is not expected to be a problem for computationally intensive
252 workloads, which have few such transitions. Careful benchmarking
253 will be required to determine whether or not other workloads
254 are significantly affected by this effect.
255
256 * Adaptive-ticks does not do anything unless there is only one
257 runnable task for a given CPU, even though there are a number
258 of other situations where the scheduling-clock tick is not
259 needed. To give but one example, consider a CPU that has one
260 runnable high-priority SCHED_FIFO task and an arbitrary number
261 of low-priority SCHED_OTHER tasks. In this case, the CPU is
262 required to run the SCHED_FIFO task until it either blocks or
263 some other higher-priority task awakens on (or is assigned to)
264 this CPU, so there is no point in sending a scheduling-clock
265 interrupt to this CPU. However, the current implementation
266 nevertheless sends scheduling-clock interrupts to CPUs having a
267 single runnable SCHED_FIFO task and multiple runnable SCHED_OTHER
268 tasks, even though these interrupts are unnecessary.
269
270 And even when there are multiple runnable tasks on a given CPU,
271 there is little point in interrupting that CPU until the current
272 running task's timeslice expires, which is almost always way
273 longer than the time of the next scheduling-clock interrupt.
274
275 Better handling of these sorts of situations is future work.
276
277 * A reboot is required to reconfigure both adaptive idle and RCU
278 callback offloading. Runtime reconfiguration could be provided
279 if needed, however, due to the complexity of reconfiguring RCU at
280 runtime, there would need to be an earthshakingly good reason.
281 Especially given that you have the straightforward option of
282 simply offloading RCU callbacks from all CPUs and pinning them
283 where you want them whenever you want them pinned.
284
285 * Additional configuration is required to deal with other sources
286 of OS jitter, including interrupts and system-utility tasks
287 and processes. This configuration normally involves binding
288 interrupts and tasks to particular CPUs.
289
290 * Some sources of OS jitter can currently be eliminated only by
291 constraining the workload. For example, the only way to eliminate
292 OS jitter due to global TLB shootdowns is to avoid the unmapping
293 operations (such as kernel module unload operations) that
294 result in these shootdowns. For another example, page faults
295 and TLB misses can be reduced (and in some cases eliminated) by
296 using huge pages and by constraining the amount of memory used
297 by the application. Pre-faulting the working set can also be
298 helpful, especially when combined with the mlock() and mlockall()
299 system calls.
300
301 * Unless all CPUs are idle, at least one CPU must keep the
302 scheduling-clock interrupt going in order to support accurate
303 timekeeping.
304
305 * If there might potentially be some adaptive-ticks CPUs, there
306 will be at least one CPU keeping the scheduling-clock interrupt
307 going, even if all CPUs are otherwise idle.
308
309 Better handling of this situation is ongoing work.
310
311 * Some process-handling operations still require the occasional
312 scheduling-clock tick. These operations include calculating CPU
313 load, maintaining sched average, computing CFS entity vruntime,
314 computing avenrun, and carrying out load balancing. They are
315 currently accommodated by scheduling-clock tick every second
316 or so. On-going work will eliminate the need even for these
317 infrequent scheduling-clock ticks.
318

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

Scheduling-clock tick을 줄이는 세 방식

1-30

이 문서는 scheduling-clock interrupt 수를 줄이는 Kconfig option과 boot parameter를 설명한다. Tick 수를 줄이면 energy efficiency를 높이고 OS jitter를 낮출 수 있다. OS jitter 감소는 계산량이 큰 일부 HPC application과 real-time application에서 중요하다.

Scheduling-clock interrupt는 scheduling-clock tick 또는 간단히 tick이라고도 한다. 이를 관리하는 주된 방식은 세 가지다.

방식설정용도
Tick을 전혀 생략하지 않음CONFIG_HZ_PERIODIC=y, 오래된 kernel은 CONFIG_NO_HZ=n일반적으로 선택하지 않는다.
Idle CPU의 tick 생략CONFIG_NO_HZ_IDLE=y, 오래된 kernel은 CONFIG_NO_HZ=y가장 일반적인 방식이며 기본 선택이 되어야 한다.
Idle이거나 runnable task가 하나뿐인 CPU의 tick 생략CONFIG_NO_HZ_FULL=yReal-time application 또는 특정 HPC workload가 아니라면 일반적으로 선택하지 않는다.

뒤의 절은 이 세 경우와 RCU에 미치는 영향, 시험 방법, 알려진 문제를 차례로 설명한다.

Scheduling-clock tick을 항상 유지하는 mode

33-62

1990년대와 2000년대 초의 매우 오래된 Linux는 scheduling-clock tick을 생략할 수 없었다. 그러나 짧은 CPU burst를 쓰는 task가 많고 idle period가 매우 자주 나타나지만 각각 수십 또는 수백 microsecond로 짧은 무거운 workload에서는 이 방식이 여전히 적합할 수 있다.

이런 workload에서는 CPU마다 runnable task가 여러 개일 때가 많아 scheduling-clock interrupt가 어차피 전달된다. Interrupt를 끄려는 시도는 효과 없이 idle 진입·이탈과 user/kernel 전환 overhead만 늘릴 수 있다. 이 mode는 CONFIG_HZ_PERIODIC=y, 오래된 kernel에서는 CONFIG_NO_HZ=n으로 선택한다.

반대로 긴 idle period가 있는 가벼운 workload에서는 tick을 생략하지 않으면 전력을 지나치게 소비한다. Battery device에서는 battery lifetime이 매우 짧아진다. 또한 짧은 iteration을 수행하는 real-time 또는 HPC workload에서는 scheduling-clock interrupt가 application 성능을 낮출 수 있다. 이런 경우 뒤의 두 mode를 검토해야 한다.

Idle CPU에서 tick 생략: CONFIG_NO_HZ_IDLE

65-101

Idle CPU에는 scheduling-clock interrupt를 보낼 이유가 거의 없다. 이 interrupt의 주된 목적은 바쁜 CPU가 여러 작업 사이에서 실행 대상을 바꾸게 하는 것인데 idle CPU에는 바꿀 작업이 없기 때문이다.

Scheduling-clock interrupt를 받지 않는 idle CPU는 dyntick-idle, dyntick-idle mode, nohz mode 또는 tickless라고 한다. 이 문서는 dyntick-idle mode라는 표현을 사용한다.

CONFIG_NO_HZ_IDLE=y는 idle CPU에 scheduling-clock interrupt를 보내지 않게 한다. Battery device와 많은 virtual machine을 실행하는 mainframe에서 특히 중요하다. CONFIG_HZ_PERIODIC=y kernel을 쓰는 battery device는 CONFIG_NO_HZ_IDLE=y를 쓸 때보다 battery를 2~3배 빠르게 소모할 수 있다. OS instance 1,500개를 실행하는 mainframe에서는 불필요한 tick이 CPU 시간의 절반을 사용할 수도 있다.

하지만 dyntick-idle mode에도 비용이 있다. Idle loop 진입과 이탈 path에서 실행하는 instruction 수가 늘고, 많은 architecture에서는 비싼 clock reprogramming operation도 증가한다. 매우 엄격한 real-time response constraint가 있는 system은 idle에서 빠져나오는 latency 증가를 피하려고 CONFIG_HZ_PERIODIC=y를 사용하기도 한다.

CONFIG_NO_HZ_IDLE=y kernel의 dyntick-idle mode는 boot parameter nohz=off로 비활성화할 수 있다. 기본값은 nohz=on이므로 활성화된 상태로 boot한다.

Runnable task가 하나인 CPU의 tick 생략: CONFIG_NO_HZ_FULL

104-143

CPU에 runnable task가 하나뿐이면 전환할 다른 task가 없으므로 scheduling-clock interrupt를 보낼 이유가 거의 없다. 이 경우 tick을 생략하는 기능은 idle CPU의 tick 생략도 포함한다.

CONFIG_NO_HZ_FULL=y는 runnable task가 하나인 CPU에 scheduling-clock interrupt를 보내지 않으며 이런 CPU를 adaptive-ticks CPU라고 한다. 엄격한 real-time response constraint가 있는 application은 scheduling-clock interrupt의 최대 실행 시간만큼 worst-case response time을 줄일 수 있다.

계산량이 많고 iteration이 짧은 workload에도 중요하다. 어떤 iteration에서 CPU 하나가 지연되면 다른 모든 CPU는 그 CPU가 끝날 때까지 idle로 기다린다. 따라서 지연 비용은 CPU 수보다 하나 작은 배수만큼 확대된다.

기본 상태에서는 adaptive-ticks CPU가 없다. nohz_full= boot parameter로 CPU를 지정한다. 예를 들어 nohz_full=1,6-8은 CPU 1, 6, 7, 8을 adaptive-ticks CPU로 지정한다.

모든 CPU를 adaptive-ticks로 지정할 수는 없다. Adaptive CPU의 gettimeofday() 같은 system call이 정확한 값을 돌려주도록 timekeeping task를 처리할 non-adaptive CPU가 최소 하나 online이어야 한다. CONFIG_NO_HZ_IDLE=y에서는 실행 중인 user process가 없어 작은 clock drift를 관찰할 대상이 없으므로 이 문제가 없다. CONFIG_NO_HZ_FULL=y가 실제 효과를 내려면 system에 CPU가 최소 두 개 있어야 한다.

Adaptive-ticks CPU의 RCU callback은 반드시 다른 CPU로 offload해야 한다. 자세한 내용은 뒤의 RCU 절에서 설명한다.

CPU는 가능한 한 오래 adaptive-ticks mode에 머문다. Kernel mode로 전환한다고 자동으로 mode를 벗어나지는 않는다. 예를 들어 해당 CPU가 RCU callback을 enqueue하여 tick이 실제로 필요한 경우에만 adaptive-ticks mode에서 빠져나온다.

Adaptive tick의 비용과 제약

144-174
  • CONFIG_NO_HZ_FULL은 CONFIG_NO_HZ_COMMON을 select하므로 dyntick idle 없이 adaptive tick만 사용할 수 없다. 구현 의존성도 이어져 CONFIG_NO_HZ_IDLE의 모든 비용을 함께 부담한다.
  • Mode 변경을 RCU 같은 kernel subsystem에 알려야 하므로 user/kernel 전환이 약간 더 비싸진다.
  • POSIX CPU timer가 있으면 CPU가 adaptive-tick mode에 들어갈 수 없다. CPU time 소비량을 기준으로 동작해야 하는 real-time application은 다른 방법을 써야 한다.
  • Hardware가 수용할 수 있는 수보다 perf event가 많으면 보통 event를 round-robin하여 시간에 걸쳐 모두 수집한다. Adaptive-tick mode가 이 round-robin을 막을 수 있다. 많은 perf event가 pending인 CPU의 mode 진입을 막는 방식으로 수정될 가능성이 있다.
  • Adaptive-tick CPU의 scheduler statistic은 non-adaptive CPU와 약간 다르게 계산될 수 있으며, 그 결과 real-time task load balancing이 흔들릴 수 있다.

계속 개선될 것으로 예상되지만 adaptive tick은 이미 여러 real-time 및 compute-intensive application에 유용하다. 다만 위 단점 때문에 아직 기본으로 enable해서는 안 된다.

RCU callback offload

177-196

CPU에 RCU callback이 pending인 경우처럼 idle CPU가 dyntick-idle 또는 adaptive-tick mode에 들어가면 안 되는 상황이 있다.

CONFIG_RCU_NOCB_CPU=y를 사용하면 RCU callback 처리를 rcuo kthread로 offload하여 이를 피할 수 있다. rcu_nocbs= boot parameter에 쉼표로 구분한 CPU와 CPU range를 지정한다. 예를 들어 rcu_nocbs=1,3-5는 CPU 1, 3, 4, 5를 선택한다. nohz_full=에 지정한 CPU도 자동으로 offload된다.

Offload된 CPU는 RCU callback을 queue하지 않으므로 RCU 때문에 dyntick-idle 또는 adaptive-tick mode 진입이 막히지 않는다. rcuo kthread를 특정 CPU에 고정하고 싶다면 userspace가 직접 pin해야 한다. 그렇지 않으면 scheduler가 실행 CPU를 결정하므로 원하는 위치와 다를 수 있다.

OS jitter 제거 효과 시험

199-220

이 문서의 OS jitter 감소 기능을 모두 enable했는데 workload 동작이 바뀌지 않았다면, workload가 jitter에 민감하지 않은 것인지 다른 요인이 방해하는 것인지 구분해야 한다. 간단한 시험 suite가 다음 git archive의 master branch에 있다.

git://git.kernel.org/pub/scm/linux/kernel/git/frederic/dynticks-testing.git

Archive를 clone하고 README의 지시를 따르면 OS jitter가 system에서 제거되었는지 평가할 trace를 생성한다. 가능한 만큼 jitter가 제거되었다고 trace가 보여 준다면 해당 workload가 OS jitter에 크게 민감하지 않다고 결론 내릴 수 있다.

이 test에는 CPU가 최소 두 개 필요하다. 현재 single-CPU system에서 OS jitter를 제거하는 좋은 방법은 없다.

알려진 문제: idle 전환 latency

223-249

Dyntick-idle은 idle 진입과 이탈을 약간 느리게 한다. 실제로는 가장 엄격한 real-time workload를 제외하면 문제가 되지 않았으며, 그런 workload 대부분은 dyntick-idle을 끈다. 그러나 scheduling-clock interrupt latency를 없애려고 adaptive tick을 사용해야 하는 workload도 있다.

  • 권장 방식: userspace의 PMQOS로 kernel에 latency 요구 사항을 전달한다.
  • x86에서는 idle=mwait boot parameter를 사용한다.
  • x86에서는 intel_idle.max_cstate=로 최대 C-state 깊이를 제한한다.
  • x86에서는 idle=poll을 사용할 수 있다. 그러나 CPU 과열과 thermal throttling으로 latency가 dyntick-idle보다 더 나빠질 수 있다. Intel CPU의 Turbo Mode도 사실상 꺼져 최대 성능이 크게 낮아질 수 있다.

알려진 문제: adaptive tick 적용 범위와 runtime 재구성

250-283

Adaptive tick은 user/kernel 전환을 약간 느리게 한다. 전환 횟수가 적은 compute-intensive workload에는 문제가 되지 않을 것으로 예상하지만 다른 workload의 영향은 세밀하게 benchmark해야 한다.

현재 adaptive tick은 CPU에 runnable task가 정확히 하나일 때만 동작한다. Tick이 필요 없는 다른 상황은 처리하지 못한다. 예를 들어 높은 priority의 runnable SCHED_FIFO task 하나와 낮은 priority의 SCHED_OTHER task 여러 개가 있는 CPU는 SCHED_FIFO task가 block되거나 더 높은 priority task가 깨어날 때까지 계속 그 task를 실행해야 한다. 이때 tick은 필요 없지만 현재 구현은 불필요한 scheduling-clock interrupt를 보낸다.

Runnable task가 여러 개여도 현재 task의 timeslice가 만료되기 전에는 CPU를 interrupt할 이유가 거의 없다. Timeslice는 대개 다음 scheduling-clock interrupt보다 훨씬 뒤에 끝난다. 이런 경우를 더 잘 처리하는 일은 향후 과제다.

Adaptive idle과 RCU callback offload 구성을 바꾸려면 reboot해야 한다. Runtime 재구성을 구현할 수는 있지만 RCU를 실행 중에 재구성하는 복잡성을 감수할 만큼 매우 강한 이유가 필요하다. 모든 CPU에서 RCU callback을 offload한 뒤 필요할 때 원하는 CPU에 pin하는 단순한 선택지가 있기 때문이다.

알려진 문제: 다른 OS jitter source

285-299

Interrupt, system utility task, process 같은 다른 OS jitter source에는 추가 구성이 필요하며 보통 interrupt와 task를 특정 CPU에 binding한다.

일부 jitter는 workload를 제한해야만 없앨 수 있다. Global TLB shootdown으로 생기는 jitter를 없애려면 kernel module unload처럼 shootdown을 발생시키는 unmap operation을 피해야 한다. Huge page를 사용하고 application memory 사용량을 제한하면 page fault와 TLB miss를 줄이거나 경우에 따라 없앨 수 있다. Working set을 미리 fault하는 방법도 도움이 되며 mlock() 또는 mlockall()과 함께 쓰면 특히 효과적이다.

알려진 문제: timekeeping과 주기적 scheduler 작업

301-317

모든 CPU가 idle이 아니라면 정확한 timekeeping을 위해 최소 CPU 하나는 scheduling-clock interrupt를 계속 발생시켜야 한다. Adaptive-ticks CPU가 존재할 가능성이 있으면 다른 모든 CPU가 idle이어도 최소 CPU 하나가 tick을 유지한다. 이 상황을 더 잘 처리하는 작업이 진행 중이다.

일부 process 처리에는 아직 간헐적인 scheduling-clock tick이 필요하다. CPU load 계산, sched average 유지, CFS entity vruntime 계산, avenrun 계산, load balancing이 포함된다. 현재는 약 1초마다 tick을 발생시켜 처리한다. 진행 중인 작업은 이런 드문 tick의 필요성까지 없애는 것을 목표로 한다.