[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Move cpu hotplug routines into common cpu.c file.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1273853272 -3600 # Node ID ba2cbbea9a6972d2da9d1e94b66306ab7266c89d # Parent df955a89b53c0bb4614476eb655538393e48c2a0 Move cpu hotplug routines into common cpu.c file. Also simplify the locking (reverting to use if spin_trylock, as returning EBUSY/EAGAIN seems unavoidable after all). In particular this should continue to ensure that stop_machine_run() does not have cpu_online_map change under its feet. Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/ia64/xen/xensetup.c | 1 xen/arch/x86/acpi/power.c | 9 - xen/arch/x86/platform_hypercall.c | 8 - xen/arch/x86/setup.c | 1 xen/arch/x86/smpboot.c | 234 +++----------------------------------- xen/arch/x86/sysctl.c | 1 xen/common/cpu.c | 205 +++++++++++++++++++++++++++++---- xen/common/spinlock.c | 13 +- xen/common/stop_machine.c | 20 ++- xen/include/asm-x86/smp.h | 4 xen/include/xen/cpu.h | 21 ++- xen/include/xen/spinlock.h | 2 12 files changed, 261 insertions(+), 258 deletions(-) diff -r df955a89b53c -r ba2cbbea9a69 xen/arch/ia64/xen/xensetup.c --- a/xen/arch/ia64/xen/xensetup.c Fri May 14 15:22:48 2010 +0100 +++ b/xen/arch/ia64/xen/xensetup.c Fri May 14 17:07:52 2010 +0100 @@ -32,6 +32,7 @@ #include <xsm/acm/acm_hooks.h> #include <asm/sn/simulator.h> #include <asm/sal.h> +#include <xen/cpu.h> unsigned long total_pages; diff -r df955a89b53c -r ba2cbbea9a69 xen/arch/x86/acpi/power.c --- a/xen/arch/x86/acpi/power.c Fri May 14 15:22:48 2010 +0100 +++ b/xen/arch/x86/acpi/power.c Fri May 14 17:07:52 2010 +0100 @@ -25,6 +25,7 @@ #include <xen/domain.h> #include <xen/console.h> #include <xen/iommu.h> +#include <xen/cpu.h> #include <public/platform.h> #include <asm/tboot.h> @@ -138,12 +139,8 @@ static int enter_state(u32 state) freeze_domains(); - disable_nonboot_cpus(); - if ( num_online_cpus() != 1 ) - { - error = -EBUSY; + if ( (error = disable_nonboot_cpus()) ) goto enable_cpu; - } cpufreq_del_cpu(0); @@ -207,7 +204,9 @@ static int enter_state(u32 state) enable_cpu: cpufreq_add_cpu(0); microcode_resume_cpu(0); + mtrr_aps_sync_begin(); enable_nonboot_cpus(); + mtrr_aps_sync_end(); thaw_domains(); spin_unlock(&pm_lock); return error; diff -r df955a89b53c -r ba2cbbea9a69 xen/arch/x86/platform_hypercall.c --- a/xen/arch/x86/platform_hypercall.c Fri May 14 15:22:48 2010 +0100 +++ b/xen/arch/x86/platform_hypercall.c Fri May 14 17:07:52 2010 +0100 @@ -410,7 +410,11 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe g_info = &op->u.pcpu_info; - spin_lock(&cpu_add_remove_lock); + if ( !get_cpu_maps() ) + { + ret = -EBUSY; + break; + } if ( (g_info->xen_cpuid >= NR_CPUS) || (g_info->xen_cpuid < 0) || @@ -429,7 +433,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe g_info->max_present = last_cpu(cpu_present_map); - spin_unlock(&cpu_add_remove_lock); + put_cpu_maps(); ret = copy_to_guest(u_xenpf_op, op, 1) ? -EFAULT : 0; } diff -r df955a89b53c -r ba2cbbea9a69 xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Fri May 14 15:22:48 2010 +0100 +++ b/xen/arch/x86/setup.c Fri May 14 17:07:52 2010 +0100 @@ -43,6 +43,7 @@ #include <asm/bzimage.h> /* for bzimage_headroom */ #include <asm/mach-generic/mach_apic.h> /* for generic_apic_probe */ #include <asm/setup.h> +#include <xen/cpu.h> #if defined(CONFIG_X86_64) #define BOOTSTRAP_DIRECTMAP_END (1UL << 32) /* 4GB */ diff -r df955a89b53c -r ba2cbbea9a69 xen/arch/x86/smpboot.c --- a/xen/arch/x86/smpboot.c Fri May 14 15:22:48 2010 +0100 +++ b/xen/arch/x86/smpboot.c Fri May 14 17:07:52 2010 +0100 @@ -46,7 +46,6 @@ #include <xen/tasklet.h> #include <xen/serial.h> #include <xen/numa.h> -#include <xen/event.h> #include <xen/cpu.h> #include <asm/current.h> #include <asm/mc146818rtc.h> @@ -58,7 +57,6 @@ #include <mach_apic.h> #include <mach_wakecpu.h> #include <smpboot_hooks.h> -#include <xen/stop_machine.h> #include <acpi/cpufreq/processor_perf.h> #define setup_trampoline() (bootsym_phys(trampoline_realmode_entry)) @@ -1310,169 +1308,9 @@ void __cpu_die(unsigned int cpu) } } -static int take_cpu_down(void *unused) -{ - void *hcpu = (void *)(long)smp_processor_id(); - int rc; - - spin_lock(&cpu_add_remove_lock); - - if (cpu_notifier_call_chain(CPU_DYING, hcpu) != NOTIFY_DONE) - BUG(); - - rc = __cpu_disable(); - - spin_unlock(&cpu_add_remove_lock); - - return rc; -} - -/* - * Protects against concurrent offline/online requests for a single CPU. - * We need this extra protection because cpu_down() cannot continuously hold - * the cpu_add_remove_lock, as it cannot be held across stop_machine_run(). - */ -static cpumask_t cpu_offlining; - -int cpu_down(unsigned int cpu) -{ - int err, notifier_rc, nr_calls; - void *hcpu = (void *)(long)cpu; - - spin_lock(&cpu_add_remove_lock); - - if ((cpu == 0) || !cpu_online(cpu) || cpu_isset(cpu, cpu_offlining)) { - spin_unlock(&cpu_add_remove_lock); - return -EINVAL; - } - - cpu_set(cpu, cpu_offlining); - - printk("Prepare to bring CPU%d down...\n", cpu); - - notifier_rc = __cpu_notifier_call_chain( - CPU_DOWN_PREPARE, hcpu, -1, &nr_calls); - if (notifier_rc != NOTIFY_DONE) { - err = notifier_to_errno(notifier_rc); - nr_calls--; - notifier_rc = __cpu_notifier_call_chain( - CPU_DOWN_FAILED, hcpu, nr_calls, NULL); - BUG_ON(notifier_rc != NOTIFY_DONE); - goto out; - } - - spin_unlock(&cpu_add_remove_lock); - err = stop_machine_run(take_cpu_down, NULL, cpu); - spin_lock(&cpu_add_remove_lock); - - if (err < 0) { - notifier_rc = cpu_notifier_call_chain(CPU_DOWN_FAILED, hcpu); - BUG_ON(notifier_rc != NOTIFY_DONE); - goto out; - } - - __cpu_die(cpu); - BUG_ON(cpu_online(cpu)); - - notifier_rc = cpu_notifier_call_chain(CPU_DEAD, hcpu); - BUG_ON(notifier_rc != NOTIFY_DONE); - -out: - if (!err) { - printk("CPU %u is now offline\n", cpu); - send_guest_global_virq(dom0, VIRQ_PCPU_STATE); - } else { - printk("Failed to take down CPU %u (error %d)\n", cpu, err); - } - cpu_clear(cpu, cpu_offlining); - spin_unlock(&cpu_add_remove_lock); - return err; -} - -int cpu_up(unsigned int cpu) -{ - int err = 0; - - spin_lock(&cpu_add_remove_lock); - - if (cpu_online(cpu) || cpu_isset(cpu, cpu_offlining)) { - err = -EINVAL; - goto out; - } - - err = __cpu_up(cpu); - if (err < 0) - goto out; - -out: - if (!err) - send_guest_global_virq(dom0, VIRQ_PCPU_STATE); - spin_unlock(&cpu_add_remove_lock); - return err; -} - -/* From kernel/power/main.c */ -/* This is protected by pm_sem semaphore */ -static cpumask_t frozen_cpus; - -void disable_nonboot_cpus(void) -{ - int cpu, error; - - error = 0; - cpus_clear(frozen_cpus); - printk("Freezing cpus ...\n"); - for_each_online_cpu(cpu) { - if (cpu == 0) - continue; - error = cpu_down(cpu); - /* No need to check EBUSY here */ - ASSERT(error != -EBUSY); - if (!error) { - cpu_set(cpu, frozen_cpus); - printk("CPU%d is down\n", cpu); - continue; - } - printk("Error taking cpu %d down: %d\n", cpu, error); - } - BUG_ON(raw_smp_processor_id() != 0); - if (error) - panic("cpus not sleeping"); -} - -void enable_nonboot_cpus(void) -{ - int cpu, error; - - printk("Thawing cpus ...\n"); - mtrr_aps_sync_begin(); - for_each_cpu_mask(cpu, frozen_cpus) { - error = cpu_up(cpu); - /* No conflict will happen here */ - ASSERT(error != -EBUSY); - if (!error) { - printk("CPU%d is up\n", cpu); - continue; - } - printk("Error taking cpu %d up: %d\n", cpu, error); - panic("Not enough cpus"); - } - mtrr_aps_sync_end(); - cpus_clear(frozen_cpus); - - /* - * Cleanup possible dangling ends after sleep... - */ - smpboot_restore_warm_reset_vector(); -} - int cpu_add(uint32_t apic_id, uint32_t acpi_id, uint32_t pxm) { - int cpu = -1; - -#ifndef CONFIG_ACPI - return -ENOSYS; -#endif + int node, cpu = -1; dprintk(XENLOG_DEBUG, "cpu_add apic_id %x acpi_id %x pxm %x\n", apic_id, acpi_id, pxm); @@ -1480,68 +1318,53 @@ int cpu_add(uint32_t apic_id, uint32_t a if ( acpi_id > MAX_MADT_ENTRIES || apic_id > MAX_APICS || pxm > 256 ) return -EINVAL; + if ( !cpu_hotplug_begin() ) + return -EBUSY; + /* Detect if the cpu has been added before */ - if ( x86_acpiid_to_apicid[acpi_id] != 0xff) + if ( x86_acpiid_to_apicid[acpi_id] != 0xff ) { - if (x86_acpiid_to_apicid[acpi_id] != apic_id) - return -EINVAL; - else - return -EEXIST; + cpu = (x86_acpiid_to_apicid[acpi_id] != apic_id) + ? -EINVAL : -EEXIST; + goto out; } if ( physid_isset(apic_id, phys_cpu_present_map) ) - return -EEXIST; - - spin_lock(&cpu_add_remove_lock); - - cpu = mp_register_lapic(apic_id, 1); - - if (cpu < 0) { - spin_unlock(&cpu_add_remove_lock); - return cpu; - } + cpu = -EEXIST; + goto out; + } + + if ( (cpu = mp_register_lapic(apic_id, 1)) < 0 ) + goto out; x86_acpiid_to_apicid[acpi_id] = apic_id; if ( !srat_disabled() ) { - int node; - - node = setup_node(pxm); - if (node < 0) + if ( (node = setup_node(pxm)) < 0 ) { dprintk(XENLOG_WARNING, "Setup node failed for pxm %x\n", pxm); x86_acpiid_to_apicid[acpi_id] = 0xff; mp_unregister_lapic(apic_id, cpu); - spin_unlock(&cpu_add_remove_lock); - return node; + cpu = node; + goto out; } apicid_to_node[apic_id] = node; } srat_detect_node(cpu); numa_add_cpu(cpu); - spin_unlock(&cpu_add_remove_lock); dprintk(XENLOG_INFO, "Add CPU %x with index %x\n", apic_id, cpu); + out: + cpu_hotplug_done(); return cpu; } int __devinit __cpu_up(unsigned int cpu) { - int notifier_rc, ret = 0, nr_calls; - void *hcpu = (void *)(long)cpu; - - notifier_rc = __cpu_notifier_call_chain( - CPU_UP_PREPARE, hcpu, -1, &nr_calls); - if (notifier_rc != NOTIFY_DONE) { - ret = notifier_to_errno(notifier_rc); - nr_calls--; - goto fail; - } - /* * We do warm boot only on cpus that had booted earlier * Otherwise cold boot is all handled from smp_boot_cpus(). @@ -1549,20 +1372,15 @@ int __devinit __cpu_up(unsigned int cpu) * when a cpu is taken offline from cpu_exit_clear(). */ if (!cpu_isset(cpu, cpu_callin_map)) { - ret = __smp_prepare_cpu(cpu); + if (__smp_prepare_cpu(cpu)) + return -EIO; smpboot_restore_warm_reset_vector(); - } - - if (ret) { - ret = -EIO; - goto fail; } /* In case one didn't come up */ if (!cpu_isset(cpu, cpu_callin_map)) { printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu); - ret = -EIO; - goto fail; + return -EIO; } /* Unleash the CPU! */ @@ -1572,15 +1390,7 @@ int __devinit __cpu_up(unsigned int cpu) process_pending_softirqs(); } - notifier_rc = cpu_notifier_call_chain(CPU_ONLINE, hcpu); - BUG_ON(notifier_rc != NOTIFY_DONE); return 0; - - fail: - notifier_rc = __cpu_notifier_call_chain( - CPU_UP_CANCELED, hcpu, nr_calls, NULL); - BUG_ON(notifier_rc != NOTIFY_DONE); - return ret; } diff -r df955a89b53c -r ba2cbbea9a69 xen/arch/x86/sysctl.c --- a/xen/arch/x86/sysctl.c Fri May 14 15:22:48 2010 +0100 +++ b/xen/arch/x86/sysctl.c Fri May 14 17:07:52 2010 +0100 @@ -25,6 +25,7 @@ #include <asm/processor.h> #include <asm/numa.h> #include <xen/nodemask.h> +#include <xen/cpu.h> #include <xsm/xsm.h> #define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0) diff -r df955a89b53c -r ba2cbbea9a69 xen/common/cpu.c --- a/xen/common/cpu.c Fri May 14 15:22:48 2010 +0100 +++ b/xen/common/cpu.c Fri May 14 17:07:52 2010 +0100 @@ -1,6 +1,9 @@ #include <xen/config.h> #include <xen/cpumask.h> #include <xen/cpu.h> +#include <xen/event.h> +#include <xen/sched.h> +#include <xen/stop_machine.h> /* * cpu_bit_bitmap[] is a special, "compressed" data structure that @@ -26,35 +29,195 @@ const unsigned long cpu_bit_bitmap[BITS_ #endif }; -DEFINE_SPINLOCK(cpu_add_remove_lock); +static DEFINE_SPINLOCK(cpu_add_remove_lock); + +bool_t get_cpu_maps(void) +{ + return spin_trylock_recursive(&cpu_add_remove_lock); +} + +void put_cpu_maps(void) +{ + spin_unlock_recursive(&cpu_add_remove_lock); +} + +bool_t cpu_hotplug_begin(void) +{ + return get_cpu_maps(); +} + +void cpu_hotplug_done(void) +{ + put_cpu_maps(); +} static RAW_NOTIFIER_HEAD(cpu_chain); int register_cpu_notifier(struct notifier_block *nb) { int ret; - spin_lock(&cpu_add_remove_lock); + if ( !spin_trylock(&cpu_add_remove_lock) ) + BUG(); /* Should never fail as we are called only during boot. */ ret = raw_notifier_chain_register(&cpu_chain, nb); spin_unlock(&cpu_add_remove_lock); return ret; } -void unregister_cpu_notifier(struct notifier_block *nb) -{ - spin_lock(&cpu_add_remove_lock); - raw_notifier_chain_unregister(&cpu_chain, nb); - spin_unlock(&cpu_add_remove_lock); -} - -int cpu_notifier_call_chain(unsigned long val, void *v) -{ - BUG_ON(!spin_is_locked(&cpu_add_remove_lock)); - return raw_notifier_call_chain(&cpu_chain, val, v); -} - -int __cpu_notifier_call_chain( - unsigned long val, void *v, int nr_to_call, int *nr_calls) -{ - BUG_ON(!spin_is_locked(&cpu_add_remove_lock)); - return __raw_notifier_call_chain(&cpu_chain, val, v, nr_to_call, nr_calls); -} +static int take_cpu_down(void *unused) +{ + void *hcpu = (void *)(long)smp_processor_id(); + if ( raw_notifier_call_chain(&cpu_chain, CPU_DYING, hcpu) != NOTIFY_DONE ) + BUG(); + return __cpu_disable(); +} + +int cpu_down(unsigned int cpu) +{ + int err, notifier_rc, nr_calls; + void *hcpu = (void *)(long)cpu; + + if ( !cpu_hotplug_begin() ) + return -EBUSY; + + if ( (cpu == 0) || !cpu_online(cpu) ) + { + cpu_hotplug_done(); + return -EINVAL; + } + + printk("Prepare to bring CPU%d down...\n", cpu); + + notifier_rc = __raw_notifier_call_chain( + &cpu_chain, CPU_DOWN_PREPARE, hcpu, -1, &nr_calls); + if ( notifier_rc != NOTIFY_DONE ) + { + err = notifier_to_errno(notifier_rc); + nr_calls--; + notifier_rc = __raw_notifier_call_chain( + &cpu_chain, CPU_DOWN_FAILED, hcpu, nr_calls, NULL); + BUG_ON(notifier_rc != NOTIFY_DONE); + goto out; + } + + if ( (err = stop_machine_run(take_cpu_down, NULL, cpu)) < 0 ) + { + notifier_rc = raw_notifier_call_chain( + &cpu_chain, CPU_DOWN_FAILED, hcpu); + BUG_ON(notifier_rc != NOTIFY_DONE); + goto out; + } + + __cpu_die(cpu); + BUG_ON(cpu_online(cpu)); + + notifier_rc = raw_notifier_call_chain(&cpu_chain, CPU_DEAD, hcpu); + BUG_ON(notifier_rc != NOTIFY_DONE); + + out: + if ( !err ) + { + printk("CPU %u is now offline\n", cpu); + send_guest_global_virq(dom0, VIRQ_PCPU_STATE); + } + else + { + printk("Failed to take down CPU %u (error %d)\n", cpu, err); + } + cpu_hotplug_done(); + return err; +} + +int cpu_up(unsigned int cpu) +{ + int notifier_rc, nr_calls, err = 0; + void *hcpu = (void *)(long)cpu; + + if ( !cpu_hotplug_begin() ) + return -EBUSY; + + if ( cpu_online(cpu) || !cpu_present(cpu) ) + { + cpu_hotplug_done(); + return -EINVAL; + } + + notifier_rc = __raw_notifier_call_chain( + &cpu_chain, CPU_UP_PREPARE, hcpu, -1, &nr_calls); + if ( notifier_rc != NOTIFY_DONE ) + { + err = notifier_to_errno(notifier_rc); + nr_calls--; + goto fail; + } + + err = __cpu_up(cpu); + if ( err < 0 ) + goto fail; + + notifier_rc = raw_notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu); + BUG_ON(notifier_rc != NOTIFY_DONE); + + send_guest_global_virq(dom0, VIRQ_PCPU_STATE); + + cpu_hotplug_done(); + return 0; + + fail: + notifier_rc = __raw_notifier_call_chain( + &cpu_chain, CPU_UP_CANCELED, hcpu, nr_calls, NULL); + BUG_ON(notifier_rc != NOTIFY_DONE); + cpu_hotplug_done(); + return err; +} + +static cpumask_t frozen_cpus; + +int disable_nonboot_cpus(void) +{ + int cpu, error = 0; + + BUG_ON(raw_smp_processor_id() != 0); + + cpus_clear(frozen_cpus); + + printk("Disabling non-boot CPUs ...\n"); + + for_each_online_cpu ( cpu ) + { + if ( cpu == 0 ) + continue; + + if ( (error = cpu_down(cpu)) ) + { + BUG_ON(error == -EBUSY); + printk("Error taking CPU%d down: %d\n", cpu, error); + break; + } + + cpu_set(cpu, frozen_cpus); + printk("CPU%d is down\n", cpu); + } + + BUG_ON(!error && (num_online_cpus() != 1)); + return error; +} + +void enable_nonboot_cpus(void) +{ + int cpu, error; + + printk("Enabling non-boot CPUs ...\n"); + + for_each_cpu_mask ( cpu, frozen_cpus ) + { + if ( (error = cpu_up(cpu)) ) + { + BUG_ON(error == -EBUSY); + printk("Error taking CPU%d up: %d\n", cpu, error); + continue; + } + printk("CPU%d is up\n", cpu); + } + + cpus_clear(frozen_cpus); +} diff -r df955a89b53c -r ba2cbbea9a69 xen/common/spinlock.c --- a/xen/common/spinlock.c Fri May 14 15:22:48 2010 +0100 +++ b/xen/common/spinlock.c Fri May 14 17:07:52 2010 +0100 @@ -186,7 +186,7 @@ void _spin_barrier_irq(spinlock_t *lock) local_irq_restore(flags); } -void _spin_lock_recursive(spinlock_t *lock) +int _spin_trylock_recursive(spinlock_t *lock) { int cpu = smp_processor_id(); @@ -197,13 +197,22 @@ void _spin_lock_recursive(spinlock_t *lo if ( likely(lock->recurse_cpu != cpu) ) { - spin_lock(lock); + if ( !spin_trylock(lock) ) + return 0; lock->recurse_cpu = cpu; } /* We support only fairly shallow recursion, else the counter overflows. */ ASSERT(lock->recurse_cnt < 0xfu); lock->recurse_cnt++; + + return 1; +} + +void _spin_lock_recursive(spinlock_t *lock) +{ + while ( !spin_trylock_recursive(lock) ) + cpu_relax(); } void _spin_unlock_recursive(spinlock_t *lock) diff -r df955a89b53c -r ba2cbbea9a69 xen/common/stop_machine.c --- a/xen/common/stop_machine.c Fri May 14 15:22:48 2010 +0100 +++ b/xen/common/stop_machine.c Fri May 14 17:07:52 2010 +0100 @@ -28,6 +28,7 @@ #include <xen/stop_machine.h> #include <xen/errno.h> #include <xen/smp.h> +#include <xen/cpu.h> #include <asm/current.h> #include <asm/processor.h> @@ -72,19 +73,20 @@ int stop_machine_run(int (*fn)(void *), BUG_ON(!local_irq_is_enabled()); + /* cpu_online_map must not change. */ + if ( !get_cpu_maps() ) + return -EBUSY; + allbutself = cpu_online_map; cpu_clear(smp_processor_id(), allbutself); nr_cpus = cpus_weight(allbutself); - if ( nr_cpus == 0 ) - { - BUG_ON(cpu != smp_processor_id()); - return (*fn)(data); - } - /* Must not spin here as the holder will expect us to be descheduled. */ if ( !spin_trylock(&stopmachine_lock) ) + { + put_cpu_maps(); return -EBUSY; + } stopmachine_data.fn = fn; stopmachine_data.fn_data = data; @@ -113,12 +115,16 @@ int stop_machine_run(int (*fn)(void *), spin_unlock(&stopmachine_lock); + put_cpu_maps(); + return ret; } -static void stopmachine_action(unsigned long unused) +static void stopmachine_action(unsigned long cpu) { enum stopmachine_state state = STOPMACHINE_START; + + BUG_ON(cpu != smp_processor_id()); smp_mb(); diff -r df955a89b53c -r ba2cbbea9a69 xen/include/asm-x86/smp.h --- a/xen/include/asm-x86/smp.h Fri May 14 15:22:48 2010 +0100 +++ b/xen/include/asm-x86/smp.h Fri May 14 17:07:52 2010 +0100 @@ -56,12 +56,8 @@ DECLARE_PER_CPU(int, cpu_state); DECLARE_PER_CPU(int, cpu_state); #define cpu_is_offline(cpu) unlikely(!cpu_online(cpu)) -extern int cpu_down(unsigned int cpu); -extern int cpu_up(unsigned int cpu); extern void cpu_exit_clear(void); extern void cpu_uninit(void); -extern void disable_nonboot_cpus(void); -extern void enable_nonboot_cpus(void); int cpu_add(uint32_t apic_id, uint32_t acpi_id, uint32_t pxm); /* diff -r df955a89b53c -r ba2cbbea9a69 xen/include/xen/cpu.h --- a/xen/include/xen/cpu.h Fri May 14 15:22:48 2010 +0100 +++ b/xen/include/xen/cpu.h Fri May 14 17:07:52 2010 +0100 @@ -5,13 +5,16 @@ #include <xen/spinlock.h> #include <xen/notifier.h> -extern spinlock_t cpu_add_remove_lock; +/* Safely access cpu_online_map, cpu_present_map, etc. */ +bool_t get_cpu_maps(void); +void put_cpu_maps(void); +/* Safely perform CPU hotplug and update cpu_online_map, etc. */ +bool_t cpu_hotplug_begin(void); +void cpu_hotplug_done(void); + +/* Receive notification of CPU hotplug events. */ int register_cpu_notifier(struct notifier_block *nb); -void unregister_cpu_notifier(struct notifier_block *nb); -int cpu_notifier_call_chain(unsigned long val, void *v); -int __cpu_notifier_call_chain( - unsigned long val, void *v, int nr_to_call, int *nr_calls); /* * Notification actions: note that only CPU_{UP,DOWN}_PREPARE may fail --- @@ -25,4 +28,12 @@ int __cpu_notifier_call_chain( #define CPU_DYING 0x0007 /* CPU is nearly dead (in stop_machine ctxt) */ #define CPU_DEAD 0x0008 /* CPU is dead */ +/* Perform CPU hotplug. May return -EAGAIN. */ +int cpu_down(unsigned int cpu); +int cpu_up(unsigned int cpu); + +/* Power management. */ +int disable_nonboot_cpus(void); +void enable_nonboot_cpus(void); + #endif /* __XEN_CPU_H__ */ diff -r df955a89b53c -r ba2cbbea9a69 xen/include/xen/spinlock.h --- a/xen/include/xen/spinlock.h Fri May 14 15:22:48 2010 +0100 +++ b/xen/include/xen/spinlock.h Fri May 14 17:07:52 2010 +0100 @@ -146,6 +146,7 @@ void _spin_barrier(spinlock_t *lock); void _spin_barrier(spinlock_t *lock); void _spin_barrier_irq(spinlock_t *lock); +int _spin_trylock_recursive(spinlock_t *lock); void _spin_lock_recursive(spinlock_t *lock); void _spin_unlock_recursive(spinlock_t *lock); @@ -191,6 +192,7 @@ int _rw_is_write_locked(rwlock_t *lock); * are any critical regions that cannot form part of such a set, they can use * standard spin_[un]lock(). */ +#define spin_trylock_recursive(l) _spin_trylock_recursive(l) #define spin_lock_recursive(l) _spin_lock_recursive(l) #define spin_unlock_recursive(l) _spin_unlock_recursive(l) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |