[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-ia64-devel] [patch 05/14] 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> 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |