[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [IA64] Kexec: partial port of CPU_HOTPLUG



# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1190928902 21600
# Node ID ec3f4e9e62f658a38cbd417226003886f81de0c7
# Parent  2b0cbf3ef83f7cd61d7b6e022a7071695b7d4cf9
[IA64] Kexec: partial port of CPU_HOTPLUG

* 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>
---
 xen/include/asm-ia64/linux-null/linux/cpu.h        |    1 
 xen/arch/ia64/linux-xen/irq_ia64.c                 |    2 
 xen/arch/ia64/linux-xen/mca_asm.S                  |    2 
 xen/arch/ia64/linux-xen/process-linux-xen.c        |   14 ++++
 xen/arch/ia64/linux-xen/sal.c                      |    2 
 xen/arch/ia64/linux-xen/smpboot.c                  |   49 +++++++++++++---
 xen/arch/ia64/xen/domain.c                         |   11 +++
 xen/arch/ia64/xen/machine_kexec.c                  |   64 ++++++++++++++++++++-
 xen/include/asm-ia64/config.h                      |    1 
 xen/include/asm-ia64/linux-xen/linux/README.origin |    1 
 xen/include/asm-ia64/linux-xen/linux/cpu.h         |   26 ++++++++
 11 files changed, 160 insertions(+), 13 deletions(-)

diff -r 2b0cbf3ef83f -r ec3f4e9e62f6 xen/arch/ia64/linux-xen/irq_ia64.c
--- a/xen/arch/ia64/linux-xen/irq_ia64.c        Thu Sep 27 15:12:58 2007 -0600
+++ b/xen/arch/ia64/linux-xen/irq_ia64.c        Thu Sep 27 15:35:02 2007 -0600
@@ -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
diff -r 2b0cbf3ef83f -r ec3f4e9e62f6 xen/arch/ia64/linux-xen/mca_asm.S
--- a/xen/arch/ia64/linux-xen/mca_asm.S Thu Sep 27 15:12:58 2007 -0600
+++ b/xen/arch/ia64/linux-xen/mca_asm.S Thu Sep 27 15:35:02 2007 -0600
@@ -147,8 +147,8 @@
 #ifndef XEN
        .global ia64_sal_to_os_handoff_state
        .global ia64_os_to_sal_handoff_state
+#endif
        .global ia64_do_tlb_purge
-#endif
 
        .text
        .align 16
diff -r 2b0cbf3ef83f -r ec3f4e9e62f6 xen/arch/ia64/linux-xen/process-linux-xen.c
--- a/xen/arch/ia64/linux-xen/process-linux-xen.c       Thu Sep 27 15:12:58 
2007 -0600
+++ b/xen/arch/ia64/linux-xen/process-linux-xen.c       Thu Sep 27 15:35:02 
2007 -0600
@@ -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();
diff -r 2b0cbf3ef83f -r ec3f4e9e62f6 xen/arch/ia64/linux-xen/sal.c
--- a/xen/arch/ia64/linux-xen/sal.c     Thu Sep 27 15:12:58 2007 -0600
+++ b/xen/arch/ia64/linux-xen/sal.c     Thu Sep 27 15:35:02 2007 -0600
@@ -129,7 +129,7 @@ static void __init
 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
diff -r 2b0cbf3ef83f -r ec3f4e9e62f6 xen/arch/ia64/linux-xen/smpboot.c
--- a/xen/arch/ia64/linux-xen/smpboot.c Thu Sep 27 15:12:58 2007 -0600
+++ b/xen/arch/ia64/linux-xen/smpboot.c Thu Sep 27 15:35:02 2007 -0600
@@ -172,6 +172,27 @@ 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;
+
+       sal_boot_rendez_state[0].br[0] = sal_boot_rendez_state[cpuid].br[0];
+       printk ("Fixed BSP b0 value from CPU %d\n", cpuid);
+
+       fix_bsp_b0 = 0;
+#endif
+}
+
 void
 sync_master (void *arg)
 {
@@ -358,6 +379,8 @@ smp_callin (void)
                BUG();
        }
 
+       fix_b0_for_bsp();
+
        lock_ipi_calllock();
        cpu_set(cpuid, cpu_online_map);
        unlock_ipi_calllock();
@@ -544,8 +567,10 @@ 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
        }
 
@@ -626,7 +651,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 +715,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 +741,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 */
diff -r 2b0cbf3ef83f -r ec3f4e9e62f6 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c        Thu Sep 27 15:12:58 2007 -0600
+++ b/xen/arch/ia64/xen/domain.c        Thu Sep 27 15:35:02 2007 -0600
@@ -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>
 
 /* dom0_size: default memory allocation for dom0 (~4GB) */
 static unsigned long __initdata dom0_size = 4096UL*1024UL*1024UL;
@@ -336,8 +339,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
@@ -346,10 +353,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();
        }
 }
 
diff -r 2b0cbf3ef83f -r ec3f4e9e62f6 xen/arch/ia64/xen/machine_kexec.c
--- a/xen/arch/ia64/xen/machine_kexec.c Thu Sep 27 15:12:58 2007 -0600
+++ b/xen/arch/ia64/xen/machine_kexec.c Thu Sep 27 15:35:02 2007 -0600
@@ -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,
@@ -83,9 +86,68 @@ static void ia64_machine_kexec(struct un
        BUG();
 }
 
+#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)
+{
+       if (num_online_cpus() == 1)
+               return -EBUSY;
+
+       if (!cpu_online(cpu))
+               return -EINVAL;
+
+#ifndef XEN
+       /* XXX: What, if anything, should Xen do here? */
+       /* Ensure that we are not runnable on dying cpu */
+       old_affinity = current->cpus_allowed;
+       tmp = CPU_MASK_ALL;
+       cpu_clear(cpu, tmp);
+       set_cpus_allowed(current, tmp);
+#endif
+
+       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)
 {
-       kexec_disable_iosapic();
+       machine_shutdown();
        unw_init_running(ia64_machine_kexec, image);
        for(;;);
 }
diff -r 2b0cbf3ef83f -r ec3f4e9e62f6 xen/include/asm-ia64/config.h
--- a/xen/include/asm-ia64/config.h     Thu Sep 27 15:12:58 2007 -0600
+++ b/xen/include/asm-ia64/config.h     Thu Sep 27 15:35:02 2007 -0600
@@ -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
diff -r 2b0cbf3ef83f -r ec3f4e9e62f6 xen/include/asm-ia64/linux-null/linux/cpu.h
--- a/xen/include/asm-ia64/linux-null/linux/cpu.h       Thu Sep 27 15:12:58 
2007 -0600
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-/* This file is intentionally left empty. */
diff -r 2b0cbf3ef83f -r ec3f4e9e62f6 
xen/include/asm-ia64/linux-xen/linux/README.origin
--- a/xen/include/asm-ia64/linux-xen/linux/README.origin        Thu Sep 27 
15:12:58 2007 -0600
+++ b/xen/include/asm-ia64/linux-xen/linux/README.origin        Thu Sep 27 
15:35:02 2007 -0600
@@ -18,4 +18,5 @@ device.h              -> linux/include/linux/device.
 device.h               -> linux/include/linux/device.h
 
 # The files below are from Linux-2.6.21
+cpu.h                  -> linux/include/linux/cpu.h
 efi.h                  -> linux/include/linux/efi.h
diff -r 2b0cbf3ef83f -r ec3f4e9e62f6 xen/include/asm-ia64/linux-xen/linux/cpu.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-ia64/linux-xen/linux/cpu.h        Thu Sep 27 15:35:02 
2007 -0600
@@ -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_ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.