[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |