* Enable CONFIG_CPU_HOTPLUG
* Add #ifndef CONFIG_XEN as appropriate around portions that are not
needed for kexec - it is used to take down cpus on SMP systems
before kexecing.
* Port various xen-specific bits as neccessary
- This has mainly been done in the existing kexec-related files,
as kexex is currently the only user of this code. If a full
port of CPU_HOTPLUG was done then this code would either disapear
or be relocated elsewhere.
Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx>
Index: xen-unstable.hg/xen/arch/ia64/linux-xen/mca_asm.S
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/linux-xen/mca_asm.S 2007-08-08
17:39:30.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/linux-xen/mca_asm.S 2007-08-08
17:59:07.000000000 +0900
@@ -147,8 +147,8 @@
#ifndef XEN
.global ia64_sal_to_os_handoff_state
.global ia64_os_to_sal_handoff_state
- .global ia64_do_tlb_purge
#endif
+ .global ia64_do_tlb_purge
.text
.align 16
Index: xen-unstable.hg/xen/arch/ia64/xen/domain.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/xen/domain.c 2007-08-08
17:39:50.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/xen/domain.c 2007-08-08 17:59:07.000000000
+0900
@@ -50,7 +50,10 @@
#include <xen/guest_access.h>
#include <asm/tlb_track.h>
#include <asm/perfmon.h>
+#include <asm/sal.h>
#include <public/vcpu.h>
+#include <linux/cpu.h>
+#include <linux/notifier.h>
static unsigned long __initdata dom0_size = 512*1024*1024;
@@ -335,8 +338,12 @@ static void default_idle(void)
local_irq_enable();
}
+extern void play_dead(void);
+
static void continue_cpu_idle_loop(void)
{
+ int cpu = smp_processor_id();
+
for ( ; ; )
{
#ifdef IA64
@@ -345,10 +352,12 @@ static void continue_cpu_idle_loop(void)
irq_stat[cpu].idle_timestamp = jiffies;
#endif
page_scrub_schedule_work();
- while ( !softirq_pending(smp_processor_id()) )
+ while ( !softirq_pending(cpu) )
default_idle();
raise_softirq(SCHEDULE_SOFTIRQ);
do_softirq();
+ if (!cpu_online(cpu))
+ play_dead();
}
}
Index: xen-unstable.hg/xen/arch/ia64/xen/machine_kexec.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/xen/machine_kexec.c 2007-08-08
17:51:34.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/xen/machine_kexec.c 2007-08-08
17:59:07.000000000 +0900
@@ -18,6 +18,9 @@
#include <asm/meminit.h>
#include <asm/hw_irq.h>
#include <asm/kexec.h>
+#include <linux/cpu.h>
+#include <linux/cpu.h>
+#include <linux/notifier.h>
typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)(
unsigned long indirection_page,
@@ -87,9 +90,68 @@ static void ia64_machine_kexec(struct un
BUG();
}
-void machine_kexec(xen_kexec_image_t *image)
+#if CONFIG_SMP
+/* Need to implement some subset of hotplug-cpu - enough to
+ * send a cpu into rendevouz */
+
+/* N.B: The tasks frozen parameter can probably be dropped
+ * This can probably be rolled into cpu_down
+ */
+static int _cpu_down(unsigned int cpu, int tasks_frozen)
+{
+ cpumask_t old_affinity, tmp;
+
+ if (num_online_cpus() == 1)
+ return -EBUSY;
+
+ if (!cpu_online(cpu))
+ return -EINVAL;
+
+ /* Ensure that we are not runnable on dying cpu */
+ /* This is current->cpus_allowed on Linux,
+ * which may well work completely differently */
+ old_affinity = current->cpu_affinity;
+ tmp = (cpumask_t)CPU_MASK_ALL;
+ cpu_clear(cpu, tmp);
+
+ cpu_clear(cpu, cpu_online_map);
+
+ __cpu_die(cpu);
+
+ return 0;
+}
+
+static int cpu_down(unsigned int cpu)
+{
+ int err;
+
+ /* Unlike Linux there is no lock, as there are no other callers
+ * and no other CPUS. */
+ err = _cpu_down(cpu, 0);
+
+ return 0;
+}
+#endif /* SMP */
+
+/* This should probably be an arch-hook called from kexec_exec()
+ * Its also likely that it should be in the xen equivalent of
+ * arch/ia64/kernel/process.c */
+static void machine_shutdown(void)
{
+#ifdef CONFIG_SMP
+ unsigned int cpu;
+
+ for_each_online_cpu(cpu) {
+ if (cpu != smp_processor_id())
+ cpu_down(cpu);
+ }
+#endif
kexec_disable_iosapic();
+}
+
+void machine_kexec(xen_kexec_image_t *image)
+{
+ machine_shutdown();
unw_init_running(ia64_machine_kexec, image);
for(;;);
}
Index: xen-unstable.hg/xen/include/asm-ia64/linux-null/linux/cpu.h
===================================================================
--- xen-unstable.hg.orig/xen/include/asm-ia64/linux-null/linux/cpu.h
2007-08-08 17:39:30.000000000 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1 +0,0 @@
-/* This file is intentionally left empty. */
Index: xen-unstable.hg/xen/include/asm-ia64/linux-xen/linux/cpu.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ xen-unstable.hg/xen/include/asm-ia64/linux-xen/linux/cpu.h 2007-08-08
17:59:07.000000000 +0900
@@ -0,0 +1,26 @@
+#ifndef _ASM_IA64_CPU_H_
+#define _ASM_IA64_CPU_H_
+
+#include <linux/device.h>
+#include <linux/cpu.h>
+#include <linux/topology.h>
+#include <linux/percpu.h>
+
+#ifndef XEN
+struct ia64_cpu {
+ struct cpu cpu;
+};
+
+DECLARE_PER_CPU(struct ia64_cpu, cpu_devices);
+#endif
+
+DECLARE_PER_CPU(int, cpu_state);
+
+#ifndef XEN
+extern int arch_register_cpu(int num);
+#ifdef CONFIG_HOTPLUG_CPU
+extern void arch_unregister_cpu(int);
+#endif
+#endif
+
+#endif /* _ASM_IA64_CPU_H_ */
Index: xen-unstable.hg/xen/include/asm-ia64/linux/asm/sal.h
===================================================================
--- xen-unstable.hg.orig/xen/include/asm-ia64/linux/asm/sal.h 2007-08-08
17:51:34.000000000 +0900
+++ xen-unstable.hg/xen/include/asm-ia64/linux/asm/sal.h 2007-08-08
17:59:07.000000000 +0900
@@ -856,7 +856,8 @@ extern int ia64_sal_oemcall_nolock(struc
u64, u64, u64, u64, u64);
extern int ia64_sal_oemcall_reentrant(struct ia64_sal_retval *, u64, u64, u64,
u64, u64, u64, u64, u64);
-#ifdef CONFIG_HOTPLUG_CPU
+
+#if CONFIG_HOTPLUG_CPU
/*
* System Abstraction Layer Specification
* Section 3.2.5.1: OS_BOOT_RENDEZ to SAL return State.
Index: xen-unstable.hg/xen/arch/ia64/linux-xen/smpboot.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/linux-xen/smpboot.c 2007-08-08
17:39:30.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/linux-xen/smpboot.c 2007-08-08
17:59:07.000000000 +0900
@@ -172,6 +172,24 @@ nointroute (char *str)
__setup("nointroute", nointroute);
+static void fix_b0_for_bsp(void)
+{
+#ifdef CONFIG_HOTPLUG_CPU
+ int cpuid;
+ static int fix_bsp_b0 = 1;
+
+ cpuid = smp_processor_id();
+
+ /*
+ * Cache the b0 value on the first AP that comes up
+ */
+ if (!(fix_bsp_b0 && cpuid))
+ return;
+
+ fix_bsp_b0 = 0;
+#endif
+}
+
void
sync_master (void *arg)
{
@@ -358,6 +376,8 @@ smp_callin (void)
BUG();
}
+ fix_b0_for_bsp();
+
lock_ipi_calllock();
cpu_set(cpuid, cpu_online_map);
unlock_ipi_calllock();
@@ -544,9 +564,11 @@ smp_build_cpu_map (void)
for (cpu = 0; cpu < NR_CPUS; cpu++) {
ia64_cpu_to_sapicid[cpu] = -1;
+#ifndef XEN
#ifdef CONFIG_HOTPLUG_CPU
cpu_set(cpu, cpu_possible_map);
#endif
+#endif
}
ia64_cpu_to_sapicid[0] = boot_cpu_id;
@@ -626,7 +648,7 @@ static struct {
__u8 valid;
} mt_info[NR_CPUS] __devinitdata;
-#ifdef CONFIG_HOTPLUG_CPU
+#if defined(XEN) && ! defined(CONFIG_HOTPLUG_CPU)
static inline void
remove_from_mtinfo(int cpu)
{
@@ -690,12 +712,21 @@ int __cpu_disable(void)
remove_siblinginfo(cpu);
cpu_clear(cpu, cpu_online_map);
+#ifndef XEN
fixup_irqs();
+#endif
local_flush_tlb_all();
cpu_clear(cpu, cpu_callin_map);
return 0;
}
+#else /* !CONFIG_HOTPLUG_CPU */
+int __cpu_disable(void)
+{
+ return -ENOSYS;
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+#ifdef CONFIG_HOTPLUG_CPU
void __cpu_die(unsigned int cpu)
{
unsigned int i;
@@ -707,16 +738,17 @@ void __cpu_die(unsigned int cpu)
printk ("CPU %d is now offline\n", cpu);
return;
}
+#ifdef XEN
+ /* XXX: There must be a better way to sleep */
+ for (int j=0; j<1000000; j++)
+ cpu_relax();
+#else
msleep(100);
+#endif
}
printk(KERN_ERR "CPU %u didn't die...\n", cpu);
}
#else /* !CONFIG_HOTPLUG_CPU */
-int __cpu_disable(void)
-{
- return -ENOSYS;
-}
-
void __cpu_die(unsigned int cpu)
{
/* We said "no" in __cpu_disable */
Index: xen-unstable.hg/xen/arch/ia64/linux-xen/irq_ia64.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/linux-xen/irq_ia64.c 2007-08-08
17:39:30.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/linux-xen/irq_ia64.c 2007-08-08
17:59:07.000000000 +0900
@@ -180,6 +180,7 @@ ia64_handle_irq (ia64_vector vector, str
irq_exit();
}
+#ifndef XEN
#ifdef CONFIG_HOTPLUG_CPU
/*
* This function emulates a interrupt processing when a cpu is about to be
@@ -226,6 +227,7 @@ void ia64_process_pending_intr(void)
irq_exit();
}
#endif
+#endif
#ifdef CONFIG_SMP
Index: xen-unstable.hg/xen/arch/ia64/linux-xen/process-linux-xen.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/linux-xen/process-linux-xen.c
2007-08-08 17:39:30.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/linux-xen/process-linux-xen.c 2007-08-08
17:59:07.000000000 +0900
@@ -6,6 +6,8 @@
* 04/11/17 Ashok Raj <ashok.raj@xxxxxxxxx> Added CPU Hotplug Support
*/
#ifdef XEN
+#include <linux/cpu.h>
+#include <linux/notifier.h>
#include <xen/types.h>
#include <xen/lib.h>
#include <xen/symbols.h>
@@ -15,6 +17,7 @@
#include <asm/processor.h>
#include <asm/ptrace.h>
#include <asm/unwind.h>
+#include <asm/sal.h>
#else
#define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */
#include <linux/config.h>
@@ -236,10 +239,15 @@ default_idle (void)
else
cpu_relax();
}
+#endif
#ifdef CONFIG_HOTPLUG_CPU
/* We don't actually take CPU down, just spin without interrupts. */
+#ifndef XEN
static inline void play_dead(void)
+#else
+void play_dead(void)
+#endif
{
extern void ia64_cpu_local_tick (void);
unsigned int this_cpu = smp_processor_id();
@@ -249,7 +257,6 @@ static inline void play_dead(void)
max_xtp();
local_irq_disable();
- idle_domain_exit();
ia64_jump_to_sal(&sal_boot_rendez_state[this_cpu]);
/*
* The above is a point of no-return, the processor is
@@ -258,12 +265,17 @@ static inline void play_dead(void)
BUG();
}
#else
+#ifndef XEN
static inline void play_dead(void)
+#else
+void play_dead(void)
+#endif
{
BUG();
}
#endif /* CONFIG_HOTPLUG_CPU */
+#ifndef XEN
void cpu_idle_wait(void)
{
unsigned int cpu, this_cpu = get_cpu();
Index: xen-unstable.hg/xen/arch/ia64/linux-xen/sal.c
===================================================================
--- xen-unstable.hg.orig/xen/arch/ia64/linux-xen/sal.c 2007-08-08
17:51:34.000000000 +0900
+++ xen-unstable.hg/xen/arch/ia64/linux-xen/sal.c 2007-08-08
17:59:07.000000000 +0900
@@ -129,7 +129,7 @@ sal_desc_entry_point (void *p)
static void __init
set_smp_redirect (int flag)
{
-#ifndef CONFIG_HOTPLUG_CPU
+#if defined(CONFIG_HOTPLUG_CPU) && ! defined(XEN)
if (no_int_routing)
smp_int_redirect &= ~flag;
else
Index: xen-unstable.hg/xen/include/asm-ia64/config.h
===================================================================
--- xen-unstable.hg.orig/xen/include/asm-ia64/config.h 2007-08-08
17:39:30.000000000 +0900
+++ xen-unstable.hg/xen/include/asm-ia64/config.h 2007-08-08
17:59:07.000000000 +0900
@@ -24,6 +24,7 @@
#ifdef CONFIG_XEN_SMP
#define CONFIG_SMP 1
+#define CONFIG_HOTPLUG_CPU 1
#define NR_CPUS 64
#define CONFIG_NUMA
#define CONFIG_ACPI_NUMA
--
--
Horms
H: http://www.vergenet.net/~horms/
W: http://www.valinux.co.jp/en/
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel
|