# HG changeset patch # User Juergen Gross # 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 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);