diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 4 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 54 |
2 files changed, 17 insertions, 41 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 82365dde00a8..887b29708447 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1916,8 +1916,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1916 | nohz_full= [KNL,BOOT] | 1916 | nohz_full= [KNL,BOOT] |
1917 | In kernels built with CONFIG_NO_HZ_FULL=y, set | 1917 | In kernels built with CONFIG_NO_HZ_FULL=y, set |
1918 | the specified list of CPUs whose tick will be stopped | 1918 | the specified list of CPUs whose tick will be stopped |
1919 | whenever possible. You need to keep at least one online | 1919 | whenever possible. The boot CPU will be forced outside |
1920 | CPU outside the range to maintain the timekeeping. | 1920 | the range to maintain the timekeeping. |
1921 | 1921 | ||
1922 | noiotrap [SH] Disables trapped I/O port accesses. | 1922 | noiotrap [SH] Disables trapped I/O port accesses. |
1923 | 1923 | ||
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 369b5769fc97..2bac5ea2c9af 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -158,11 +158,21 @@ int tick_nohz_full_cpu(int cpu) | |||
158 | /* Parse the boot-time nohz CPU list from the kernel parameters. */ | 158 | /* Parse the boot-time nohz CPU list from the kernel parameters. */ |
159 | static int __init tick_nohz_full_setup(char *str) | 159 | static int __init tick_nohz_full_setup(char *str) |
160 | { | 160 | { |
161 | int cpu; | ||
162 | |||
161 | alloc_bootmem_cpumask_var(&nohz_full_mask); | 163 | alloc_bootmem_cpumask_var(&nohz_full_mask); |
162 | if (cpulist_parse(str, nohz_full_mask) < 0) | 164 | if (cpulist_parse(str, nohz_full_mask) < 0) { |
163 | pr_warning("NOHZ: Incorrect nohz_full cpumask\n"); | 165 | pr_warning("NOHZ: Incorrect nohz_full cpumask\n"); |
164 | else | 166 | return 1; |
165 | have_nohz_full_mask = true; | 167 | } |
168 | |||
169 | cpu = smp_processor_id(); | ||
170 | if (cpumask_test_cpu(cpu, nohz_full_mask)) { | ||
171 | pr_warning("NO_HZ: Clearing %d from nohz_full range for timekeeping\n", cpu); | ||
172 | cpumask_clear_cpu(cpu, nohz_full_mask); | ||
173 | } | ||
174 | have_nohz_full_mask = true; | ||
175 | |||
166 | return 1; | 176 | return 1; |
167 | } | 177 | } |
168 | __setup("nohz_full=", tick_nohz_full_setup); | 178 | __setup("nohz_full=", tick_nohz_full_setup); |
@@ -195,42 +205,8 @@ static char __initdata nohz_full_buf[NR_CPUS + 1]; | |||
195 | 205 | ||
196 | static int __init init_tick_nohz_full(void) | 206 | static int __init init_tick_nohz_full(void) |
197 | { | 207 | { |
198 | cpumask_var_t online_nohz; | 208 | if (have_nohz_full_mask) |
199 | int cpu; | 209 | cpu_notifier(tick_nohz_cpu_down_callback, 0); |
200 | |||
201 | if (!have_nohz_full_mask) | ||
202 | return 0; | ||
203 | |||
204 | cpu_notifier(tick_nohz_cpu_down_callback, 0); | ||
205 | |||
206 | if (!zalloc_cpumask_var(&online_nohz, GFP_KERNEL)) { | ||
207 | pr_warning("NO_HZ: Not enough memory to check full nohz mask\n"); | ||
208 | return -ENOMEM; | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * CPUs can probably not be concurrently offlined on initcall time. | ||
213 | * But we are paranoid, aren't we? | ||
214 | */ | ||
215 | get_online_cpus(); | ||
216 | |||
217 | /* Ensure we keep a CPU outside the dynticks range for timekeeping */ | ||
218 | cpumask_and(online_nohz, cpu_online_mask, nohz_full_mask); | ||
219 | if (cpumask_equal(online_nohz, cpu_online_mask)) { | ||
220 | pr_warning("NO_HZ: Must keep at least one online CPU " | ||
221 | "out of nohz_full range\n"); | ||
222 | /* | ||
223 | * We know the current CPU doesn't have its tick stopped. | ||
224 | * Let's use it for the timekeeping duty. | ||
225 | */ | ||
226 | preempt_disable(); | ||
227 | cpu = smp_processor_id(); | ||
228 | pr_warning("NO_HZ: Clearing %d from nohz_full range\n", cpu); | ||
229 | cpumask_clear_cpu(cpu, nohz_full_mask); | ||
230 | preempt_enable(); | ||
231 | } | ||
232 | put_online_cpus(); | ||
233 | free_cpumask_var(online_nohz); | ||
234 | 210 | ||
235 | cpulist_scnprintf(nohz_full_buf, sizeof(nohz_full_buf), nohz_full_mask); | 211 | cpulist_scnprintf(nohz_full_buf, sizeof(nohz_full_buf), nohz_full_mask); |
236 | pr_info("NO_HZ: Full dynticks CPUs: %s.\n", nohz_full_buf); | 212 | pr_info("NO_HZ: Full dynticks CPUs: %s.\n", nohz_full_buf); |