WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-ia64-devel

[Xen-ia64-devel] [patch 05/14] Kexec: partial port of CPU_HOTPLUG

To: xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-ia64-devel] [patch 05/14] Kexec: partial port of CPU_HOTPLUG
From: Simon Horman <horms@xxxxxxxxxxxx>
Date: Wed, 12 Sep 2007 17:08:50 +0900
Delivery-date: Wed, 12 Sep 2007 01:43:10 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-ia64-devel-request@lists.xensource.com?subject=help>
List-id: Discussion of the ia64 port of Xen <xen-ia64-devel.lists.xensource.com>
List-post: <mailto:xen-ia64-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20070912080845.674923870@xxxxxxxxxxxx>
Sender: xen-ia64-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: quilt/0.46-1
* 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