Commit 86fffe4a authored by Chris Wilson's avatar Chris Wilson Committed by Linus Torvalds

kernel: remove stop_machine() Kconfig dependency

Currently the full stop_machine() routine is only enabled on SMP if
module unloading is enabled, or if the CPUs are hotpluggable.  This
leads to configurations where stop_machine() is broken as it will then
only run the callback on the local CPU with irqs disabled, and not stop
the other CPUs or run the callback on them.

For example, this breaks MTRR setup on x86 in certain configs since
ea8596bb ("kprobes/x86: Remove unused text_poke_smp() and
text_poke_smp_batch() functions") as the MTRR is only established on the
boot CPU.

This patch removes the Kconfig option for STOP_MACHINE and uses the SMP
and HOTPLUG_CPU config options to compile the correct stop_machine() for
the architecture, removing the false dependency on MODULE_UNLOAD in the
process.

Link: https://lkml.org/lkml/2014/10/8/124
References: https://bugs.freedesktop.org/show_bug.cgi?id=84794Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Acked-by: default avatarIngo Molnar <mingo@kernel.org>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Pranith Kumar <bobby.prani@gmail.com>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Vladimir Davydov <vdavydov@parallels.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: H. Peter Anvin <hpa@linux.intel.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Iulia Manda <iulia.manda21@gmail.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Chuck Ebbert <cebbert.lkml@gmail.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 98e89cf0
...@@ -99,7 +99,7 @@ static inline int try_stop_cpus(const struct cpumask *cpumask, ...@@ -99,7 +99,7 @@ static inline int try_stop_cpus(const struct cpumask *cpumask,
* grabbing every spinlock (and more). So the "read" side to such a * grabbing every spinlock (and more). So the "read" side to such a
* lock is anything which disables preemption. * lock is anything which disables preemption.
*/ */
#if defined(CONFIG_STOP_MACHINE) && defined(CONFIG_SMP) #if defined(CONFIG_SMP) || defined(CONFIG_HOTPLUG_CPU)
/** /**
* stop_machine: freeze the machine on all CPUs and run this function * stop_machine: freeze the machine on all CPUs and run this function
...@@ -118,7 +118,7 @@ int stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus); ...@@ -118,7 +118,7 @@ int stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus);
int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data, int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data,
const struct cpumask *cpus); const struct cpumask *cpus);
#else /* CONFIG_STOP_MACHINE && CONFIG_SMP */ #else /* CONFIG_SMP || CONFIG_HOTPLUG_CPU */
static inline int stop_machine(cpu_stop_fn_t fn, void *data, static inline int stop_machine(cpu_stop_fn_t fn, void *data,
const struct cpumask *cpus) const struct cpumask *cpus)
...@@ -137,5 +137,5 @@ static inline int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data, ...@@ -137,5 +137,5 @@ static inline int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data,
return stop_machine(fn, data, cpus); return stop_machine(fn, data, cpus);
} }
#endif /* CONFIG_STOP_MACHINE && CONFIG_SMP */ #endif /* CONFIG_SMP || CONFIG_HOTPLUG_CPU */
#endif /* _LINUX_STOP_MACHINE */ #endif /* _LINUX_STOP_MACHINE */
...@@ -2030,13 +2030,6 @@ config INIT_ALL_POSSIBLE ...@@ -2030,13 +2030,6 @@ config INIT_ALL_POSSIBLE
it was better to provide this option than to break all the archs it was better to provide this option than to break all the archs
and have several arch maintainers pursuing me down dark alleys. and have several arch maintainers pursuing me down dark alleys.
config STOP_MACHINE
bool
default y
depends on (SMP && MODULE_UNLOAD) || HOTPLUG_CPU
help
Need stop_machine() primitive.
source "block/Kconfig" source "block/Kconfig"
config PREEMPT_NOTIFIERS config PREEMPT_NOTIFIERS
......
...@@ -531,7 +531,7 @@ static int __init cpu_stop_init(void) ...@@ -531,7 +531,7 @@ static int __init cpu_stop_init(void)
} }
early_initcall(cpu_stop_init); early_initcall(cpu_stop_init);
#ifdef CONFIG_STOP_MACHINE #if defined(CONFIG_SMP) || defined(CONFIG_HOTPLUG_CPU)
static int __stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus) static int __stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus)
{ {
...@@ -631,4 +631,4 @@ int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data, ...@@ -631,4 +631,4 @@ int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data,
return ret ?: done.ret; return ret ?: done.ret;
} }
#endif /* CONFIG_STOP_MACHINE */ #endif /* CONFIG_SMP || CONFIG_HOTPLUG_CPU */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment