aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2017-09-12 15:37:09 -0400
committerIngo Molnar <mingo@kernel.org>2017-09-14 05:41:06 -0400
commit0d85923c7a81719567311ba0eae8ecb2efd4c8a0 (patch)
tree34c854caa12350d56552dbae1545d6484a8d13c3 /kernel
parent05ba3de74a3f499dcaa37b186220aaf174c95a4b (diff)
smpboot/threads, watchdog/core: Avoid runtime allocation
smpboot_update_cpumask_threads_percpu() allocates a temporary cpumask at runtime. This is suboptimal because the call site needs more code size for proper error handling than a statically allocated temporary mask requires data size. Add static temporary cpumask. The function is globaly serialized, so no further protection required. Remove the half baken error handling in the watchdog code and get rid of the export as there are no in tree modular users of that function. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Don Zickus <dzickus@redhat.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Borislav Petkov <bp@alien8.de> Cc: Chris Metcalf <cmetcalf@mellanox.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Sebastian Siewior <bigeasy@linutronix.de> Cc: Ulrich Obergfell <uobergfe@redhat.com> Link: http://lkml.kernel.org/r/20170912194147.297288838@linutronix.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/smpboot.c22
-rw-r--r--kernel/watchdog.c21
2 files changed, 12 insertions, 31 deletions
diff --git a/kernel/smpboot.c b/kernel/smpboot.c
index 1d71c051a951..ed7507b69b48 100644
--- a/kernel/smpboot.c
+++ b/kernel/smpboot.c
@@ -344,39 +344,31 @@ EXPORT_SYMBOL_GPL(smpboot_unregister_percpu_thread);
344 * by the client, but only by calling this function. 344 * by the client, but only by calling this function.
345 * This function can only be called on a registered smp_hotplug_thread. 345 * This function can only be called on a registered smp_hotplug_thread.
346 */ 346 */
347int smpboot_update_cpumask_percpu_thread(struct smp_hotplug_thread *plug_thread, 347void smpboot_update_cpumask_percpu_thread(struct smp_hotplug_thread *plug_thread,
348 const struct cpumask *new) 348 const struct cpumask *new)
349{ 349{
350 struct cpumask *old = plug_thread->cpumask; 350 struct cpumask *old = plug_thread->cpumask;
351 cpumask_var_t tmp; 351 static struct cpumask tmp;
352 unsigned int cpu; 352 unsigned int cpu;
353 353
354 if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
355 return -ENOMEM;
356
357 get_online_cpus(); 354 get_online_cpus();
358 mutex_lock(&smpboot_threads_lock); 355 mutex_lock(&smpboot_threads_lock);
359 356
360 /* Park threads that were exclusively enabled on the old mask. */ 357 /* Park threads that were exclusively enabled on the old mask. */
361 cpumask_andnot(tmp, old, new); 358 cpumask_andnot(&tmp, old, new);
362 for_each_cpu_and(cpu, tmp, cpu_online_mask) 359 for_each_cpu_and(cpu, &tmp, cpu_online_mask)
363 smpboot_park_thread(plug_thread, cpu); 360 smpboot_park_thread(plug_thread, cpu);
364 361
365 /* Unpark threads that are exclusively enabled on the new mask. */ 362 /* Unpark threads that are exclusively enabled on the new mask. */
366 cpumask_andnot(tmp, new, old); 363 cpumask_andnot(&tmp, new, old);
367 for_each_cpu_and(cpu, tmp, cpu_online_mask) 364 for_each_cpu_and(cpu, &tmp, cpu_online_mask)
368 smpboot_unpark_thread(plug_thread, cpu); 365 smpboot_unpark_thread(plug_thread, cpu);
369 366
370 cpumask_copy(old, new); 367 cpumask_copy(old, new);
371 368
372 mutex_unlock(&smpboot_threads_lock); 369 mutex_unlock(&smpboot_threads_lock);
373 put_online_cpus(); 370 put_online_cpus();
374
375 free_cpumask_var(tmp);
376
377 return 0;
378} 371}
379EXPORT_SYMBOL_GPL(smpboot_update_cpumask_percpu_thread);
380 372
381static DEFINE_PER_CPU(atomic_t, cpu_hotplug_state) = ATOMIC_INIT(CPU_POST_DEAD); 373static DEFINE_PER_CPU(atomic_t, cpu_hotplug_state) = ATOMIC_INIT(CPU_POST_DEAD);
382 374
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index cedf45ab4d81..8935a3a4c2fb 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -787,31 +787,20 @@ out:
787 return err; 787 return err;
788} 788}
789 789
790static int watchdog_update_cpus(void) 790static void watchdog_update_cpus(void)
791{ 791{
792 if (IS_ENABLED(CONFIG_SOFTLOCKUP_DETECTOR)) { 792 if (IS_ENABLED(CONFIG_SOFTLOCKUP_DETECTOR) && watchdog_running) {
793 return smpboot_update_cpumask_percpu_thread(&watchdog_threads, 793 smpboot_update_cpumask_percpu_thread(&watchdog_threads,
794 &watchdog_cpumask); 794 &watchdog_cpumask);
795 __lockup_detector_cleanup(); 795 __lockup_detector_cleanup();
796 } 796 }
797 return 0;
798} 797}
799 798
800static void proc_watchdog_cpumask_update(void) 799static void proc_watchdog_cpumask_update(void)
801{ 800{
802 /* Remove impossible cpus to keep sysctl output clean. */ 801 /* Remove impossible cpus to keep sysctl output clean. */
803 cpumask_and(&watchdog_cpumask, &watchdog_cpumask, cpu_possible_mask); 802 cpumask_and(&watchdog_cpumask, &watchdog_cpumask, cpu_possible_mask);
804 803 watchdog_update_cpus();
805 if (watchdog_running) {
806 /*
807 * Failure would be due to being unable to allocate a
808 * temporary cpumask, so we are likely not in a position to
809 * do much else to make things better.
810 */
811 if (watchdog_update_cpus() != 0)
812 pr_err("cpumask update failed\n");
813 }
814
815 watchdog_nmi_reconfigure(); 804 watchdog_nmi_reconfigure();
816} 805}
817 806