From 5d79075199b4c0891fc8390d23c573825ca28deb Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 3 Feb 2004 18:31:50 -0800 Subject: [PATCH] [PATCH] lock_cpu_hotplug only if CONFIG_CPU_HOTPLUG From: Rusty Russell The cpucontrol mutex is not required when no cpus can go up and down. Andrew wrote a wrapper for it to avoid #ifdefs, this expands that to only be defined for CONFIG_HOTPLUG_CPU, and uses it everywhere. The only downside is that the cpucontrol lock was overloaded by my recent patch to net/core/flow.c to protect it from reentrance, so this reintroduces the local flow_flush_sem. This code isn't speed critical, so taking two locks when CONFIG_HOTPLUG_CPU=y is not really an issue. --- include/linux/cpu.h | 14 ++++++++------ kernel/module.c | 6 +++--- net/core/flow.c | 6 ++++-- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 02579ec6b99cf..5ecc291dc138f 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -38,9 +38,6 @@ extern void unregister_cpu_notifier(struct notifier_block *nb); int cpu_up(unsigned int cpu); -#define lock_cpu_hotplug() down(&cpucontrol) -#define unlock_cpu_hotplug() up(&cpucontrol) - #else static inline int register_cpu_notifier(struct notifier_block *nb) @@ -51,12 +48,17 @@ static inline void unregister_cpu_notifier(struct notifier_block *nb) { } -#define lock_cpu_hotplug() do { } while (0) -#define unlock_cpu_hotplug() do { } while (0) - #endif /* CONFIG_SMP */ extern struct sysdev_class cpu_sysdev_class; +#ifdef CONFIG_HOTPLUG_CPU /* Stop CPUs going up and down. */ extern struct semaphore cpucontrol; +#define lock_cpu_hotplug() down(&cpucontrol) +#define unlock_cpu_hotplug() up(&cpucontrol) +#else +#define lock_cpu_hotplug() do { } while (0) +#define unlock_cpu_hotplug() do { } while (0) +#endif + #endif /* _LINUX_CPU_H_ */ diff --git a/kernel/module.c b/kernel/module.c index fc934874c881b..a51fa89ed1a17 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -554,7 +554,7 @@ static int stop_refcounts(void) stopref_state = STOPREF_WAIT; /* No CPUs can come up or down during this. */ - down(&cpucontrol); + lock_cpu_hotplug(); for (i = 0; i < NR_CPUS; i++) { if (i == cpu || !cpu_online(i)) @@ -572,7 +572,7 @@ static int stop_refcounts(void) /* If some failed, kill them all. */ if (ret < 0) { stopref_set_state(STOPREF_EXIT, 1); - up(&cpucontrol); + unlock_cpu_hotplug(); return ret; } @@ -595,7 +595,7 @@ static void restart_refcounts(void) stopref_set_state(STOPREF_EXIT, 0); local_irq_enable(); preempt_enable(); - up(&cpucontrol); + unlock_cpu_hotplug(); } #else /* ...!SMP */ static inline int stop_refcounts(void) diff --git a/net/core/flow.c b/net/core/flow.c index f13a1752b6032..cef037afdf412 100644 --- a/net/core/flow.c +++ b/net/core/flow.c @@ -283,10 +283,11 @@ static void flow_cache_flush_per_cpu(void *data) void flow_cache_flush(void) { struct flow_flush_info info; + static DECLARE_MUTEX(flow_flush_sem); - /* Don't want cpus going down or up during this, also protects - * against multiple callers. */ + /* Don't want cpus going down or up during this. */ lock_cpu_hotplug(); + down(&flow_flush_sem); atomic_set(&info.cpuleft, num_online_cpus()); init_completion(&info.completion); @@ -296,6 +297,7 @@ void flow_cache_flush(void) local_bh_enable(); wait_for_completion(&info.completion); + up(&flow_flush_sem); unlock_cpu_hotplug(); } -- 2.53.0