* [PATCH] Allow ACPI state change with active cpupools
@ 2012-03-20 12:15 Juergen Gross
2012-03-20 12:52 ` Keir Fraser
0 siblings, 1 reply; 7+ messages in thread
From: Juergen Gross @ 2012-03-20 12:15 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: Type: text/plain, Size: 2069 bytes --]
Changing the ACPI state (e.g. power off) while not all cpus are in cpupool 0
will currently crash the hypervisor during disabling the other cpus.
This patch avoids the crash by adding the reason for disabling a cpu (either
permanent e.g. in case of cpu hotplug or temporary in case of ACPI state
change).
This requires an additional parameter for cpu callbacks. All callbacks are
changed to take a structure as parameter instead of only the cpu number.
Signed-off-by: Juergen Gross <juergen.gross@ts.fujitsu.com>
25 files changed, 185 insertions(+), 139 deletions(-)
xen/arch/x86/acpi/cpu_idle.c | 13 ++++---
xen/arch/x86/cpu/mcheck/mce.c | 8 ++--
xen/arch/x86/cpu/mcheck/mce_intel.c | 8 ++--
xen/arch/x86/hvm/hvm.c | 10 ++---
xen/arch/x86/microcode.c | 6 +--
xen/arch/x86/nmi.c | 17 +++++----
xen/arch/x86/percpu.c | 8 ++--
xen/arch/x86/setup.c | 2 -
xen/arch/x86/smpboot.c | 8 ++--
xen/arch/x86/sysctl.c | 8 ++--
xen/arch/x86/x86_32/traps.c | 8 ++--
xen/common/cpu.c | 46 ++++++++++++++++----------
xen/common/cpupool.c | 17 ++++++---
xen/common/kexec.c | 13 ++++---
xen/common/rcupdate.c | 15 +++++---
xen/common/sched_credit2.c | 6 +--
xen/common/schedule.c | 8 ++--
xen/common/stop_machine.c | 17 +++++----
xen/common/tasklet.c | 19 ++++++----
xen/common/timer.c | 15 +++++---
xen/common/tmem_xen.c | 32 +++++++++---------
xen/common/trace.c | 6 +--
xen/drivers/cpufreq/cpufreq.c | 15 +++++---
xen/drivers/cpufreq/cpufreq_misc_governors.c | 6 +--
xen/include/xen/cpu.h | 13 ++++++-
[-- Attachment #2: xen-staging.hg.patch --]
[-- Type: text/x-patch, Size: 33075 bytes --]
# HG changeset patch
# User Juergen Gross <juergen.gross@ts.fujitsu.com>
# Date 1332245707 -3600
# Node ID 6ca47f4a35ab18e72117970caca4612a07cb4d3b
# Parent 4e1d091d10d83130842170cd61f1194e5459f2aa
Allow ACPI state change with active cpupools
Changing the ACPI state (e.g. power off) while not all cpus are in cpupool 0
will currently crash the hypervisor during disabling the other cpus.
This patch avoids the crash by adding the reason for disabling a cpu (either
permanent e.g. in case of cpu hotplug or temporary in case of ACPI state
change).
This requires an additional parameter for cpu callbacks. All callbacks are
changed to take a structure as parameter instead of only the cpu number.
Signed-off-by: Juergen Gross <juergen.gross@ts.fujitsu.com>
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/arch/x86/acpi/cpu_idle.c
--- a/xen/arch/x86/acpi/cpu_idle.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/arch/x86/acpi/cpu_idle.c Tue Mar 20 13:15:07 2012 +0100
@@ -1161,16 +1161,16 @@ bool_t cpuidle_using_deep_cstate(void)
}
static int cpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
+ struct cpu_notifier_data *hcpu = data;
/* Only hook on CPU_ONLINE because a dead cpu may utilize the info to
* to enter deep C-state */
switch ( action )
{
case CPU_ONLINE:
- (void)cpuidle_init_cpu(cpu);
+ (void)cpuidle_init_cpu(hcpu->cpu);
break;
default:
break;
@@ -1185,8 +1185,11 @@ static struct notifier_block cpu_nfb = {
static int __init cpuidle_presmp_init(void)
{
- void *cpu = (void *)(long)smp_processor_id();
- cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
+ struct cpu_notifier_data hcpu;
+
+ hcpu.cpu = smp_processor_id();
+ hcpu.reason = CPU_REASON_PERMANENT;
+ cpu_callback(&cpu_nfb, CPU_ONLINE, &hcpu);
register_cpu_notifier(&cpu_nfb);
return 0;
}
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/arch/x86/cpu/mcheck/mce.c
--- a/xen/arch/x86/cpu/mcheck/mce.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/arch/x86/cpu/mcheck/mce.c Tue Mar 20 13:15:07 2012 +0100
@@ -771,19 +771,19 @@ static int cpu_poll_bankmask_alloc(unsig
}
static int cpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
int rc = 0;
+ struct cpu_notifier_data *hcpu = data;
switch ( action )
{
case CPU_UP_PREPARE:
- rc = cpu_poll_bankmask_alloc(cpu);
+ rc = cpu_poll_bankmask_alloc(hcpu->cpu);
break;
case CPU_UP_CANCELED:
case CPU_DEAD:
- cpu_poll_bankmask_free(cpu);
+ cpu_poll_bankmask_free(hcpu->cpu);
break;
default:
break;
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/arch/x86/cpu/mcheck/mce_intel.c
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c Tue Mar 20 13:15:07 2012 +0100
@@ -1365,15 +1365,15 @@ out:
}
static int cpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
int rc = 0;
+ struct cpu_notifier_data *hcpu = data;
switch ( action )
{
case CPU_UP_PREPARE:
- rc = cpu_mcabank_alloc(cpu);
+ rc = cpu_mcabank_alloc(hcpu->cpu);
break;
case CPU_DYING:
cpu_mcheck_disable();
@@ -1381,7 +1381,7 @@ static int cpu_callback(
case CPU_UP_CANCELED:
case CPU_DEAD:
cpu_mcheck_distribute_cmci();
- cpu_mcabank_free(cpu);
+ cpu_mcabank_free(hcpu->cpu);
break;
default:
break;
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/arch/x86/hvm/hvm.c Tue Mar 20 13:15:07 2012 +0100
@@ -79,22 +79,22 @@ unsigned long __attribute__ ((__section_
hvm_io_bitmap[3*PAGE_SIZE/BYTES_PER_LONG];
static int cpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
-{
- unsigned int cpu = (unsigned long)hcpu;
+ struct notifier_block *nfb, unsigned long action, void *data)
+{
int rc = 0;
+ struct cpu_notifier_data *hcpu = data;
switch ( action )
{
case CPU_UP_PREPARE:
- rc = hvm_funcs.cpu_up_prepare(cpu);
+ rc = hvm_funcs.cpu_up_prepare(hcpu->cpu);
break;
case CPU_DYING:
hvm_cpu_down();
break;
case CPU_UP_CANCELED:
case CPU_DEAD:
- hvm_funcs.cpu_dead(cpu);
+ hvm_funcs.cpu_dead(hcpu->cpu);
break;
default:
break;
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/arch/x86/microcode.c
--- a/xen/arch/x86/microcode.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/arch/x86/microcode.c Tue Mar 20 13:15:07 2012 +0100
@@ -273,14 +273,14 @@ __initcall(microcode_init);
__initcall(microcode_init);
static int microcode_percpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
+ struct cpu_notifier_data *hcpu = data;
switch ( action )
{
case CPU_DEAD:
- microcode_fini_cpu(cpu);
+ microcode_fini_cpu(hcpu->cpu);
break;
}
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/arch/x86/nmi.c
--- a/xen/arch/x86/nmi.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/arch/x86/nmi.c Tue Mar 20 13:15:07 2012 +0100
@@ -375,19 +375,19 @@ void __pminit setup_apic_nmi_watchdog(vo
}
static int cpu_nmi_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
+ struct cpu_notifier_data *hcpu = data;
switch ( action )
{
case CPU_UP_PREPARE:
- init_timer(&per_cpu(nmi_timer, cpu), nmi_timer_fn, NULL, cpu);
- set_timer(&per_cpu(nmi_timer, cpu), NOW());
+ init_timer(&per_cpu(nmi_timer, hcpu->cpu), nmi_timer_fn, NULL, hcpu->cpu);
+ set_timer(&per_cpu(nmi_timer, hcpu->cpu), NOW());
break;
case CPU_UP_CANCELED:
case CPU_DEAD:
- kill_timer(&per_cpu(nmi_timer, cpu));
+ kill_timer(&per_cpu(nmi_timer, hcpu->cpu));
break;
default:
break;
@@ -417,14 +417,15 @@ void watchdog_enable(void)
void __init watchdog_setup(void)
{
- unsigned int cpu;
+ struct cpu_notifier_data hcpu;
/*
* Activate periodic heartbeats. We cannot do this earlier during
* setup because the timer infrastructure is not available.
*/
- for_each_online_cpu ( cpu )
- cpu_nmi_callback(&cpu_nmi_nfb, CPU_UP_PREPARE, (void *)(long)cpu);
+ hcpu.reason = CPU_REASON_PERMANENT;
+ for_each_online_cpu ( hcpu.cpu )
+ cpu_nmi_callback(&cpu_nmi_nfb, CPU_UP_PREPARE, &hcpu);
register_cpu_notifier(&cpu_nmi_nfb);
watchdog_enable();
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/arch/x86/percpu.c
--- a/xen/arch/x86/percpu.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/arch/x86/percpu.c Tue Mar 20 13:15:07 2012 +0100
@@ -51,19 +51,19 @@ static void free_percpu_area(unsigned in
}
static int cpu_percpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
int rc = 0;
+ struct cpu_notifier_data *hcpu = data;
switch ( action )
{
case CPU_UP_PREPARE:
- rc = init_percpu_area(cpu);
+ rc = init_percpu_area(hcpu->cpu);
break;
case CPU_UP_CANCELED:
case CPU_DEAD:
- free_percpu_area(cpu);
+ free_percpu_area(hcpu->cpu);
break;
default:
break;
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/arch/x86/setup.c Tue Mar 20 13:15:07 2012 +0100
@@ -1300,7 +1300,7 @@ void __init __start_xen(unsigned long mb
if ( (num_online_cpus() < max_cpus) && !cpu_online(i) )
{
- int ret = cpu_up(i);
+ int ret = cpu_up(i, CPU_REASON_PERMANENT);
if ( ret != 0 )
printk("Failed to bring up CPU %u (error %d)\n", i, ret);
}
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/arch/x86/smpboot.c Tue Mar 20 13:15:07 2012 +0100
@@ -720,19 +720,19 @@ static int cpu_smpboot_alloc(unsigned in
}
static int cpu_smpboot_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
int rc = 0;
+ struct cpu_notifier_data *hcpu = data;
switch ( action )
{
case CPU_UP_PREPARE:
- rc = cpu_smpboot_alloc(cpu);
+ rc = cpu_smpboot_alloc(hcpu->cpu);
break;
case CPU_UP_CANCELED:
case CPU_DEAD:
- cpu_smpboot_free(cpu);
+ cpu_smpboot_free(hcpu->cpu);
break;
default:
break;
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/arch/x86/sysctl.c
--- a/xen/arch/x86/sysctl.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/arch/x86/sysctl.c Tue Mar 20 13:15:07 2012 +0100
@@ -34,12 +34,12 @@ long cpu_up_helper(void *data)
long cpu_up_helper(void *data)
{
int cpu = (unsigned long)data;
- int ret = cpu_up(cpu);
+ int ret = cpu_up(cpu, CPU_REASON_PERMANENT);
if ( ret == -EBUSY )
{
/* On EBUSY, flush RCU work and have one more go. */
rcu_barrier();
- ret = cpu_up(cpu);
+ ret = cpu_up(cpu, CPU_REASON_PERMANENT);
}
return ret;
}
@@ -47,12 +47,12 @@ long cpu_down_helper(void *data)
long cpu_down_helper(void *data)
{
int cpu = (unsigned long)data;
- int ret = cpu_down(cpu);
+ int ret = cpu_down(cpu, CPU_REASON_PERMANENT);
if ( ret == -EBUSY )
{
/* On EBUSY, flush RCU work and have one more go. */
rcu_barrier();
- ret = cpu_down(cpu);
+ ret = cpu_down(cpu, CPU_REASON_PERMANENT);
}
return ret;
}
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/arch/x86/x86_32/traps.c Tue Mar 20 13:15:07 2012 +0100
@@ -201,16 +201,16 @@ static unsigned char __attribute__ ((__s
boot_cpu_doublefault_space[PAGE_SIZE];
static int cpu_doublefault_tss_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
void *p;
int rc = 0;
+ struct cpu_notifier_data *hcpu = data;
switch ( action )
{
case CPU_UP_PREPARE:
- per_cpu(doublefault_tss, cpu) = p = alloc_xenheap_page();
+ per_cpu(doublefault_tss, hcpu->cpu) = p = alloc_xenheap_page();
if ( p == NULL )
rc = -ENOMEM;
else
@@ -218,7 +218,7 @@ static int cpu_doublefault_tss_callback(
break;
case CPU_UP_CANCELED:
case CPU_DEAD:
- free_xenheap_page(per_cpu(doublefault_tss, cpu));
+ free_xenheap_page(per_cpu(doublefault_tss, hcpu->cpu));
break;
default:
break;
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/common/cpu.c
--- a/xen/common/cpu.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/common/cpu.c Tue Mar 20 13:15:07 2012 +0100
@@ -70,17 +70,21 @@ void __init register_cpu_notifier(struct
static int take_cpu_down(void *unused)
{
- void *hcpu = (void *)(long)smp_processor_id();
- int notifier_rc = notifier_call_chain(&cpu_chain, CPU_DYING, hcpu, NULL);
+ int notifier_rc;
+ struct cpu_notifier_data hcpu;
+
+ hcpu.cpu = smp_processor_id();
+ hcpu.reason = CPU_REASON_PERMANENT;
+ notifier_rc = notifier_call_chain(&cpu_chain, CPU_DYING, &hcpu, NULL);
BUG_ON(notifier_rc != NOTIFY_DONE);
__cpu_disable();
return 0;
}
-int cpu_down(unsigned int cpu)
+int cpu_down(unsigned int cpu, int reason)
{
int err, notifier_rc;
- void *hcpu = (void *)(long)cpu;
+ struct cpu_notifier_data hcpu;
struct notifier_block *nb = NULL;
if ( !cpu_hotplug_begin() )
@@ -92,7 +96,9 @@ int cpu_down(unsigned int cpu)
return -EINVAL;
}
- notifier_rc = notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, hcpu, &nb);
+ hcpu.cpu = cpu;
+ hcpu.reason = reason;
+ notifier_rc = notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, &hcpu, &nb);
if ( notifier_rc != NOTIFY_DONE )
{
err = notifier_to_errno(notifier_rc);
@@ -105,7 +111,7 @@ int cpu_down(unsigned int cpu)
__cpu_die(cpu);
BUG_ON(cpu_online(cpu));
- notifier_rc = notifier_call_chain(&cpu_chain, CPU_DEAD, hcpu, NULL);
+ notifier_rc = notifier_call_chain(&cpu_chain, CPU_DEAD, &hcpu, NULL);
BUG_ON(notifier_rc != NOTIFY_DONE);
send_global_virq(VIRQ_PCPU_STATE);
@@ -113,16 +119,16 @@ int cpu_down(unsigned int cpu)
return 0;
fail:
- notifier_rc = notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, hcpu, &nb);
+ notifier_rc = notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, &hcpu, &nb);
BUG_ON(notifier_rc != NOTIFY_DONE);
cpu_hotplug_done();
return err;
}
-int cpu_up(unsigned int cpu)
+int cpu_up(unsigned int cpu, int reason)
{
int notifier_rc, err = 0;
- void *hcpu = (void *)(long)cpu;
+ struct cpu_notifier_data hcpu;
struct notifier_block *nb = NULL;
if ( !cpu_hotplug_begin() )
@@ -134,7 +140,9 @@ int cpu_up(unsigned int cpu)
return -EINVAL;
}
- notifier_rc = notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu, &nb);
+ hcpu.cpu = cpu;
+ hcpu.reason = reason;
+ notifier_rc = notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, &hcpu, &nb);
if ( notifier_rc != NOTIFY_DONE )
{
err = notifier_to_errno(notifier_rc);
@@ -145,7 +153,7 @@ int cpu_up(unsigned int cpu)
if ( err < 0 )
goto fail;
- notifier_rc = notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu, NULL);
+ notifier_rc = notifier_call_chain(&cpu_chain, CPU_ONLINE, &hcpu, NULL);
BUG_ON(notifier_rc != NOTIFY_DONE);
send_global_virq(VIRQ_PCPU_STATE);
@@ -154,7 +162,7 @@ int cpu_up(unsigned int cpu)
return 0;
fail:
- notifier_rc = notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu, &nb);
+ notifier_rc = notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, &hcpu, &nb);
BUG_ON(notifier_rc != NOTIFY_DONE);
cpu_hotplug_done();
return err;
@@ -162,9 +170,13 @@ int cpu_up(unsigned int cpu)
void notify_cpu_starting(unsigned int cpu)
{
- void *hcpu = (void *)(long)cpu;
- int notifier_rc = notifier_call_chain(
- &cpu_chain, CPU_STARTING, hcpu, NULL);
+ int notifier_rc;
+ struct cpu_notifier_data hcpu;
+
+ hcpu.cpu = cpu;
+ hcpu.reason = CPU_REASON_PERMANENT;
+ notifier_rc = notifier_call_chain(
+ &cpu_chain, CPU_STARTING, &hcpu, NULL);
BUG_ON(notifier_rc != NOTIFY_DONE);
}
@@ -185,7 +197,7 @@ int disable_nonboot_cpus(void)
if ( cpu == 0 )
continue;
- if ( (error = cpu_down(cpu)) )
+ if ( (error = cpu_down(cpu, CPU_REASON_TEMP)) )
{
BUG_ON(error == -EBUSY);
printk("Error taking CPU%d down: %d\n", cpu, error);
@@ -207,7 +219,7 @@ void enable_nonboot_cpus(void)
for_each_cpu ( cpu, &frozen_cpus )
{
- if ( (error = cpu_up(cpu)) )
+ if ( (error = cpu_up(cpu, CPU_REASON_TEMP)) )
{
BUG_ON(error == -EBUSY);
printk("Error taking CPU%d up: %d\n", cpu, error);
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/common/cpupool.c
--- a/xen/common/cpupool.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/common/cpupool.c Tue Mar 20 13:15:07 2012 +0100
@@ -624,19 +624,21 @@ void dump_runq(unsigned char key)
}
static int cpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
int rc = 0;
+ struct cpu_notifier_data *hcpu = data;
switch ( action )
{
case CPU_DOWN_FAILED:
case CPU_ONLINE:
- cpupool_cpu_add(cpu);
+ if ( hcpu->reason == CPU_REASON_PERMANENT )
+ cpupool_cpu_add(hcpu->cpu);
break;
case CPU_DOWN_PREPARE:
- rc = cpupool_cpu_remove(cpu);
+ if ( hcpu->reason == CPU_REASON_PERMANENT )
+ rc = cpupool_cpu_remove(hcpu->cpu);
break;
default:
break;
@@ -652,11 +654,14 @@ static int __init cpupool_presmp_init(vo
static int __init cpupool_presmp_init(void)
{
int err;
- void *cpu = (void *)(long)smp_processor_id();
+ struct cpu_notifier_data hcpu;
+
+ hcpu.reason = CPU_REASON_PERMANENT;
+ hcpu.cpu = smp_processor_id();
cpupool0 = cpupool_create(0, 0, &err);
BUG_ON(cpupool0 == NULL);
cpupool_put(cpupool0);
- cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
+ cpu_callback(&cpu_nfb, CPU_ONLINE, &hcpu);
register_cpu_notifier(&cpu_nfb);
return 0;
}
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/common/kexec.c
--- a/xen/common/kexec.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/common/kexec.c Tue Mar 20 13:15:07 2012 +0100
@@ -457,9 +457,9 @@ static int kexec_init_cpu_notes(const un
}
static int cpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned long cpu = (unsigned long)hcpu;
+ struct cpu_notifier_data *hcpu = data;
/* Only hook on CPU_UP_PREPARE because once a crash_note has been reported
* to dom0, it must keep it around in case of a crash, as the crash kernel
@@ -471,7 +471,7 @@ static int cpu_callback(
* manner of problems elsewhere very soon, and if it is during runtime,
* then failing to allocate crash notes is not a good enough reason to
* fail the CPU_UP_PREPARE */
- kexec_init_cpu_notes(cpu);
+ kexec_init_cpu_notes(hcpu->cpu);
break;
default:
break;
@@ -497,7 +497,10 @@ void __init kexec_early_calculations(voi
static int __init kexec_init(void)
{
- void *cpu = (void *)(unsigned long)smp_processor_id();
+ struct cpu_notifier_data hcpu;
+
+ hcpu.cpu = smp_processor_id();
+ hcpu.reason = CPU_REASON_PERMANENT;
/* If no crash area, no need to allocate space for notes. */
if ( !kexec_crash_area.size )
@@ -532,7 +535,7 @@ static int __init kexec_init(void)
register_keyhandler('C', &crashdump_trigger_keyhandler);
- cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
+ cpu_callback(&cpu_nfb, CPU_UP_PREPARE, &hcpu);
register_cpu_notifier(&cpu_nfb);
return 0;
}
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/common/rcupdate.c
--- a/xen/common/rcupdate.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/common/rcupdate.c Tue Mar 20 13:15:07 2012 +0100
@@ -453,15 +453,15 @@ static void rcu_init_percpu_data(int cpu
}
static int cpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
- struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
+ struct cpu_notifier_data *hcpu = data;
+ struct rcu_data *rdp = &per_cpu(rcu_data, hcpu->cpu);
switch ( action )
{
case CPU_UP_PREPARE:
- rcu_init_percpu_data(cpu, &rcu_ctrlblk, rdp);
+ rcu_init_percpu_data(hcpu->cpu, &rcu_ctrlblk, rdp);
break;
case CPU_UP_CANCELED:
case CPU_DEAD:
@@ -480,8 +480,11 @@ static struct notifier_block cpu_nfb = {
void __init rcu_init(void)
{
- void *cpu = (void *)(long)smp_processor_id();
- cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
+ struct cpu_notifier_data hcpu;
+
+ hcpu.cpu = smp_processor_id();
+ hcpu.reason = CPU_REASON_PERMANENT;
+ cpu_callback(&cpu_nfb, CPU_UP_PREPARE, &hcpu);
register_cpu_notifier(&cpu_nfb);
open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
}
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/common/sched_credit2.c
--- a/xen/common/sched_credit2.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/common/sched_credit2.c Tue Mar 20 13:15:07 2012 +0100
@@ -2003,15 +2003,15 @@ csched_cpu_starting(int cpu)
}
static int cpu_credit2_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
int rc = 0;
+ struct cpu_notifier_data *hcpu = data;
switch ( action )
{
case CPU_STARTING:
- csched_cpu_starting(cpu);
+ csched_cpu_starting(hcpu->cpu);
break;
default:
break;
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/common/schedule.c
--- a/xen/common/schedule.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/common/schedule.c Tue Mar 20 13:15:07 2012 +0100
@@ -1254,19 +1254,19 @@ static void cpu_schedule_down(unsigned i
}
static int cpu_schedule_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
int rc = 0;
+ struct cpu_notifier_data *hcpu = data;
switch ( action )
{
case CPU_UP_PREPARE:
- rc = cpu_schedule_up(cpu);
+ rc = cpu_schedule_up(hcpu->cpu);
break;
case CPU_UP_CANCELED:
case CPU_DEAD:
- cpu_schedule_down(cpu);
+ cpu_schedule_down(hcpu->cpu);
break;
default:
break;
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/common/stop_machine.c
--- a/xen/common/stop_machine.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/common/stop_machine.c Tue Mar 20 13:15:07 2012 +0100
@@ -165,13 +165,13 @@ static void stopmachine_action(unsigned
}
static int cpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
+ struct cpu_notifier_data *hcpu = data;
if ( action == CPU_UP_PREPARE )
- tasklet_init(&per_cpu(stopmachine_tasklet, cpu),
- stopmachine_action, cpu);
+ tasklet_init(&per_cpu(stopmachine_tasklet, hcpu->cpu),
+ stopmachine_action, hcpu->cpu);
return NOTIFY_DONE;
}
@@ -182,11 +182,12 @@ static struct notifier_block cpu_nfb = {
static int __init cpu_stopmachine_init(void)
{
- unsigned int cpu;
- for_each_online_cpu ( cpu )
+ struct cpu_notifier_data hcpu;
+
+ hcpu.reason = CPU_REASON_PERMANENT;
+ for_each_online_cpu ( hcpu.cpu )
{
- void *hcpu = (void *)(long)cpu;
- cpu_callback(&cpu_nfb, CPU_UP_PREPARE, hcpu);
+ cpu_callback(&cpu_nfb, CPU_UP_PREPARE, &hcpu);
}
register_cpu_notifier(&cpu_nfb);
return 0;
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/common/tasklet.c
--- a/xen/common/tasklet.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/common/tasklet.c Tue Mar 20 13:15:07 2012 +0100
@@ -209,20 +209,20 @@ void softirq_tasklet_init(
}
static int cpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
+ struct cpu_notifier_data *hcpu = data;
switch ( action )
{
case CPU_UP_PREPARE:
- INIT_LIST_HEAD(&per_cpu(tasklet_list, cpu));
- INIT_LIST_HEAD(&per_cpu(softirq_tasklet_list, cpu));
+ INIT_LIST_HEAD(&per_cpu(tasklet_list, hcpu->cpu));
+ INIT_LIST_HEAD(&per_cpu(softirq_tasklet_list, hcpu->cpu));
break;
case CPU_UP_CANCELED:
case CPU_DEAD:
- migrate_tasklets_from_cpu(cpu, &per_cpu(tasklet_list, cpu));
- migrate_tasklets_from_cpu(cpu, &per_cpu(softirq_tasklet_list, cpu));
+ migrate_tasklets_from_cpu(hcpu->cpu, &per_cpu(tasklet_list, hcpu->cpu));
+ migrate_tasklets_from_cpu(hcpu->cpu, &per_cpu(softirq_tasklet_list, hcpu->cpu));
break;
default:
break;
@@ -238,8 +238,11 @@ static struct notifier_block cpu_nfb = {
void __init tasklet_subsys_init(void)
{
- void *hcpu = (void *)(long)smp_processor_id();
- cpu_callback(&cpu_nfb, CPU_UP_PREPARE, hcpu);
+ struct cpu_notifier_data hcpu;
+
+ hcpu.cpu = smp_processor_id();
+ hcpu.reason = CPU_REASON_PERMANENT;
+ cpu_callback(&cpu_nfb, CPU_UP_PREPARE, &hcpu);
register_cpu_notifier(&cpu_nfb);
open_softirq(TASKLET_SOFTIRQ, tasklet_softirq_action);
tasklets_initialised = 1;
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/common/timer.c
--- a/xen/common/timer.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/common/timer.c Tue Mar 20 13:15:07 2012 +0100
@@ -596,10 +596,10 @@ static struct timer *dummy_heap;
static struct timer *dummy_heap;
static int cpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
- struct timers *ts = &per_cpu(timers, cpu);
+ struct cpu_notifier_data *hcpu = data;
+ struct timers *ts = &per_cpu(timers, hcpu->cpu);
switch ( action )
{
@@ -610,7 +610,7 @@ static int cpu_callback(
break;
case CPU_UP_CANCELED:
case CPU_DEAD:
- migrate_timers_from_cpu(cpu);
+ migrate_timers_from_cpu(hcpu->cpu);
break;
default:
break;
@@ -626,7 +626,10 @@ static struct notifier_block cpu_nfb = {
void __init timer_init(void)
{
- void *cpu = (void *)(long)smp_processor_id();
+ struct cpu_notifier_data hcpu;
+
+ hcpu.cpu = smp_processor_id();
+ hcpu.reason = CPU_REASON_PERMANENT;
open_softirq(TIMER_SOFTIRQ, timer_softirq_action);
@@ -637,7 +640,7 @@ void __init timer_init(void)
SET_HEAP_SIZE(&dummy_heap, 0);
SET_HEAP_LIMIT(&dummy_heap, 0);
- cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
+ cpu_callback(&cpu_nfb, CPU_UP_PREPARE, &hcpu);
register_cpu_notifier(&cpu_nfb);
register_keyhandler('a', &dump_timerq_keyhandler);
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/common/tmem_xen.c
--- a/xen/common/tmem_xen.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/common/tmem_xen.c Tue Mar 20 13:15:07 2012 +0100
@@ -412,38 +412,38 @@ static int dstmem_order, workmem_order;
static int dstmem_order, workmem_order;
static int cpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
+ struct cpu_notifier_data *hcpu = data;
switch ( action )
{
case CPU_UP_PREPARE: {
- if ( per_cpu(dstmem, cpu) == NULL )
+ if ( per_cpu(dstmem, hcpu->cpu) == NULL )
{
struct page_info *p = alloc_domheap_pages(0, dstmem_order, 0);
- per_cpu(dstmem, cpu) = p ? page_to_virt(p) : NULL;
+ per_cpu(dstmem, hcpu->cpu) = p ? page_to_virt(p) : NULL;
}
- if ( per_cpu(workmem, cpu) == NULL )
+ if ( per_cpu(workmem, hcpu->cpu) == NULL )
{
struct page_info *p = alloc_domheap_pages(0, workmem_order, 0);
- per_cpu(workmem, cpu) = p ? page_to_virt(p) : NULL;
+ per_cpu(workmem, hcpu->cpu) = p ? page_to_virt(p) : NULL;
}
break;
}
case CPU_DEAD:
case CPU_UP_CANCELED: {
- if ( per_cpu(dstmem, cpu) != NULL )
+ if ( per_cpu(dstmem, hcpu->cpu) != NULL )
{
- struct page_info *p = virt_to_page(per_cpu(dstmem, cpu));
+ struct page_info *p = virt_to_page(per_cpu(dstmem, hcpu->cpu));
free_domheap_pages(p, dstmem_order);
- per_cpu(dstmem, cpu) = NULL;
+ per_cpu(dstmem, hcpu->cpu) = NULL;
}
- if ( per_cpu(workmem, cpu) != NULL )
+ if ( per_cpu(workmem, hcpu->cpu) != NULL )
{
- struct page_info *p = virt_to_page(per_cpu(workmem, cpu));
+ struct page_info *p = virt_to_page(per_cpu(workmem, hcpu->cpu));
free_domheap_pages(p, workmem_order);
- per_cpu(workmem, cpu) = NULL;
+ per_cpu(workmem, hcpu->cpu) = NULL;
}
break;
}
@@ -460,7 +460,7 @@ static struct notifier_block cpu_nfb = {
EXPORT int __init tmh_init(void)
{
- unsigned int cpu;
+ struct cpu_notifier_data hcpu;
if ( !tmh_mempool_init() )
return 0;
@@ -468,10 +468,10 @@ EXPORT int __init tmh_init(void)
dstmem_order = get_order_from_pages(LZO_DSTMEM_PAGES);
workmem_order = get_order_from_bytes(LZO1X_1_MEM_COMPRESS);
- for_each_online_cpu ( cpu )
+ hcpu.reason = CPU_REASON_PERMANENT;
+ for_each_online_cpu ( hcpu.cpu )
{
- void *hcpu = (void *)(long)cpu;
- cpu_callback(&cpu_nfb, CPU_UP_PREPARE, hcpu);
+ cpu_callback(&cpu_nfb, CPU_UP_PREPARE, &hcpu);
}
register_cpu_notifier(&cpu_nfb);
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/common/trace.c
--- a/xen/common/trace.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/common/trace.c Tue Mar 20 13:15:07 2012 +0100
@@ -80,12 +80,12 @@ static u32 tb_event_mask = TRC_ALL;
#define fit_to_type(_type, _x) (((_x)+sizeof(_type)-1) / sizeof(_type))
static int cpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
+ struct cpu_notifier_data *hcpu = data;
if ( action == CPU_UP_PREPARE )
- spin_lock_init(&per_cpu(t_lock, cpu));
+ spin_lock_init(&per_cpu(t_lock, hcpu->cpu));
return NOTIFY_DONE;
}
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/drivers/cpufreq/cpufreq.c
--- a/xen/drivers/cpufreq/cpufreq.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/drivers/cpufreq/cpufreq.c Tue Mar 20 13:15:07 2012 +0100
@@ -615,18 +615,18 @@ void __init cpufreq_cmdline_parse(char *
}
static int cpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
+ struct cpu_notifier_data *hcpu = data;
switch ( action )
{
case CPU_DOWN_FAILED:
case CPU_ONLINE:
- (void)cpufreq_add_cpu(cpu);
+ (void)cpufreq_add_cpu(hcpu->cpu);
break;
case CPU_DOWN_PREPARE:
- (void)cpufreq_del_cpu(cpu);
+ (void)cpufreq_del_cpu(hcpu->cpu);
break;
default:
break;
@@ -641,8 +641,11 @@ static struct notifier_block cpu_nfb = {
static int __init cpufreq_presmp_init(void)
{
- void *cpu = (void *)(long)smp_processor_id();
- cpu_callback(&cpu_nfb, CPU_ONLINE, cpu);
+ struct cpu_notifier_data hcpu;
+
+ hcpu.cpu = smp_processor_id();
+ hcpu.reason = CPU_REASON_PERMANENT;
+ cpu_callback(&cpu_nfb, CPU_ONLINE, &hcpu);
register_cpu_notifier(&cpu_nfb);
return 0;
}
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/drivers/cpufreq/cpufreq_misc_governors.c
--- a/xen/drivers/cpufreq/cpufreq_misc_governors.c Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/drivers/cpufreq/cpufreq_misc_governors.c Tue Mar 20 13:15:07 2012 +0100
@@ -92,14 +92,14 @@ cpufreq_userspace_handle_option(const ch
}
static int cpufreq_userspace_cpu_callback(
- struct notifier_block *nfb, unsigned long action, void *hcpu)
+ struct notifier_block *nfb, unsigned long action, void *data)
{
- unsigned int cpu = (unsigned long)hcpu;
+ struct cpu_notifier_data *hcpu = data;
switch (action)
{
case CPU_UP_PREPARE:
- per_cpu(cpu_set_freq, cpu) = userspace_cmdline_freq;
+ per_cpu(cpu_set_freq, hcpu->cpu) = userspace_cmdline_freq;
break;
}
diff -r 4e1d091d10d8 -r 6ca47f4a35ab xen/include/xen/cpu.h
--- a/xen/include/xen/cpu.h Fri Mar 16 15:24:25 2012 +0000
+++ b/xen/include/xen/cpu.h Tue Mar 20 13:15:07 2012 +0100
@@ -48,9 +48,18 @@ void register_cpu_notifier(struct notifi
/* CPU_DEAD: CPU is dead. */
#define CPU_DEAD (0x0008 | NOTIFY_REVERSE)
+struct cpu_notifier_data {
+ unsigned int cpu;
+ int reason;
+};
+
/* Perform CPU hotplug. May return -EAGAIN. */
-int cpu_down(unsigned int cpu);
-int cpu_up(unsigned int cpu);
+int cpu_down(unsigned int cpu, int reason);
+int cpu_up(unsigned int cpu, int reason);
+/* cpu will be removed/added permanently (e.g. hotplug) */
+#define CPU_REASON_PERMANENT 1
+/* cpu will be removed/added temporarily (e.g. acpi state change) */
+#define CPU_REASON_TEMP 2
/* From arch code, send CPU_STARTING notification. */
void notify_cpu_starting(unsigned int cpu);
[-- Attachment #3: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] Allow ACPI state change with active cpupools
2012-03-20 12:15 [PATCH] Allow ACPI state change with active cpupools Juergen Gross
@ 2012-03-20 12:52 ` Keir Fraser
2012-03-20 13:35 ` Juergen Gross
0 siblings, 1 reply; 7+ messages in thread
From: Keir Fraser @ 2012-03-20 12:52 UTC (permalink / raw)
To: Juergen Gross, xen-devel
That's quite a lot of bother. Firstly, this could probably be supported by a
global system_state type of variable indicating whether we are booting,
suspending, normal. Etc. Secondly I wonder whether you really need to care
about this detail from within the cpupool code? When you offline a CPU in
cpupool!=0, remember it. Put it back in the pool when it onlines, if the
pool still exists. Don't prevent a pool from being destroyed just because it
has offline cpus as members. Something like that? Or even always have the
cpupool code put onlined cpus in pool 0, and have the acpi suspend code
remember and restore pool memberships.
-- Keir
On 20/03/2012 12:15, "Juergen Gross" <juergen.gross@ts.fujitsu.com> wrote:
> Changing the ACPI state (e.g. power off) while not all cpus are in cpupool 0
> will currently crash the hypervisor during disabling the other cpus.
> This patch avoids the crash by adding the reason for disabling a cpu (either
> permanent e.g. in case of cpu hotplug or temporary in case of ACPI state
> change).
> This requires an additional parameter for cpu callbacks. All callbacks are
> changed to take a structure as parameter instead of only the cpu number.
>
> Signed-off-by: Juergen Gross <juergen.gross@ts.fujitsu.com>
>
>
> 25 files changed, 185 insertions(+), 139 deletions(-)
> xen/arch/x86/acpi/cpu_idle.c | 13 ++++---
> xen/arch/x86/cpu/mcheck/mce.c | 8 ++--
> xen/arch/x86/cpu/mcheck/mce_intel.c | 8 ++--
> xen/arch/x86/hvm/hvm.c | 10 ++---
> xen/arch/x86/microcode.c | 6 +--
> xen/arch/x86/nmi.c | 17 +++++----
> xen/arch/x86/percpu.c | 8 ++--
> xen/arch/x86/setup.c | 2 -
> xen/arch/x86/smpboot.c | 8 ++--
> xen/arch/x86/sysctl.c | 8 ++--
> xen/arch/x86/x86_32/traps.c | 8 ++--
> xen/common/cpu.c | 46 ++++++++++++++++----------
> xen/common/cpupool.c | 17 ++++++---
> xen/common/kexec.c | 13 ++++---
> xen/common/rcupdate.c | 15 +++++---
> xen/common/sched_credit2.c | 6 +--
> xen/common/schedule.c | 8 ++--
> xen/common/stop_machine.c | 17 +++++----
> xen/common/tasklet.c | 19 ++++++----
> xen/common/timer.c | 15 +++++---
> xen/common/tmem_xen.c | 32 +++++++++---------
> xen/common/trace.c | 6 +--
> xen/drivers/cpufreq/cpufreq.c | 15 +++++---
> xen/drivers/cpufreq/cpufreq_misc_governors.c | 6 +--
> xen/include/xen/cpu.h | 13 ++++++-
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Allow ACPI state change with active cpupools
2012-03-20 12:52 ` Keir Fraser
@ 2012-03-20 13:35 ` Juergen Gross
2012-03-20 14:30 ` Keir Fraser
0 siblings, 1 reply; 7+ messages in thread
From: Juergen Gross @ 2012-03-20 13:35 UTC (permalink / raw)
To: Keir Fraser; +Cc: xen-devel
On 03/20/2012 01:52 PM, Keir Fraser wrote:
> That's quite a lot of bother. Firstly, this could probably be supported by a
> global system_state type of variable indicating whether we are booting,
> suspending, normal. Etc. Secondly I wonder whether you really need to care
> about this detail from within the cpupool code? When you offline a CPU in
> cpupool!=0, remember it. Put it back in the pool when it onlines, if the
> pool still exists. Don't prevent a pool from being destroyed just because it
> has offline cpus as members. Something like that? Or even always have the
> cpupool code put onlined cpus in pool 0, and have the acpi suspend code
> remember and restore pool memberships.
Hmm. Using a global variable seems to be hacky. I tried to find a clean solution
for the problem. If the changes are too big in your opinion, I'll try to handle
cpu offlining local to cpupools.
Thanks for your opinion,
Juergen
> -- Keir
>
> On 20/03/2012 12:15, "Juergen Gross"<juergen.gross@ts.fujitsu.com> wrote:
>
>> Changing the ACPI state (e.g. power off) while not all cpus are in cpupool 0
>> will currently crash the hypervisor during disabling the other cpus.
>> This patch avoids the crash by adding the reason for disabling a cpu (either
>> permanent e.g. in case of cpu hotplug or temporary in case of ACPI state
>> change).
>> This requires an additional parameter for cpu callbacks. All callbacks are
>> changed to take a structure as parameter instead of only the cpu number.
>>
>> Signed-off-by: Juergen Gross<juergen.gross@ts.fujitsu.com>
>>
>>
>> 25 files changed, 185 insertions(+), 139 deletions(-)
>> xen/arch/x86/acpi/cpu_idle.c | 13 ++++---
>> xen/arch/x86/cpu/mcheck/mce.c | 8 ++--
>> xen/arch/x86/cpu/mcheck/mce_intel.c | 8 ++--
>> xen/arch/x86/hvm/hvm.c | 10 ++---
>> xen/arch/x86/microcode.c | 6 +--
>> xen/arch/x86/nmi.c | 17 +++++----
>> xen/arch/x86/percpu.c | 8 ++--
>> xen/arch/x86/setup.c | 2 -
>> xen/arch/x86/smpboot.c | 8 ++--
>> xen/arch/x86/sysctl.c | 8 ++--
>> xen/arch/x86/x86_32/traps.c | 8 ++--
>> xen/common/cpu.c | 46 ++++++++++++++++----------
>> xen/common/cpupool.c | 17 ++++++---
>> xen/common/kexec.c | 13 ++++---
>> xen/common/rcupdate.c | 15 +++++---
>> xen/common/sched_credit2.c | 6 +--
>> xen/common/schedule.c | 8 ++--
>> xen/common/stop_machine.c | 17 +++++----
>> xen/common/tasklet.c | 19 ++++++----
>> xen/common/timer.c | 15 +++++---
>> xen/common/tmem_xen.c | 32 +++++++++---------
>> xen/common/trace.c | 6 +--
>> xen/drivers/cpufreq/cpufreq.c | 15 +++++---
>> xen/drivers/cpufreq/cpufreq_misc_governors.c | 6 +--
>> xen/include/xen/cpu.h | 13 ++++++-
>>
>>
>> _______________________________________________
>> Xen-devel mailing list
>> Xen-devel@lists.xen.org
>> http://lists.xen.org/xen-devel
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
>
>
--
Juergen Gross Principal Developer Operating Systems
PDG ES&S SWE OS6 Telephone: +49 (0) 89 3222 2967
Fujitsu Technology Solutions e-mail: juergen.gross@ts.fujitsu.com
Domagkstr. 28 Internet: ts.fujitsu.com
D-80807 Muenchen Company details: ts.fujitsu.com/imprint.html
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Allow ACPI state change with active cpupools
2012-03-20 13:35 ` Juergen Gross
@ 2012-03-20 14:30 ` Keir Fraser
2012-03-20 14:46 ` Juergen Gross
0 siblings, 1 reply; 7+ messages in thread
From: Keir Fraser @ 2012-03-20 14:30 UTC (permalink / raw)
To: Juergen Gross; +Cc: xen-devel
On 20/03/2012 13:35, "Juergen Gross" <juergen.gross@ts.fujitsu.com> wrote:
> On 03/20/2012 01:52 PM, Keir Fraser wrote:
>> That's quite a lot of bother. Firstly, this could probably be supported by a
>> global system_state type of variable indicating whether we are booting,
>> suspending, normal. Etc. Secondly I wonder whether you really need to care
>> about this detail from within the cpupool code? When you offline a CPU in
>> cpupool!=0, remember it. Put it back in the pool when it onlines, if the
>> pool still exists. Don't prevent a pool from being destroyed just because it
>> has offline cpus as members. Something like that? Or even always have the
>> cpupool code put onlined cpus in pool 0, and have the acpi suspend code
>> remember and restore pool memberships.
>
> Hmm. Using a global variable seems to be hacky.
I'm not so sure. Suspend/resume is a significant out-of-the-ordinary global
system state. Representing that in a state variable doesn't seem so bad.
There are other states we could fold into this, for example we have an
early_boot variable in arch/x86 which could become part of the state
enumeration.
> I tried to find a clean
> solution
> for the problem. If the changes are too big in your opinion, I'll try to
> handle
> cpu offlining local to cpupools.
Is it better to have cpupools know about offlining/suspend, or have
offlining/suspend know about cpupools? I would have thought the latter makes
more sense since it is offlining/suspend which calls into the cpupool
subsystem.
-- Keir
> Thanks for your opinion,
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Allow ACPI state change with active cpupools
2012-03-20 14:30 ` Keir Fraser
@ 2012-03-20 14:46 ` Juergen Gross
2012-03-20 14:55 ` Keir Fraser
0 siblings, 1 reply; 7+ messages in thread
From: Juergen Gross @ 2012-03-20 14:46 UTC (permalink / raw)
To: Keir Fraser; +Cc: xen-devel
On 03/20/2012 03:30 PM, Keir Fraser wrote:
> On 20/03/2012 13:35, "Juergen Gross"<juergen.gross@ts.fujitsu.com> wrote:
>
>> On 03/20/2012 01:52 PM, Keir Fraser wrote:
>>> That's quite a lot of bother. Firstly, this could probably be supported by a
>>> global system_state type of variable indicating whether we are booting,
>>> suspending, normal. Etc. Secondly I wonder whether you really need to care
>>> about this detail from within the cpupool code? When you offline a CPU in
>>> cpupool!=0, remember it. Put it back in the pool when it onlines, if the
>>> pool still exists. Don't prevent a pool from being destroyed just because it
>>> has offline cpus as members. Something like that? Or even always have the
>>> cpupool code put onlined cpus in pool 0, and have the acpi suspend code
>>> remember and restore pool memberships.
>> Hmm. Using a global variable seems to be hacky.
> I'm not so sure. Suspend/resume is a significant out-of-the-ordinary global
> system state. Representing that in a state variable doesn't seem so bad.
> There are other states we could fold into this, for example we have an
> early_boot variable in arch/x86 which could become part of the state
> enumeration.
>
>> I tried to find a clean
>> solution
>> for the problem. If the changes are too big in your opinion, I'll try to
>> handle
>> cpu offlining local to cpupools.
> Is it better to have cpupools know about offlining/suspend, or have
> offlining/suspend know about cpupools? I would have thought the latter makes
> more sense since it is offlining/suspend which calls into the cpupool
> subsystem.
I thought of a more relaxed solution in the cpupool coding:
Instead of allowing to offline a cpu only if it is in Pool-0, I would allow it
if:
- the cpu is not the last one in the cpupool
- or no domain is active in the cpupool (this would include the suspend case,
where all domains are paused)
Together with your proposal to remember the cpupool for an offlined cpu to add
it again when it is onlined the handling should be rather simple and local.
Juergen
--
Juergen Gross Principal Developer Operating Systems
PDG ES&S SWE OS6 Telephone: +49 (0) 89 3222 2967
Fujitsu Technology Solutions e-mail: juergen.gross@ts.fujitsu.com
Domagkstr. 28 Internet: ts.fujitsu.com
D-80807 Muenchen Company details: ts.fujitsu.com/imprint.html
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Allow ACPI state change with active cpupools
2012-03-20 14:46 ` Juergen Gross
@ 2012-03-20 14:55 ` Keir Fraser
2012-03-21 13:46 ` Juergen Gross
0 siblings, 1 reply; 7+ messages in thread
From: Keir Fraser @ 2012-03-20 14:55 UTC (permalink / raw)
To: Juergen Gross; +Cc: xen-devel
On 20/03/2012 14:46, "Juergen Gross" <juergen.gross@ts.fujitsu.com> wrote:
>> Is it better to have cpupools know about offlining/suspend, or have
>> offlining/suspend know about cpupools? I would have thought the latter makes
>> more sense since it is offlining/suspend which calls into the cpupool
>> subsystem.
>
> I thought of a more relaxed solution in the cpupool coding:
>
> Instead of allowing to offline a cpu only if it is in Pool-0, I would allow it
> if:
> - the cpu is not the last one in the cpupool
> - or no domain is active in the cpupool (this would include the suspend case,
> where all domains are paused)
>
> Together with your proposal to remember the cpupool for an offlined cpu to add
> it again when it is onlined the handling should be rather simple and local.
Ah, I see. Yes, a more flexible policy like this in the cpupool subsystem is
best solution of all, imo.
-- Keir
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Allow ACPI state change with active cpupools
2012-03-20 14:55 ` Keir Fraser
@ 2012-03-21 13:46 ` Juergen Gross
0 siblings, 0 replies; 7+ messages in thread
From: Juergen Gross @ 2012-03-21 13:46 UTC (permalink / raw)
To: Keir Fraser; +Cc: xen-devel
On 03/20/2012 03:55 PM, Keir Fraser wrote:
> On 20/03/2012 14:46, "Juergen Gross"<juergen.gross@ts.fujitsu.com> wrote:
>
>>> Is it better to have cpupools know about offlining/suspend, or have
>>> offlining/suspend know about cpupools? I would have thought the latter makes
>>> more sense since it is offlining/suspend which calls into the cpupool
>>> subsystem.
>> I thought of a more relaxed solution in the cpupool coding:
>>
>> Instead of allowing to offline a cpu only if it is in Pool-0, I would allow it
>> if:
>> - the cpu is not the last one in the cpupool
>> - or no domain is active in the cpupool (this would include the suspend case,
>> where all domains are paused)
>>
>> Together with your proposal to remember the cpupool for an offlined cpu to add
>> it again when it is onlined the handling should be rather simple and local.
> Ah, I see. Yes, a more flexible policy like this in the cpupool subsystem is
> best solution of all, imo.
I have a problem with that solution. I had to change cpu_disable_scheduler() to
do a vcpu_migrate() only if the vcpu is runnable. When the ACPI state change
isn't permanent like in poweroff case I don't want to change vcpu affinities.
This action might be necessary in vcpu_wake() if v->processor isn't usable for
the vcpu any more.
Unfortunately vcpu_migrate() is calling evtchn_move_pirqs(), which taking the
domain event channel lock. And vcpu_wake() is called at least by send_evtchn()
with that lock already hold...
Is it possible to use spin_lock_recursive() for the domain event channel lock?
Another solution would be to omit the vcpu_migrate() in cpu_disable_scheduler()
for paused vcpus only and to do it when unpausing the vcpu, but this would
leak scheduler internals...
Juergen
--
Juergen Gross Principal Developer Operating Systems
PDG ES&S SWE OS6 Telephone: +49 (0) 89 3222 2967
Fujitsu Technology Solutions e-mail: juergen.gross@ts.fujitsu.com
Domagkstr. 28 Internet: ts.fujitsu.com
D-80807 Muenchen Company details: ts.fujitsu.com/imprint.html
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-03-21 13:46 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-20 12:15 [PATCH] Allow ACPI state change with active cpupools Juergen Gross
2012-03-20 12:52 ` Keir Fraser
2012-03-20 13:35 ` Juergen Gross
2012-03-20 14:30 ` Keir Fraser
2012-03-20 14:46 ` Juergen Gross
2012-03-20 14:55 ` Keir Fraser
2012-03-21 13:46 ` Juergen Gross
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).