diff options
author | Keir Fraser <keir@xen.org> | 2012-03-23 14:01:05 +0000 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2012-03-23 14:01:05 +0000 |
commit | b1a874d21701a48d9f8619578320f2311538dc31 (patch) | |
tree | 0403f3f3f0f79b1c03262c0906035089ab81d0aa | |
parent | 739fe96a37ec9007e660e24585788ac547c2e77b (diff) | |
download | xen-b1a874d21701a48d9f8619578320f2311538dc31.tar.gz xen-b1a874d21701a48d9f8619578320f2311538dc31.tar.bz2 xen-b1a874d21701a48d9f8619578320f2311538dc31.zip |
Introduce system_state variable.
Use it to replace x86-specific early_boot boolean variable.
Also use it to detect suspend/resume case during cpu offline/online
to avoid unnecessarily breaking vcpu and cpupool affinities.
Signed-off-by: Keir Fraser <keir@xen.org>
Acked-by: Juergen Gross <juergen.gross@ts.fujitsu.com>
xen-unstable changeset: 25079:d5ccb2d1dbd1
xen-unstable date: Thu Mar 22 12:20:13 2012 +0000
Backport requested by Juergen to fix crash on poweroff when using
cpupools.
-rw-r--r-- | xen/arch/x86/acpi/power.c | 10 | ||||
-rw-r--r-- | xen/arch/x86/mm.c | 2 | ||||
-rw-r--r-- | xen/arch/x86/setup.c | 8 | ||||
-rw-r--r-- | xen/arch/x86/x86_32/mm.c | 2 | ||||
-rw-r--r-- | xen/arch/x86/x86_64/mm.c | 2 | ||||
-rw-r--r-- | xen/common/cpupool.c | 5 | ||||
-rw-r--r-- | xen/common/kernel.c | 2 | ||||
-rw-r--r-- | xen/common/schedule.c | 2 | ||||
-rw-r--r-- | xen/include/asm-x86/setup.h | 1 | ||||
-rw-r--r-- | xen/include/xen/kernel.h | 8 |
10 files changed, 33 insertions, 9 deletions
diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c index 935c9a1101..53b5e17c44 100644 --- a/xen/arch/x86/acpi/power.c +++ b/xen/arch/x86/acpi/power.c @@ -135,6 +135,9 @@ static int enter_state(u32 state) if ( !spin_trylock(&pm_lock) ) return -EBUSY; + BUG_ON(system_state != SYS_STATE_active); + system_state = SYS_STATE_suspend; + printk(XENLOG_INFO "Preparing system for ACPI S%d state.\n", state); freeze_domains(); @@ -142,7 +145,10 @@ static int enter_state(u32 state) acpi_dmar_reinstate(); if ( (error = disable_nonboot_cpus()) ) + { + system_state = SYS_STATE_resume; goto enable_cpu; + } cpufreq_del_cpu(0); @@ -159,6 +165,7 @@ static int enter_state(u32 state) if ( (error = device_power_down()) ) { printk(XENLOG_ERR "Some devices failed to power down."); + system_state = SYS_STATE_resume; goto done; } @@ -179,6 +186,8 @@ static int enter_state(u32 state) break; } + system_state = SYS_STATE_resume; + /* Restore CR4 and EFER from cached values. */ cr4 = read_cr4(); write_cr4(cr4 & ~X86_CR4_MCE); @@ -212,6 +221,7 @@ static int enter_state(u32 state) mtrr_aps_sync_end(); acpi_dmar_zap(); thaw_domains(); + system_state = SYS_STATE_active; spin_unlock(&pm_lock); return error; } diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index fd37a6aa7e..cbdf065909 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -5123,7 +5123,7 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned long addr, void free_xen_pagetable(void *v) { - if ( early_boot ) + if ( system_state == SYS_STATE_early_boot ) return; if ( is_xen_heap_page(virt_to_page(v)) ) diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 1777ffec51..d88884e4cb 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -87,8 +87,6 @@ boolean_param("noapic", skip_ioapic_setup); s8 __read_mostly xen_cpuidle = -1; boolean_param("cpuidle", xen_cpuidle); -bool_t __read_mostly early_boot = 1; - cpumask_t __read_mostly cpu_present_map; unsigned long __read_mostly xen_phys_start; @@ -275,7 +273,7 @@ static void *__init bootstrap_map(const module_t *mod) void *ret; #ifdef __x86_64__ - if ( !early_boot ) + if ( system_state != SYS_STATE_early_boot ) return mod ? mfn_to_virt(mod->mod_start) : NULL; #endif @@ -1142,7 +1140,7 @@ void __init __start_xen(unsigned long mbi_p) #endif end_boot_allocator(); - early_boot = 0; + system_state = SYS_STATE_boot; #if defined(CONFIG_X86_64) vesa_init(); @@ -1341,6 +1339,8 @@ void __init __start_xen(unsigned long mbi_p) /* Hide UART from DOM0 if we're using it */ serial_endboot(); + system_state = SYS_STATE_active; + domain_unpause_by_systemcontroller(dom0); reset_stack_and_jump(init_done); diff --git a/xen/arch/x86/x86_32/mm.c b/xen/arch/x86/x86_32/mm.c index 73a2a9bcbc..16ae743462 100644 --- a/xen/arch/x86/x86_32/mm.c +++ b/xen/arch/x86/x86_32/mm.c @@ -45,7 +45,7 @@ void *alloc_xen_pagetable(void) { unsigned long mfn; - if ( !early_boot ) + if ( system_state != SYS_STATE_early_boot ) { void *v = alloc_xenheap_page(); diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index 46c55080bc..72cbca4cfd 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -81,7 +81,7 @@ void *alloc_xen_pagetable(void) { unsigned long mfn; - if ( !early_boot ) + if ( system_state != SYS_STATE_early_boot ) { struct page_info *pg = alloc_domheap_page(NULL, 0); diff --git a/xen/common/cpupool.c b/xen/common/cpupool.c index c705475538..cafb4be792 100644 --- a/xen/common/cpupool.c +++ b/xen/common/cpupool.c @@ -616,6 +616,10 @@ static int cpu_callback( unsigned int cpu = (unsigned long)hcpu; int rc = 0; + if ( (system_state == SYS_STATE_suspend) || + (system_state == SYS_STATE_resume) ) + goto out; + switch ( action ) { case CPU_DOWN_FAILED: @@ -629,6 +633,7 @@ static int cpu_callback( break; } +out: return !rc ? NOTIFY_DONE : notifier_from_errno(rc); } diff --git a/xen/common/kernel.c b/xen/common/kernel.c index c061a0d838..3ce1dcc7a9 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -22,6 +22,8 @@ #ifndef COMPAT +enum system_state system_state = SYS_STATE_early_boot; + int tainted; xen_commandline_t saved_cmdline; diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 907ea09a76..1ed1bbb4ad 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -546,7 +546,7 @@ int cpu_disable_scheduler(unsigned int cpu) bool_t affinity_broken; c = per_cpu(cpupool, cpu); - if ( c == NULL ) + if ( (c == NULL) || (system_state == SYS_STATE_suspend) ) return ret; for_each_domain ( d ) diff --git a/xen/include/asm-x86/setup.h b/xen/include/asm-x86/setup.h index 4d1ce7202f..58199476f8 100644 --- a/xen/include/asm-x86/setup.h +++ b/xen/include/asm-x86/setup.h @@ -3,7 +3,6 @@ #include <xen/multiboot.h> -extern bool_t early_boot; extern unsigned long xenheap_initial_phys_start; void init_done(void); diff --git a/xen/include/xen/kernel.h b/xen/include/xen/kernel.h index fd03f74c8b..8e12a52507 100644 --- a/xen/include/xen/kernel.h +++ b/xen/include/xen/kernel.h @@ -81,5 +81,13 @@ extern char _sinittext[], _einittext[]; (__p >= _sinittext) && (__p <= _einittext); \ }) +extern enum system_state { + SYS_STATE_early_boot, + SYS_STATE_boot, + SYS_STATE_active, + SYS_STATE_suspend, + SYS_STATE_resume +} system_state; + #endif /* _LINUX_KERNEL_H */ |