From 763ba1e4777b6be47c3d875e80ae9d9646500d7a Mon Sep 17 00:00:00 2001 From: Gautham R Shenoy Date: Thu, 26 Nov 2009 09:59:05 +0000 Subject: [PATCH] --- yaml --- r: 175826 b: refs/heads/master c: 51badebdcf394cc5fd574a524b55b3f6085e5e9c h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/powerpc/platforms/pseries/dlpar.c | 45 +++++++++++++++----- trunk/drivers/base/cpu.c | 2 + trunk/include/linux/cpu.h | 13 ++++++ 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/[refs] b/[refs] index 47a8910564be..139e49e6b893 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b6db63d1a7f0138f348ba7a648df35ac6365988e +refs/heads/master: 51badebdcf394cc5fd574a524b55b3f6085e5e9c diff --git a/trunk/arch/powerpc/platforms/pseries/dlpar.c b/trunk/arch/powerpc/platforms/pseries/dlpar.c index 642e1b2e5c42..fd2f0afeb4de 100644 --- a/trunk/arch/powerpc/platforms/pseries/dlpar.c +++ b/trunk/arch/powerpc/platforms/pseries/dlpar.c @@ -436,6 +436,18 @@ int dlpar_release_drc(u32 drc_index) #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE +static DEFINE_MUTEX(pseries_cpu_hotplug_mutex); + +void cpu_hotplug_driver_lock() +{ + mutex_lock(&pseries_cpu_hotplug_mutex); +} + +void cpu_hotplug_driver_unlock() +{ + mutex_unlock(&pseries_cpu_hotplug_mutex); +} + static ssize_t dlpar_cpu_probe(const char *buf, size_t count) { struct device_node *dn; @@ -443,13 +455,18 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count) char *cpu_name; int rc; + cpu_hotplug_driver_lock(); rc = strict_strtoul(buf, 0, &drc_index); - if (rc) - return -EINVAL; + if (rc) { + rc = -EINVAL; + goto out; + } dn = dlpar_configure_connector(drc_index); - if (!dn) - return -EINVAL; + if (!dn) { + rc = -EINVAL; + goto out; + } /* configure-connector reports cpus as living in the base * directory of the device tree. CPUs actually live in the @@ -459,7 +476,8 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count) GFP_KERNEL); if (!cpu_name) { dlpar_free_cc_nodes(dn); - return -ENOMEM; + rc = -ENOMEM; + goto out; } sprintf(cpu_name, "/cpus%s", dn->full_name); @@ -469,7 +487,8 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count) rc = dlpar_acquire_drc(drc_index); if (rc) { dlpar_free_cc_nodes(dn); - return -EINVAL; + rc = -EINVAL; + goto out; } rc = dlpar_attach_node(dn); @@ -479,6 +498,8 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count) } rc = online_node_cpus(dn); +out: + cpu_hotplug_driver_unlock(); return rc ? rc : count; } @@ -499,26 +520,30 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count) return -EINVAL; } + cpu_hotplug_driver_lock(); rc = offline_node_cpus(dn); if (rc) { of_node_put(dn); - return -EINVAL; + rc = -EINVAL; + goto out; } rc = dlpar_release_drc(*drc_index); if (rc) { of_node_put(dn); - return -EINVAL; + goto out; } rc = dlpar_detach_node(dn); if (rc) { dlpar_acquire_drc(*drc_index); - return rc; + goto out; } of_node_put(dn); - return count; +out: + cpu_hotplug_driver_unlock(); + return rc ? rc : count; } static int __init pseries_dlpar_init(void) diff --git a/trunk/drivers/base/cpu.c b/trunk/drivers/base/cpu.c index 7c03af7b84a9..27fd775375b0 100644 --- a/trunk/drivers/base/cpu.c +++ b/trunk/drivers/base/cpu.c @@ -35,6 +35,7 @@ static ssize_t __ref store_online(struct sys_device *dev, struct sysdev_attribut struct cpu *cpu = container_of(dev, struct cpu, sysdev); ssize_t ret; + cpu_hotplug_driver_lock(); switch (buf[0]) { case '0': ret = cpu_down(cpu->sysdev.id); @@ -49,6 +50,7 @@ static ssize_t __ref store_online(struct sys_device *dev, struct sysdev_attribut default: ret = -EINVAL; } + cpu_hotplug_driver_unlock(); if (ret >= 0) ret = count; diff --git a/trunk/include/linux/cpu.h b/trunk/include/linux/cpu.h index c972f7ccb7d3..e287863ac053 100644 --- a/trunk/include/linux/cpu.h +++ b/trunk/include/linux/cpu.h @@ -117,6 +117,19 @@ extern void put_online_cpus(void); #define unregister_hotcpu_notifier(nb) unregister_cpu_notifier(nb) int cpu_down(unsigned int cpu); +#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE +extern void cpu_hotplug_driver_lock(void); +extern void cpu_hotplug_driver_unlock(void); +#else +static inline void cpu_hotplug_driver_lock(void) +{ +} + +static inline void cpu_hotplug_driver_unlock(void) +{ +} +#endif + #else /* CONFIG_HOTPLUG_CPU */ #define get_online_cpus() do { } while (0)