aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-10-27 20:12:41 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-10-27 20:12:41 -0400
commit5c2aae8355f7ec1341d5c473c500a77bbfa7f701 (patch)
treebdb6059fbc1b476c36e7cda433fc4db64c627407
parent3fbc4d63744b21ed6814ce768672531500bd3f14 (diff)
parent16ff816d3b5d2b81fcff5ca44eb9a98ac3b604b4 (diff)
Merge branch 'acpi-hotplug'
* acpi-hotplug: ACPI / memhotplug: Use defined marco METHOD_NAME__STA ACPI / hotplug: Use kobject_init_and_add() instead of _init() and _add() ACPI / hotplug: Don't set kobject parent pointer explicitly ACPI / hotplug: Set kobject name via kobject_add(), not kobject_set_name() hotplug, powerpc, x86: Remove cpu_hotplug_driver_lock() hotplug / x86: Disable ARCH_CPU_PROBE_RELEASE on x86 hotplug / x86: Add hotplug lock to missing places hotplug / x86: Fix online state in cpu0 debug interface
-rw-r--r--arch/powerpc/kernel/smp.c12
-rw-r--r--arch/powerpc/platforms/pseries/dlpar.c43
-rw-r--r--arch/x86/Kconfig4
-rw-r--r--arch/x86/kernel/smpboot.c21
-rw-r--r--arch/x86/kernel/topology.c11
-rw-r--r--drivers/acpi/acpi_memhotplug.c5
-rw-r--r--drivers/acpi/sysfs.c9
-rw-r--r--drivers/base/cpu.c39
-rw-r--r--include/linux/cpu.h13
9 files changed, 53 insertions, 104 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 8e59abc237d7..930cd8af3503 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -844,18 +844,6 @@ void __cpu_die(unsigned int cpu)
844 smp_ops->cpu_die(cpu); 844 smp_ops->cpu_die(cpu);
845} 845}
846 846
847static DEFINE_MUTEX(powerpc_cpu_hotplug_driver_mutex);
848
849void cpu_hotplug_driver_lock()
850{
851 mutex_lock(&powerpc_cpu_hotplug_driver_mutex);
852}
853
854void cpu_hotplug_driver_unlock()
855{
856 mutex_unlock(&powerpc_cpu_hotplug_driver_mutex);
857}
858
859void cpu_die(void) 847void cpu_die(void)
860{ 848{
861 if (ppc_md.cpu_die) 849 if (ppc_md.cpu_die)
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index 7cfdaae1721a..a8fe5aa3d34f 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -404,46 +404,38 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
404 unsigned long drc_index; 404 unsigned long drc_index;
405 int rc; 405 int rc;
406 406
407 cpu_hotplug_driver_lock();
408 rc = strict_strtoul(buf, 0, &drc_index); 407 rc = strict_strtoul(buf, 0, &drc_index);
409 if (rc) { 408 if (rc)
410 rc = -EINVAL; 409 return -EINVAL;
411 goto out;
412 }
413 410
414 parent = of_find_node_by_path("/cpus"); 411 parent = of_find_node_by_path("/cpus");
415 if (!parent) { 412 if (!parent)
416 rc = -ENODEV; 413 return -ENODEV;
417 goto out;
418 }
419 414
420 dn = dlpar_configure_connector(drc_index, parent); 415 dn = dlpar_configure_connector(drc_index, parent);
421 if (!dn) { 416 if (!dn)
422 rc = -EINVAL; 417 return -EINVAL;
423 goto out;
424 }
425 418
426 of_node_put(parent); 419 of_node_put(parent);
427 420
428 rc = dlpar_acquire_drc(drc_index); 421 rc = dlpar_acquire_drc(drc_index);
429 if (rc) { 422 if (rc) {
430 dlpar_free_cc_nodes(dn); 423 dlpar_free_cc_nodes(dn);
431 rc = -EINVAL; 424 return -EINVAL;
432 goto out;
433 } 425 }
434 426
435 rc = dlpar_attach_node(dn); 427 rc = dlpar_attach_node(dn);
436 if (rc) { 428 if (rc) {
437 dlpar_release_drc(drc_index); 429 dlpar_release_drc(drc_index);
438 dlpar_free_cc_nodes(dn); 430 dlpar_free_cc_nodes(dn);
439 goto out; 431 return rc;
440 } 432 }
441 433
442 rc = dlpar_online_cpu(dn); 434 rc = dlpar_online_cpu(dn);
443out: 435 if (rc)
444 cpu_hotplug_driver_unlock(); 436 return rc;
445 437
446 return rc ? rc : count; 438 return count;
447} 439}
448 440
449static int dlpar_offline_cpu(struct device_node *dn) 441static int dlpar_offline_cpu(struct device_node *dn)
@@ -516,30 +508,27 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count)
516 return -EINVAL; 508 return -EINVAL;
517 } 509 }
518 510
519 cpu_hotplug_driver_lock();
520 rc = dlpar_offline_cpu(dn); 511 rc = dlpar_offline_cpu(dn);
521 if (rc) { 512 if (rc) {
522 of_node_put(dn); 513 of_node_put(dn);
523 rc = -EINVAL; 514 return -EINVAL;
524 goto out;
525 } 515 }
526 516
527 rc = dlpar_release_drc(*drc_index); 517 rc = dlpar_release_drc(*drc_index);
528 if (rc) { 518 if (rc) {
529 of_node_put(dn); 519 of_node_put(dn);
530 goto out; 520 return rc;
531 } 521 }
532 522
533 rc = dlpar_detach_node(dn); 523 rc = dlpar_detach_node(dn);
534 if (rc) { 524 if (rc) {
535 dlpar_acquire_drc(*drc_index); 525 dlpar_acquire_drc(*drc_index);
536 goto out; 526 return rc;
537 } 527 }
538 528
539 of_node_put(dn); 529 of_node_put(dn);
540out: 530
541 cpu_hotplug_driver_unlock(); 531 return count;
542 return rc ? rc : count;
543} 532}
544 533
545static int __init pseries_dlpar_init(void) 534static int __init pseries_dlpar_init(void)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index f67e839f06c8..0c11032e2e91 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -254,10 +254,6 @@ config ARCH_HWEIGHT_CFLAGS
254 default "-fcall-saved-ecx -fcall-saved-edx" if X86_32 254 default "-fcall-saved-ecx -fcall-saved-edx" if X86_32
255 default "-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" if X86_64 255 default "-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" if X86_64
256 256
257config ARCH_CPU_PROBE_RELEASE
258 def_bool y
259 depends on HOTPLUG_CPU
260
261config ARCH_SUPPORTS_UPROBES 257config ARCH_SUPPORTS_UPROBES
262 def_bool y 258 def_bool y
263 259
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 6cacab671f9b..e73b3f53310c 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -82,27 +82,6 @@
82/* State of each CPU */ 82/* State of each CPU */
83DEFINE_PER_CPU(int, cpu_state) = { 0 }; 83DEFINE_PER_CPU(int, cpu_state) = { 0 };
84 84
85#ifdef CONFIG_HOTPLUG_CPU
86/*
87 * We need this for trampoline_base protection from concurrent accesses when
88 * off- and onlining cores wildly.
89 */
90static DEFINE_MUTEX(x86_cpu_hotplug_driver_mutex);
91
92void cpu_hotplug_driver_lock(void)
93{
94 mutex_lock(&x86_cpu_hotplug_driver_mutex);
95}
96
97void cpu_hotplug_driver_unlock(void)
98{
99 mutex_unlock(&x86_cpu_hotplug_driver_mutex);
100}
101
102ssize_t arch_cpu_probe(const char *buf, size_t count) { return -1; }
103ssize_t arch_cpu_release(const char *buf, size_t count) { return -1; }
104#endif
105
106/* Number of siblings per CPU package */ 85/* Number of siblings per CPU package */
107int smp_num_siblings = 1; 86int smp_num_siblings = 1;
108EXPORT_SYMBOL(smp_num_siblings); 87EXPORT_SYMBOL(smp_num_siblings);
diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
index 6e60b5fe2244..649b010da00b 100644
--- a/arch/x86/kernel/topology.c
+++ b/arch/x86/kernel/topology.c
@@ -65,29 +65,32 @@ int __ref _debug_hotplug_cpu(int cpu, int action)
65 if (!cpu_is_hotpluggable(cpu)) 65 if (!cpu_is_hotpluggable(cpu))
66 return -EINVAL; 66 return -EINVAL;
67 67
68 cpu_hotplug_driver_lock(); 68 lock_device_hotplug();
69 69
70 switch (action) { 70 switch (action) {
71 case 0: 71 case 0:
72 ret = cpu_down(cpu); 72 ret = cpu_down(cpu);
73 if (!ret) { 73 if (!ret) {
74 pr_info("CPU %u is now offline\n", cpu); 74 pr_info("CPU %u is now offline\n", cpu);
75 dev->offline = true;
75 kobject_uevent(&dev->kobj, KOBJ_OFFLINE); 76 kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
76 } else 77 } else
77 pr_debug("Can't offline CPU%d.\n", cpu); 78 pr_debug("Can't offline CPU%d.\n", cpu);
78 break; 79 break;
79 case 1: 80 case 1:
80 ret = cpu_up(cpu); 81 ret = cpu_up(cpu);
81 if (!ret) 82 if (!ret) {
83 dev->offline = false;
82 kobject_uevent(&dev->kobj, KOBJ_ONLINE); 84 kobject_uevent(&dev->kobj, KOBJ_ONLINE);
83 else 85 } else {
84 pr_debug("Can't online CPU%d.\n", cpu); 86 pr_debug("Can't online CPU%d.\n", cpu);
87 }
85 break; 88 break;
86 default: 89 default:
87 ret = -EINVAL; 90 ret = -EINVAL;
88 } 91 }
89 92
90 cpu_hotplug_driver_unlock(); 93 unlock_device_hotplug();
91 94
92 return ret; 95 return ret;
93} 96}
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index c00a3a73409b..551dad712ffe 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -152,8 +152,9 @@ static int acpi_memory_check_device(struct acpi_memory_device *mem_device)
152 unsigned long long current_status; 152 unsigned long long current_status;
153 153
154 /* Get device present/absent information from the _STA */ 154 /* Get device present/absent information from the _STA */
155 if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle, "_STA", 155 if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle,
156 NULL, &current_status))) 156 METHOD_NAME__STA, NULL,
157 &current_status)))
157 return -ENODEV; 158 return -ENODEV;
158 /* 159 /*
159 * Check for device status. Device should be 160 * Check for device status. Device should be
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index 05306a59aedc..bb6045c5385b 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -762,13 +762,8 @@ void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug,
762 if (!hotplug_kobj) 762 if (!hotplug_kobj)
763 goto err_out; 763 goto err_out;
764 764
765 kobject_init(&hotplug->kobj, &acpi_hotplug_profile_ktype); 765 error = kobject_init_and_add(&hotplug->kobj,
766 error = kobject_set_name(&hotplug->kobj, "%s", name); 766 &acpi_hotplug_profile_ktype, hotplug_kobj, "%s", name);
767 if (error)
768 goto err_out;
769
770 hotplug->kobj.parent = hotplug_kobj;
771 error = kobject_add(&hotplug->kobj, hotplug_kobj, NULL);
772 if (error) 767 if (error)
773 goto err_out; 768 goto err_out;
774 769
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 848ebbd25717..f48370dfc908 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -44,13 +44,11 @@ static int __ref cpu_subsys_online(struct device *dev)
44 struct cpu *cpu = container_of(dev, struct cpu, dev); 44 struct cpu *cpu = container_of(dev, struct cpu, dev);
45 int cpuid = dev->id; 45 int cpuid = dev->id;
46 int from_nid, to_nid; 46 int from_nid, to_nid;
47 int ret = -ENODEV; 47 int ret;
48
49 cpu_hotplug_driver_lock();
50 48
51 from_nid = cpu_to_node(cpuid); 49 from_nid = cpu_to_node(cpuid);
52 if (from_nid == NUMA_NO_NODE) 50 if (from_nid == NUMA_NO_NODE)
53 goto out; 51 return -ENODEV;
54 52
55 ret = cpu_up(cpuid); 53 ret = cpu_up(cpuid);
56 /* 54 /*
@@ -61,19 +59,12 @@ static int __ref cpu_subsys_online(struct device *dev)
61 if (from_nid != to_nid) 59 if (from_nid != to_nid)
62 change_cpu_under_node(cpu, from_nid, to_nid); 60 change_cpu_under_node(cpu, from_nid, to_nid);
63 61
64 out:
65 cpu_hotplug_driver_unlock();
66 return ret; 62 return ret;
67} 63}
68 64
69static int cpu_subsys_offline(struct device *dev) 65static int cpu_subsys_offline(struct device *dev)
70{ 66{
71 int ret; 67 return cpu_down(dev->id);
72
73 cpu_hotplug_driver_lock();
74 ret = cpu_down(dev->id);
75 cpu_hotplug_driver_unlock();
76 return ret;
77} 68}
78 69
79void unregister_cpu(struct cpu *cpu) 70void unregister_cpu(struct cpu *cpu)
@@ -93,7 +84,17 @@ static ssize_t cpu_probe_store(struct device *dev,
93 const char *buf, 84 const char *buf,
94 size_t count) 85 size_t count)
95{ 86{
96 return arch_cpu_probe(buf, count); 87 ssize_t cnt;
88 int ret;
89
90 ret = lock_device_hotplug_sysfs();
91 if (ret)
92 return ret;
93
94 cnt = arch_cpu_probe(buf, count);
95
96 unlock_device_hotplug();
97 return cnt;
97} 98}
98 99
99static ssize_t cpu_release_store(struct device *dev, 100static ssize_t cpu_release_store(struct device *dev,
@@ -101,7 +102,17 @@ static ssize_t cpu_release_store(struct device *dev,
101 const char *buf, 102 const char *buf,
102 size_t count) 103 size_t count)
103{ 104{
104 return arch_cpu_release(buf, count); 105 ssize_t cnt;
106 int ret;
107
108 ret = lock_device_hotplug_sysfs();
109 if (ret)
110 return ret;
111
112 cnt = arch_cpu_release(buf, count);
113
114 unlock_device_hotplug();
115 return cnt;
105} 116}
106 117
107static DEVICE_ATTR(probe, S_IWUSR, NULL, cpu_probe_store); 118static DEVICE_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 801ff9e73679..3434ef7de017 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -185,19 +185,6 @@ extern void cpu_hotplug_enable(void);
185void clear_tasks_mm_cpumask(int cpu); 185void clear_tasks_mm_cpumask(int cpu);
186int cpu_down(unsigned int cpu); 186int cpu_down(unsigned int cpu);
187 187
188#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
189extern void cpu_hotplug_driver_lock(void);
190extern void cpu_hotplug_driver_unlock(void);
191#else
192static inline void cpu_hotplug_driver_lock(void)
193{
194}
195
196static inline void cpu_hotplug_driver_unlock(void)
197{
198}
199#endif
200
201#else /* CONFIG_HOTPLUG_CPU */ 188#else /* CONFIG_HOTPLUG_CPU */
202 189
203static inline void cpu_hotplug_begin(void) {} 190static inline void cpu_hotplug_begin(void) {}