diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2016-07-13 13:16:37 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-07-15 04:40:23 -0400 |
commit | 8c18b2d2d0881b116ea52498c6d624c0a71e1fdc (patch) | |
tree | 8ebaca2853a4c8ccff9179f8ed91f0c00bbb429a | |
parent | 7d88eb695a1f5f67820e02999b949d5cfa080442 (diff) |
virt: Convert kvm hotplug to state machine
Install the callbacks via the state machine. The core won't invoke the
callbacks on already online CPUs.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Cc: Gleb Natapov <gleb@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Radim Krcmar <rkrcmar@redhat.com>
Cc: kvm@vger.kernel.org
Cc: rt@linutronix.de
Link: http://lkml.kernel.org/r/20160713153335.886159080@linutronix.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | include/linux/cpuhotplug.h | 1 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 32 |
2 files changed, 9 insertions, 24 deletions
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index a5b6a6526af8..5423997c94f7 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h | |||
@@ -36,6 +36,7 @@ enum cpuhp_state { | |||
36 | CPUHP_AP_PERF_XTENSA_STARTING, | 36 | CPUHP_AP_PERF_XTENSA_STARTING, |
37 | CPUHP_AP_ARM_VFP_STARTING, | 37 | CPUHP_AP_ARM_VFP_STARTING, |
38 | CPUHP_AP_PERF_ARM_STARTING, | 38 | CPUHP_AP_PERF_ARM_STARTING, |
39 | CPUHP_AP_KVM_STARTING, | ||
39 | CPUHP_AP_NOTIFY_STARTING, | 40 | CPUHP_AP_NOTIFY_STARTING, |
40 | CPUHP_AP_ONLINE, | 41 | CPUHP_AP_ONLINE, |
41 | CPUHP_TEARDOWN_CPU, | 42 | CPUHP_TEARDOWN_CPU, |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 48bd520fc702..c1d6cf5a74a1 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -3144,12 +3144,13 @@ static void hardware_enable_nolock(void *junk) | |||
3144 | } | 3144 | } |
3145 | } | 3145 | } |
3146 | 3146 | ||
3147 | static void hardware_enable(void) | 3147 | static int kvm_starting_cpu(unsigned int cpu) |
3148 | { | 3148 | { |
3149 | raw_spin_lock(&kvm_count_lock); | 3149 | raw_spin_lock(&kvm_count_lock); |
3150 | if (kvm_usage_count) | 3150 | if (kvm_usage_count) |
3151 | hardware_enable_nolock(NULL); | 3151 | hardware_enable_nolock(NULL); |
3152 | raw_spin_unlock(&kvm_count_lock); | 3152 | raw_spin_unlock(&kvm_count_lock); |
3153 | return 0; | ||
3153 | } | 3154 | } |
3154 | 3155 | ||
3155 | static void hardware_disable_nolock(void *junk) | 3156 | static void hardware_disable_nolock(void *junk) |
@@ -3162,12 +3163,13 @@ static void hardware_disable_nolock(void *junk) | |||
3162 | kvm_arch_hardware_disable(); | 3163 | kvm_arch_hardware_disable(); |
3163 | } | 3164 | } |
3164 | 3165 | ||
3165 | static void hardware_disable(void) | 3166 | static int kvm_dying_cpu(unsigned int cpu) |
3166 | { | 3167 | { |
3167 | raw_spin_lock(&kvm_count_lock); | 3168 | raw_spin_lock(&kvm_count_lock); |
3168 | if (kvm_usage_count) | 3169 | if (kvm_usage_count) |
3169 | hardware_disable_nolock(NULL); | 3170 | hardware_disable_nolock(NULL); |
3170 | raw_spin_unlock(&kvm_count_lock); | 3171 | raw_spin_unlock(&kvm_count_lock); |
3172 | return 0; | ||
3171 | } | 3173 | } |
3172 | 3174 | ||
3173 | static void hardware_disable_all_nolock(void) | 3175 | static void hardware_disable_all_nolock(void) |
@@ -3208,21 +3210,6 @@ static int hardware_enable_all(void) | |||
3208 | return r; | 3210 | return r; |
3209 | } | 3211 | } |
3210 | 3212 | ||
3211 | static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val, | ||
3212 | void *v) | ||
3213 | { | ||
3214 | val &= ~CPU_TASKS_FROZEN; | ||
3215 | switch (val) { | ||
3216 | case CPU_DYING: | ||
3217 | hardware_disable(); | ||
3218 | break; | ||
3219 | case CPU_STARTING: | ||
3220 | hardware_enable(); | ||
3221 | break; | ||
3222 | } | ||
3223 | return NOTIFY_OK; | ||
3224 | } | ||
3225 | |||
3226 | static int kvm_reboot(struct notifier_block *notifier, unsigned long val, | 3213 | static int kvm_reboot(struct notifier_block *notifier, unsigned long val, |
3227 | void *v) | 3214 | void *v) |
3228 | { | 3215 | { |
@@ -3489,10 +3476,6 @@ int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx, | |||
3489 | return r; | 3476 | return r; |
3490 | } | 3477 | } |
3491 | 3478 | ||
3492 | static struct notifier_block kvm_cpu_notifier = { | ||
3493 | .notifier_call = kvm_cpu_hotplug, | ||
3494 | }; | ||
3495 | |||
3496 | static int kvm_debugfs_open(struct inode *inode, struct file *file, | 3479 | static int kvm_debugfs_open(struct inode *inode, struct file *file, |
3497 | int (*get)(void *, u64 *), int (*set)(void *, u64), | 3480 | int (*get)(void *, u64 *), int (*set)(void *, u64), |
3498 | const char *fmt) | 3481 | const char *fmt) |
@@ -3743,7 +3726,8 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, | |||
3743 | goto out_free_1; | 3726 | goto out_free_1; |
3744 | } | 3727 | } |
3745 | 3728 | ||
3746 | r = register_cpu_notifier(&kvm_cpu_notifier); | 3729 | r = cpuhp_setup_state_nocalls(CPUHP_AP_KVM_STARTING, "AP_KVM_STARTING", |
3730 | kvm_starting_cpu, kvm_dying_cpu); | ||
3747 | if (r) | 3731 | if (r) |
3748 | goto out_free_2; | 3732 | goto out_free_2; |
3749 | register_reboot_notifier(&kvm_reboot_notifier); | 3733 | register_reboot_notifier(&kvm_reboot_notifier); |
@@ -3797,7 +3781,7 @@ out_free: | |||
3797 | kmem_cache_destroy(kvm_vcpu_cache); | 3781 | kmem_cache_destroy(kvm_vcpu_cache); |
3798 | out_free_3: | 3782 | out_free_3: |
3799 | unregister_reboot_notifier(&kvm_reboot_notifier); | 3783 | unregister_reboot_notifier(&kvm_reboot_notifier); |
3800 | unregister_cpu_notifier(&kvm_cpu_notifier); | 3784 | cpuhp_remove_state_nocalls(CPUHP_AP_KVM_STARTING); |
3801 | out_free_2: | 3785 | out_free_2: |
3802 | out_free_1: | 3786 | out_free_1: |
3803 | kvm_arch_hardware_unsetup(); | 3787 | kvm_arch_hardware_unsetup(); |
@@ -3820,7 +3804,7 @@ void kvm_exit(void) | |||
3820 | kvm_async_pf_deinit(); | 3804 | kvm_async_pf_deinit(); |
3821 | unregister_syscore_ops(&kvm_syscore_ops); | 3805 | unregister_syscore_ops(&kvm_syscore_ops); |
3822 | unregister_reboot_notifier(&kvm_reboot_notifier); | 3806 | unregister_reboot_notifier(&kvm_reboot_notifier); |
3823 | unregister_cpu_notifier(&kvm_cpu_notifier); | 3807 | cpuhp_remove_state_nocalls(CPUHP_AP_KVM_STARTING); |
3824 | on_each_cpu(hardware_disable_nolock, NULL, 1); | 3808 | on_each_cpu(hardware_disable_nolock, NULL, 1); |
3825 | kvm_arch_hardware_unsetup(); | 3809 | kvm_arch_hardware_unsetup(); |
3826 | kvm_arch_exit(); | 3810 | kvm_arch_exit(); |