* [PATCH 1/5] Move rtas_stop_self() into platforms/pseries/hotplug-cpu.c
@ 2006-12-05 6:52 Michael Ellerman
2006-12-05 6:52 ` [PATCH 2/5] Move pSeries_mach_cpu_die() " Michael Ellerman
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Michael Ellerman @ 2006-12-05 6:52 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
As the first step in consolidating the pseries hotplug cpu code,
create platforms/pseries/hotplug-cpu.c and move rtas_stop_self()
into it. Do the rtas token initialisation in a new initcall, rather
than rtas_initialize()
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/kernel/rtas.c | 29 -------------
arch/powerpc/platforms/pseries/Makefile | 2
arch/powerpc/platforms/pseries/hotplug-cpu.c | 58 +++++++++++++++++++++++++++
3 files changed, 60 insertions(+), 29 deletions(-)
Index: powerpc/arch/powerpc/kernel/rtas.c
===================================================================
--- powerpc.orig/arch/powerpc/kernel/rtas.c
+++ powerpc/arch/powerpc/kernel/rtas.c
@@ -810,32 +810,6 @@ asmlinkage int ppc_rtas(struct rtas_args
return 0;
}
-#ifdef CONFIG_HOTPLUG_CPU
-/* This version can't take the spinlock, because it never returns */
-static struct rtas_args rtas_stop_self_args = {
- /* The token is initialized for real in setup_system() */
- .token = RTAS_UNKNOWN_SERVICE,
- .nargs = 0,
- .nret = 1,
- .rets = &rtas_stop_self_args.args[0],
-};
-
-void rtas_stop_self(void)
-{
- struct rtas_args *rtas_args = &rtas_stop_self_args;
-
- local_irq_disable();
-
- BUG_ON(rtas_args->token == RTAS_UNKNOWN_SERVICE);
-
- printk("cpu %u (hwid %u) Ready to die...\n",
- smp_processor_id(), hard_smp_processor_id());
- enter_rtas(__pa(rtas_args));
-
- panic("Alas, I survived.\n");
-}
-#endif
-
/*
* Call early during boot, before mem init or bootmem, to retrieve the RTAS
* informations from the device-tree and allocate the RMO buffer for userland
@@ -880,9 +854,6 @@ void __init rtas_initialize(void)
#endif
rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region);
-#ifdef CONFIG_HOTPLUG_CPU
- rtas_stop_self_args.token = rtas_token("stop-self");
-#endif /* CONFIG_HOTPLUG_CPU */
#ifdef CONFIG_RTAS_ERROR_LOGGING
rtas_last_error_token = rtas_token("rtas-last-error");
#endif
Index: powerpc/arch/powerpc/platforms/pseries/Makefile
===================================================================
--- powerpc.orig/arch/powerpc/platforms/pseries/Makefile
+++ powerpc/arch/powerpc/platforms/pseries/Makefile
@@ -10,6 +10,8 @@ obj-$(CONFIG_XICS) += xics.o
obj-$(CONFIG_SCANLOG) += scanlog.o
obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o
+
obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
obj-$(CONFIG_HVCS) += hvcserver.o
obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o
Index: powerpc/arch/powerpc/platforms/pseries/hotplug-cpu.c
===================================================================
--- /dev/null
+++ powerpc/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -0,0 +1,58 @@
+/*
+ * pseries CPU Hotplug infrastructure.
+ *
+ * Split out from arch/powerpc/kernel/rtas.c
+ *
+ * Peter Bergner, IBM March 2001.
+ * Copyright (C) 2001 IBM.
+ *
+ * Copyright (C) 2006 Michael Ellerman, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/cpu.h>
+#include <asm/system.h>
+#include <asm/prom.h>
+#include <asm/rtas.h>
+#include <asm/firmware.h>
+#include <asm/machdep.h>
+#include <asm/vdso_datapage.h>
+#include <asm/pSeries_reconfig.h>
+#include "xics.h"
+
+/* This version can't take the spinlock, because it never returns */
+static struct rtas_args rtas_stop_self_args = {
+ .token = RTAS_UNKNOWN_SERVICE,
+ .nargs = 0,
+ .nret = 1,
+ .rets = &rtas_stop_self_args.args[0],
+};
+
+void rtas_stop_self(void)
+{
+ struct rtas_args *args = &rtas_stop_self_args;
+
+ local_irq_disable();
+
+ BUG_ON(args->token == RTAS_UNKNOWN_SERVICE);
+
+ printk("cpu %u (hwid %u) Ready to die...\n",
+ smp_processor_id(), hard_smp_processor_id());
+ enter_rtas(__pa(args));
+
+ panic("Alas, I survived.\n");
+}
+
+static int __init pseries_cpu_hotplug_init(void)
+{
+ rtas_stop_self_args.token = rtas_token("stop-self");
+
+ return 0;
+}
+arch_initcall(pseries_cpu_hotplug_init);
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/5] Move pSeries_mach_cpu_die() into platforms/pseries/hotplug-cpu.c
2006-12-05 6:52 [PATCH 1/5] Move rtas_stop_self() into platforms/pseries/hotplug-cpu.c Michael Ellerman
@ 2006-12-05 6:52 ` Michael Ellerman
2006-12-05 6:52 ` [PATCH 4/5] Only enable cpu hotplug via RTAS if the required firmware support is found Michael Ellerman
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Michael Ellerman @ 2006-12-05 6:52 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
Move pSeries_mach_cpu_die() into platforms/pseries/hotplug-cpu.c,
this allows rtas_stop_self() to be static so remove the prototype.
Wire up pSeries_mach_cpu_die() in the initcall, rather than statically
in setup.c, the initcall will still run prior to the cpu hotplug code
being callable, so there should be no change in behaviour.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/hotplug-cpu.c | 18 ++++++++++++++++--
arch/powerpc/platforms/pseries/setup.c | 16 ----------------
include/asm-powerpc/rtas.h | 2 --
3 files changed, 16 insertions(+), 20 deletions(-)
Index: powerpc/arch/powerpc/platforms/pseries/hotplug-cpu.c
===================================================================
--- powerpc.orig/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ powerpc/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -1,7 +1,8 @@
/*
* pseries CPU Hotplug infrastructure.
*
- * Split out from arch/powerpc/kernel/rtas.c
+ * Split out from arch/powerpc/platforms/pseries/setup.c and
+ * arch/powerpc/kernel/rtas.c
*
* Peter Bergner, IBM March 2001.
* Copyright (C) 2001 IBM.
@@ -34,7 +35,7 @@ static struct rtas_args rtas_stop_self_a
.rets = &rtas_stop_self_args.args[0],
};
-void rtas_stop_self(void)
+static void rtas_stop_self(void)
{
struct rtas_args *args = &rtas_stop_self_args;
@@ -49,10 +50,23 @@ void rtas_stop_self(void)
panic("Alas, I survived.\n");
}
+static void pSeries_mach_cpu_die(void)
+{
+ local_irq_disable();
+ idle_task_exit();
+ xics_teardown_cpu(0);
+ rtas_stop_self();
+ /* Should never get here... */
+ BUG();
+ for(;;);
+}
+
static int __init pseries_cpu_hotplug_init(void)
{
rtas_stop_self_args.token = rtas_token("stop-self");
+ ppc_md.cpu_die = pSeries_mach_cpu_die;
+
return 0;
}
arch_initcall(pseries_cpu_hotplug_init);
Index: powerpc/arch/powerpc/platforms/pseries/setup.c
===================================================================
--- powerpc.orig/arch/powerpc/platforms/pseries/setup.c
+++ powerpc/arch/powerpc/platforms/pseries/setup.c
@@ -347,21 +347,6 @@ static int __init pSeries_init_panel(voi
}
arch_initcall(pSeries_init_panel);
-#ifdef CONFIG_HOTPLUG_CPU
-static void pSeries_mach_cpu_die(void)
-{
- local_irq_disable();
- idle_task_exit();
- xics_teardown_cpu(0);
- rtas_stop_self();
- /* Should never get here... */
- BUG();
- for(;;);
-}
-#else
-#define pSeries_mach_cpu_die NULL
-#endif
-
static int pseries_set_dabr(unsigned long dabr)
{
return plpar_hcall_norets(H_SET_DABR, dabr);
@@ -561,7 +546,6 @@ define_machine(pseries) {
.power_off = rtas_power_off,
.halt = rtas_halt,
.panic = rtas_os_term,
- .cpu_die = pSeries_mach_cpu_die,
.get_boot_time = rtas_get_boot_time,
.get_rtc_time = rtas_get_rtc_time,
.set_rtc_time = rtas_set_rtc_time,
Index: powerpc/include/asm-powerpc/rtas.h
===================================================================
--- powerpc.orig/include/asm-powerpc/rtas.h
+++ powerpc/include/asm-powerpc/rtas.h
@@ -221,8 +221,6 @@ extern int rtas_get_error_log_max(void);
extern spinlock_t rtas_data_buf_lock;
extern char rtas_data_buf[RTAS_DATA_BUF_SIZE];
-extern void rtas_stop_self(void);
-
/* RMO buffer reserved for user-space RTAS use */
extern unsigned long rtas_rmo_buf;
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/5] Move the rest of the hotplug cpu code into platforms/pseries/hotplug-cpu.c
2006-12-05 6:52 [PATCH 1/5] Move rtas_stop_self() into platforms/pseries/hotplug-cpu.c Michael Ellerman
2006-12-05 6:52 ` [PATCH 2/5] Move pSeries_mach_cpu_die() " Michael Ellerman
2006-12-05 6:52 ` [PATCH 4/5] Only enable cpu hotplug via RTAS if the required firmware support is found Michael Ellerman
@ 2006-12-05 6:52 ` Michael Ellerman
2006-12-05 6:52 ` [PATCH 5/5] Cleanup pass over platforms/pseries/hotplug-cpu.c Michael Ellerman
2006-12-06 22:51 ` [PATCH 1/5] Move rtas_stop_self() into platforms/pseries/hotplug-cpu.c Linas Vepstas
4 siblings, 0 replies; 6+ messages in thread
From: Michael Ellerman @ 2006-12-05 6:52 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
Move the rest of the hotplug cpu code from platforms/pseries/smp.c into
platforms/pseries/hotplug-cpu.c.
Wire up the smp_ops callbacks and the notifier in the hotplug cpu initcall,
rather than in smp_init_pseries(). No change in behaviour.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/hotplug-cpu.c | 201 ++++++++++++++++++++++++++-
arch/powerpc/platforms/pseries/smp.c | 200 --------------------------
2 files changed, 199 insertions(+), 202 deletions(-)
Index: powerpc/arch/powerpc/platforms/pseries/hotplug-cpu.c
===================================================================
--- powerpc.orig/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ powerpc/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -1,11 +1,14 @@
/*
* pseries CPU Hotplug infrastructure.
*
- * Split out from arch/powerpc/platforms/pseries/setup.c and
- * arch/powerpc/kernel/rtas.c
+ * Split out from arch/powerpc/platforms/pseries/setup.c
+ * arch/powerpc/kernel/rtas.c, and arch/powerpc/platforms/pseries/smp.c
*
* Peter Bergner, IBM March 2001.
* Copyright (C) 2001 IBM.
+ * Dave Engebretsen, Peter Bergner, and
+ * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
+ * Plus various changes from other IBM teams...
*
* Copyright (C) 2006 Michael Ellerman, IBM Corporation
*
@@ -61,12 +64,206 @@ static void pSeries_mach_cpu_die(void)
for(;;);
}
+/* Get state of physical CPU.
+ * Return codes:
+ * 0 - The processor is in the RTAS stopped state
+ * 1 - stop-self is in progress
+ * 2 - The processor is not in the RTAS stopped state
+ * -1 - Hardware Error
+ * -2 - Hardware Busy, Try again later.
+ */
+static int query_cpu_stopped(unsigned int pcpu)
+{
+ int cpu_status;
+ int status, qcss_tok;
+
+ qcss_tok = rtas_token("query-cpu-stopped-state");
+ if (qcss_tok == RTAS_UNKNOWN_SERVICE)
+ return -1;
+ status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu);
+ if (status != 0) {
+ printk(KERN_ERR
+ "RTAS query-cpu-stopped-state failed: %i\n", status);
+ return status;
+ }
+
+ return cpu_status;
+}
+
+static int pSeries_cpu_disable(void)
+{
+ int cpu = smp_processor_id();
+
+ cpu_clear(cpu, cpu_online_map);
+ vdso_data->processorCount--;
+
+ /*fix boot_cpuid here*/
+ if (cpu == boot_cpuid)
+ boot_cpuid = any_online_cpu(cpu_online_map);
+
+ /* FIXME: abstract this to not be platform specific later on */
+ xics_migrate_irqs_away();
+ return 0;
+}
+
+static void pSeries_cpu_die(unsigned int cpu)
+{
+ int tries;
+ int cpu_status;
+ unsigned int pcpu = get_hard_smp_processor_id(cpu);
+
+ for (tries = 0; tries < 25; tries++) {
+ cpu_status = query_cpu_stopped(pcpu);
+ if (cpu_status == 0 || cpu_status == -1)
+ break;
+ msleep(200);
+ }
+ if (cpu_status != 0) {
+ printk("Querying DEAD? cpu %i (%i) shows %i\n",
+ cpu, pcpu, cpu_status);
+ }
+
+ /* Isolation and deallocation are definatly done by
+ * drslot_chrp_cpu. If they were not they would be
+ * done here. Change isolate state to Isolate and
+ * change allocation-state to Unusable.
+ */
+ paca[cpu].cpu_start = 0;
+}
+
+/*
+ * Update cpu_present_map and paca(s) for a new cpu node. The wrinkle
+ * here is that a cpu device node may represent up to two logical cpus
+ * in the SMT case. We must honor the assumption in other code that
+ * the logical ids for sibling SMT threads x and y are adjacent, such
+ * that x^1 == y and y^1 == x.
+ */
+static int pSeries_add_processor(struct device_node *np)
+{
+ unsigned int cpu;
+ cpumask_t candidate_map, tmp = CPU_MASK_NONE;
+ int err = -ENOSPC, len, nthreads, i;
+ const u32 *intserv;
+
+ intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len);
+ if (!intserv)
+ return 0;
+
+ nthreads = len / sizeof(u32);
+ for (i = 0; i < nthreads; i++)
+ cpu_set(i, tmp);
+
+ lock_cpu_hotplug();
+
+ BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map));
+
+ /* Get a bitmap of unoccupied slots. */
+ cpus_xor(candidate_map, cpu_possible_map, cpu_present_map);
+ if (cpus_empty(candidate_map)) {
+ /* If we get here, it most likely means that NR_CPUS is
+ * less than the partition's max processors setting.
+ */
+ printk(KERN_ERR "Cannot add cpu %s; this system configuration"
+ " supports %d logical cpus.\n", np->full_name,
+ cpus_weight(cpu_possible_map));
+ goto out_unlock;
+ }
+
+ while (!cpus_empty(tmp))
+ if (cpus_subset(tmp, candidate_map))
+ /* Found a range where we can insert the new cpu(s) */
+ break;
+ else
+ cpus_shift_left(tmp, tmp, nthreads);
+
+ if (cpus_empty(tmp)) {
+ printk(KERN_ERR "Unable to find space in cpu_present_map for"
+ " processor %s with %d thread(s)\n", np->name,
+ nthreads);
+ goto out_unlock;
+ }
+
+ for_each_cpu_mask(cpu, tmp) {
+ BUG_ON(cpu_isset(cpu, cpu_present_map));
+ cpu_set(cpu, cpu_present_map);
+ set_hard_smp_processor_id(cpu, *intserv++);
+ }
+ err = 0;
+out_unlock:
+ unlock_cpu_hotplug();
+ return err;
+}
+
+/*
+ * Update the present map for a cpu node which is going away, and set
+ * the hard id in the paca(s) to -1 to be consistent with boot time
+ * convention for non-present cpus.
+ */
+static void pSeries_remove_processor(struct device_node *np)
+{
+ unsigned int cpu;
+ int len, nthreads, i;
+ const u32 *intserv;
+
+ intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len);
+ if (!intserv)
+ return;
+
+ nthreads = len / sizeof(u32);
+
+ lock_cpu_hotplug();
+ for (i = 0; i < nthreads; i++) {
+ for_each_present_cpu(cpu) {
+ if (get_hard_smp_processor_id(cpu) != intserv[i])
+ continue;
+ BUG_ON(cpu_online(cpu));
+ cpu_clear(cpu, cpu_present_map);
+ set_hard_smp_processor_id(cpu, -1);
+ break;
+ }
+ if (cpu == NR_CPUS)
+ printk(KERN_WARNING "Could not find cpu to remove "
+ "with physical id 0x%x\n", intserv[i]);
+ }
+ unlock_cpu_hotplug();
+}
+
+static int pSeries_smp_notifier(struct notifier_block *nb, unsigned long action, void *node)
+{
+ int err = NOTIFY_OK;
+
+ switch (action) {
+ case PSERIES_RECONFIG_ADD:
+ if (pSeries_add_processor(node))
+ err = NOTIFY_BAD;
+ break;
+ case PSERIES_RECONFIG_REMOVE:
+ pSeries_remove_processor(node);
+ break;
+ default:
+ err = NOTIFY_DONE;
+ break;
+ }
+ return err;
+}
+
+static struct notifier_block pSeries_smp_nb = {
+ .notifier_call = pSeries_smp_notifier,
+};
+
static int __init pseries_cpu_hotplug_init(void)
{
rtas_stop_self_args.token = rtas_token("stop-self");
ppc_md.cpu_die = pSeries_mach_cpu_die;
+ smp_ops->cpu_disable = pSeries_cpu_disable;
+ smp_ops->cpu_die = pSeries_cpu_die;
+
+ /* Processors can be added/removed only on LPAR */
+ if (firmware_has_feature(FW_FEATURE_LPAR))
+ pSeries_reconfig_notifier_register(&pSeries_smp_nb);
+
return 0;
}
arch_initcall(pseries_cpu_hotplug_init);
Index: powerpc/arch/powerpc/platforms/pseries/smp.c
===================================================================
--- powerpc.orig/arch/powerpc/platforms/pseries/smp.c
+++ powerpc/arch/powerpc/platforms/pseries/smp.c
@@ -64,197 +64,6 @@ static cpumask_t of_spin_map;
extern void generic_secondary_smp_init(unsigned long);
-#ifdef CONFIG_HOTPLUG_CPU
-
-/* Get state of physical CPU.
- * Return codes:
- * 0 - The processor is in the RTAS stopped state
- * 1 - stop-self is in progress
- * 2 - The processor is not in the RTAS stopped state
- * -1 - Hardware Error
- * -2 - Hardware Busy, Try again later.
- */
-static int query_cpu_stopped(unsigned int pcpu)
-{
- int cpu_status;
- int status, qcss_tok;
-
- qcss_tok = rtas_token("query-cpu-stopped-state");
- if (qcss_tok == RTAS_UNKNOWN_SERVICE)
- return -1;
- status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu);
- if (status != 0) {
- printk(KERN_ERR
- "RTAS query-cpu-stopped-state failed: %i\n", status);
- return status;
- }
-
- return cpu_status;
-}
-
-static int pSeries_cpu_disable(void)
-{
- int cpu = smp_processor_id();
-
- cpu_clear(cpu, cpu_online_map);
- vdso_data->processorCount--;
-
- /*fix boot_cpuid here*/
- if (cpu == boot_cpuid)
- boot_cpuid = any_online_cpu(cpu_online_map);
-
- /* FIXME: abstract this to not be platform specific later on */
- xics_migrate_irqs_away();
- return 0;
-}
-
-static void pSeries_cpu_die(unsigned int cpu)
-{
- int tries;
- int cpu_status;
- unsigned int pcpu = get_hard_smp_processor_id(cpu);
-
- for (tries = 0; tries < 25; tries++) {
- cpu_status = query_cpu_stopped(pcpu);
- if (cpu_status == 0 || cpu_status == -1)
- break;
- msleep(200);
- }
- if (cpu_status != 0) {
- printk("Querying DEAD? cpu %i (%i) shows %i\n",
- cpu, pcpu, cpu_status);
- }
-
- /* Isolation and deallocation are definatly done by
- * drslot_chrp_cpu. If they were not they would be
- * done here. Change isolate state to Isolate and
- * change allocation-state to Unusable.
- */
- paca[cpu].cpu_start = 0;
-}
-
-/*
- * Update cpu_present_map and paca(s) for a new cpu node. The wrinkle
- * here is that a cpu device node may represent up to two logical cpus
- * in the SMT case. We must honor the assumption in other code that
- * the logical ids for sibling SMT threads x and y are adjacent, such
- * that x^1 == y and y^1 == x.
- */
-static int pSeries_add_processor(struct device_node *np)
-{
- unsigned int cpu;
- cpumask_t candidate_map, tmp = CPU_MASK_NONE;
- int err = -ENOSPC, len, nthreads, i;
- const u32 *intserv;
-
- intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len);
- if (!intserv)
- return 0;
-
- nthreads = len / sizeof(u32);
- for (i = 0; i < nthreads; i++)
- cpu_set(i, tmp);
-
- lock_cpu_hotplug();
-
- BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map));
-
- /* Get a bitmap of unoccupied slots. */
- cpus_xor(candidate_map, cpu_possible_map, cpu_present_map);
- if (cpus_empty(candidate_map)) {
- /* If we get here, it most likely means that NR_CPUS is
- * less than the partition's max processors setting.
- */
- printk(KERN_ERR "Cannot add cpu %s; this system configuration"
- " supports %d logical cpus.\n", np->full_name,
- cpus_weight(cpu_possible_map));
- goto out_unlock;
- }
-
- while (!cpus_empty(tmp))
- if (cpus_subset(tmp, candidate_map))
- /* Found a range where we can insert the new cpu(s) */
- break;
- else
- cpus_shift_left(tmp, tmp, nthreads);
-
- if (cpus_empty(tmp)) {
- printk(KERN_ERR "Unable to find space in cpu_present_map for"
- " processor %s with %d thread(s)\n", np->name,
- nthreads);
- goto out_unlock;
- }
-
- for_each_cpu_mask(cpu, tmp) {
- BUG_ON(cpu_isset(cpu, cpu_present_map));
- cpu_set(cpu, cpu_present_map);
- set_hard_smp_processor_id(cpu, *intserv++);
- }
- err = 0;
-out_unlock:
- unlock_cpu_hotplug();
- return err;
-}
-
-/*
- * Update the present map for a cpu node which is going away, and set
- * the hard id in the paca(s) to -1 to be consistent with boot time
- * convention for non-present cpus.
- */
-static void pSeries_remove_processor(struct device_node *np)
-{
- unsigned int cpu;
- int len, nthreads, i;
- const u32 *intserv;
-
- intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len);
- if (!intserv)
- return;
-
- nthreads = len / sizeof(u32);
-
- lock_cpu_hotplug();
- for (i = 0; i < nthreads; i++) {
- for_each_present_cpu(cpu) {
- if (get_hard_smp_processor_id(cpu) != intserv[i])
- continue;
- BUG_ON(cpu_online(cpu));
- cpu_clear(cpu, cpu_present_map);
- set_hard_smp_processor_id(cpu, -1);
- break;
- }
- if (cpu == NR_CPUS)
- printk(KERN_WARNING "Could not find cpu to remove "
- "with physical id 0x%x\n", intserv[i]);
- }
- unlock_cpu_hotplug();
-}
-
-static int pSeries_smp_notifier(struct notifier_block *nb, unsigned long action, void *node)
-{
- int err = NOTIFY_OK;
-
- switch (action) {
- case PSERIES_RECONFIG_ADD:
- if (pSeries_add_processor(node))
- err = NOTIFY_BAD;
- break;
- case PSERIES_RECONFIG_REMOVE:
- pSeries_remove_processor(node);
- break;
- default:
- err = NOTIFY_DONE;
- break;
- }
- return err;
-}
-
-static struct notifier_block pSeries_smp_nb = {
- .notifier_call = pSeries_smp_notifier,
-};
-
-#endif /* CONFIG_HOTPLUG_CPU */
-
/**
* smp_startup_cpu() - start the given cpu
*
@@ -422,15 +231,6 @@ static void __init smp_init_pseries(void
DBG(" -> smp_init_pSeries()\n");
-#ifdef CONFIG_HOTPLUG_CPU
- smp_ops->cpu_disable = pSeries_cpu_disable;
- smp_ops->cpu_die = pSeries_cpu_die;
-
- /* Processors can be added/removed only on LPAR */
- if (firmware_has_feature(FW_FEATURE_LPAR))
- pSeries_reconfig_notifier_register(&pSeries_smp_nb);
-#endif
-
/* Mark threads which are still spinning in hold loops. */
if (cpu_has_feature(CPU_FTR_SMT)) {
for_each_present_cpu(i) {
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 4/5] Only enable cpu hotplug via RTAS if the required firmware support is found
2006-12-05 6:52 [PATCH 1/5] Move rtas_stop_self() into platforms/pseries/hotplug-cpu.c Michael Ellerman
2006-12-05 6:52 ` [PATCH 2/5] Move pSeries_mach_cpu_die() " Michael Ellerman
@ 2006-12-05 6:52 ` Michael Ellerman
2006-12-05 6:52 ` [PATCH 3/5] Move the rest of the hotplug cpu code into platforms/pseries/hotplug-cpu.c Michael Ellerman
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Michael Ellerman @ 2006-12-05 6:52 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
To support cpu hotplug on pseries we require two RTAS tokens, the cpu
hotplug machinery should only be wired up if these tokens are found in
the device tree.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/hotplug-cpu.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
Index: powerpc/arch/powerpc/platforms/pseries/hotplug-cpu.c
===================================================================
--- powerpc.orig/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ powerpc/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -64,6 +64,8 @@ static void pSeries_mach_cpu_die(void)
for(;;);
}
+static int qcss_tok; /* query-cpu-stopped-state token */
+
/* Get state of physical CPU.
* Return codes:
* 0 - The processor is in the RTAS stopped state
@@ -74,12 +76,8 @@ static void pSeries_mach_cpu_die(void)
*/
static int query_cpu_stopped(unsigned int pcpu)
{
- int cpu_status;
- int status, qcss_tok;
+ int cpu_status, status;
- qcss_tok = rtas_token("query-cpu-stopped-state");
- if (qcss_tok == RTAS_UNKNOWN_SERVICE)
- return -1;
status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu);
if (status != 0) {
printk(KERN_ERR
@@ -254,9 +252,16 @@ static struct notifier_block pSeries_smp
static int __init pseries_cpu_hotplug_init(void)
{
rtas_stop_self_args.token = rtas_token("stop-self");
+ qcss_tok = rtas_token("query-cpu-stopped-state");
- ppc_md.cpu_die = pSeries_mach_cpu_die;
+ if (rtas_stop_self_args.token == RTAS_UNKNOWN_SERVICE ||
+ qcss_tok == RTAS_UNKNOWN_SERVICE) {
+ printk(KERN_INFO "CPU Hotplug not supported by firmware "
+ "- disabling.\n");
+ return 0;
+ }
+ ppc_md.cpu_die = pSeries_mach_cpu_die;
smp_ops->cpu_disable = pSeries_cpu_disable;
smp_ops->cpu_die = pSeries_cpu_die;
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 5/5] Cleanup pass over platforms/pseries/hotplug-cpu.c
2006-12-05 6:52 [PATCH 1/5] Move rtas_stop_self() into platforms/pseries/hotplug-cpu.c Michael Ellerman
` (2 preceding siblings ...)
2006-12-05 6:52 ` [PATCH 3/5] Move the rest of the hotplug cpu code into platforms/pseries/hotplug-cpu.c Michael Ellerman
@ 2006-12-05 6:52 ` Michael Ellerman
2006-12-06 22:51 ` [PATCH 1/5] Move rtas_stop_self() into platforms/pseries/hotplug-cpu.c Linas Vepstas
4 siblings, 0 replies; 6+ messages in thread
From: Michael Ellerman @ 2006-12-05 6:52 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
Purely cosmetic. Change pSeries to pseries inline with other parts of the
kernel, and fix an overly long line.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/hotplug-cpu.c | 29 +++++++++++++--------------
1 file changed, 15 insertions(+), 14 deletions(-)
Index: powerpc/arch/powerpc/platforms/pseries/hotplug-cpu.c
===================================================================
--- powerpc.orig/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ powerpc/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -53,7 +53,7 @@ static void rtas_stop_self(void)
panic("Alas, I survived.\n");
}
-static void pSeries_mach_cpu_die(void)
+static void pseries_mach_cpu_die(void)
{
local_irq_disable();
idle_task_exit();
@@ -88,7 +88,7 @@ static int query_cpu_stopped(unsigned in
return cpu_status;
}
-static int pSeries_cpu_disable(void)
+static int pseries_cpu_disable(void)
{
int cpu = smp_processor_id();
@@ -104,7 +104,7 @@ static int pSeries_cpu_disable(void)
return 0;
}
-static void pSeries_cpu_die(unsigned int cpu)
+static void pseries_cpu_die(unsigned int cpu)
{
int tries;
int cpu_status;
@@ -136,7 +136,7 @@ static void pSeries_cpu_die(unsigned int
* the logical ids for sibling SMT threads x and y are adjacent, such
* that x^1 == y and y^1 == x.
*/
-static int pSeries_add_processor(struct device_node *np)
+static int pseries_add_processor(struct device_node *np)
{
unsigned int cpu;
cpumask_t candidate_map, tmp = CPU_MASK_NONE;
@@ -197,7 +197,7 @@ out_unlock:
* the hard id in the paca(s) to -1 to be consistent with boot time
* convention for non-present cpus.
*/
-static void pSeries_remove_processor(struct device_node *np)
+static void pseries_remove_processor(struct device_node *np)
{
unsigned int cpu;
int len, nthreads, i;
@@ -226,17 +226,18 @@ static void pSeries_remove_processor(str
unlock_cpu_hotplug();
}
-static int pSeries_smp_notifier(struct notifier_block *nb, unsigned long action, void *node)
+static int pseries_smp_notifier(struct notifier_block *nb,
+ unsigned long action, void *node)
{
int err = NOTIFY_OK;
switch (action) {
case PSERIES_RECONFIG_ADD:
- if (pSeries_add_processor(node))
+ if (pseries_add_processor(node))
err = NOTIFY_BAD;
break;
case PSERIES_RECONFIG_REMOVE:
- pSeries_remove_processor(node);
+ pseries_remove_processor(node);
break;
default:
err = NOTIFY_DONE;
@@ -245,8 +246,8 @@ static int pSeries_smp_notifier(struct n
return err;
}
-static struct notifier_block pSeries_smp_nb = {
- .notifier_call = pSeries_smp_notifier,
+static struct notifier_block pseries_smp_nb = {
+ .notifier_call = pseries_smp_notifier,
};
static int __init pseries_cpu_hotplug_init(void)
@@ -261,13 +262,13 @@ static int __init pseries_cpu_hotplug_in
return 0;
}
- ppc_md.cpu_die = pSeries_mach_cpu_die;
- smp_ops->cpu_disable = pSeries_cpu_disable;
- smp_ops->cpu_die = pSeries_cpu_die;
+ ppc_md.cpu_die = pseries_mach_cpu_die;
+ smp_ops->cpu_disable = pseries_cpu_disable;
+ smp_ops->cpu_die = pseries_cpu_die;
/* Processors can be added/removed only on LPAR */
if (firmware_has_feature(FW_FEATURE_LPAR))
- pSeries_reconfig_notifier_register(&pSeries_smp_nb);
+ pSeries_reconfig_notifier_register(&pseries_smp_nb);
return 0;
}
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/5] Move rtas_stop_self() into platforms/pseries/hotplug-cpu.c
2006-12-05 6:52 [PATCH 1/5] Move rtas_stop_self() into platforms/pseries/hotplug-cpu.c Michael Ellerman
` (3 preceding siblings ...)
2006-12-05 6:52 ` [PATCH 5/5] Cleanup pass over platforms/pseries/hotplug-cpu.c Michael Ellerman
@ 2006-12-06 22:51 ` Linas Vepstas
4 siblings, 0 replies; 6+ messages in thread
From: Linas Vepstas @ 2006-12-06 22:51 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Paul Mackerras
On Tue, Dec 05, 2006 at 05:52:36PM +1100, Michael Ellerman wrote:
> As the first step in consolidating the pseries hotplug cpu code,
>
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
As per previous discussion,
Acked-by: Linas Vepstas <linas@austin.ibm.cm>
--linas
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2006-12-06 22:51 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-05 6:52 [PATCH 1/5] Move rtas_stop_self() into platforms/pseries/hotplug-cpu.c Michael Ellerman
2006-12-05 6:52 ` [PATCH 2/5] Move pSeries_mach_cpu_die() " Michael Ellerman
2006-12-05 6:52 ` [PATCH 4/5] Only enable cpu hotplug via RTAS if the required firmware support is found Michael Ellerman
2006-12-05 6:52 ` [PATCH 3/5] Move the rest of the hotplug cpu code into platforms/pseries/hotplug-cpu.c Michael Ellerman
2006-12-05 6:52 ` [PATCH 5/5] Cleanup pass over platforms/pseries/hotplug-cpu.c Michael Ellerman
2006-12-06 22:51 ` [PATCH 1/5] Move rtas_stop_self() into platforms/pseries/hotplug-cpu.c Linas Vepstas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).