diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2014-03-25 10:44:06 -0400 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-03-25 10:44:06 -0400 |
| commit | f7b9ddb8a5e8a25954217fa25d114bd8cf4491a4 (patch) | |
| tree | 06837e268d145e59ad46d9cd5f6c36c16f2424c9 | |
| parent | ea2108c9308071ae41ae6f537724cb2734045943 (diff) | |
| parent | 2ed10cc15e7edf2daf22ce807a877a1266e97711 (diff) | |
Merge tag 'kvm-s390-20140325' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into kvm-next
3 fixes
- memory leak on certain SIGP conditions
- wrong size for idle bitmap (always too big)
- clear local interrupts on initial CPU reset
1 performance improvement
- improve performance with many guests on certain workloads
| -rw-r--r-- | arch/s390/include/asm/kvm_host.h | 3 | ||||
| -rw-r--r-- | arch/s390/kvm/interrupt.c | 14 | ||||
| -rw-r--r-- | arch/s390/kvm/kvm-s390.c | 6 | ||||
| -rw-r--r-- | arch/s390/kvm/kvm-s390.h | 1 | ||||
| -rw-r--r-- | arch/s390/kvm/sigp.c | 14 |
5 files changed, 28 insertions, 10 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index dd3933754d23..68897fc65950 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
| @@ -222,8 +222,7 @@ struct kvm_s390_float_interrupt { | |||
| 222 | struct list_head list; | 222 | struct list_head list; |
| 223 | atomic_t active; | 223 | atomic_t active; |
| 224 | int next_rr_cpu; | 224 | int next_rr_cpu; |
| 225 | unsigned long idle_mask[(KVM_MAX_VCPUS + sizeof(long) - 1) | 225 | unsigned long idle_mask[BITS_TO_LONGS(KVM_MAX_VCPUS)]; |
| 226 | / sizeof(long)]; | ||
| 227 | unsigned int irq_count; | 226 | unsigned int irq_count; |
| 228 | }; | 227 | }; |
| 229 | 228 | ||
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 2e2814eceb85..200a8f9390b6 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
| @@ -510,6 +510,20 @@ enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer) | |||
| 510 | return HRTIMER_NORESTART; | 510 | return HRTIMER_NORESTART; |
| 511 | } | 511 | } |
| 512 | 512 | ||
| 513 | void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu) | ||
| 514 | { | ||
| 515 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
| 516 | struct kvm_s390_interrupt_info *n, *inti = NULL; | ||
| 517 | |||
| 518 | spin_lock_bh(&li->lock); | ||
| 519 | list_for_each_entry_safe(inti, n, &li->list, list) { | ||
| 520 | list_del(&inti->list); | ||
| 521 | kfree(inti); | ||
| 522 | } | ||
| 523 | atomic_set(&li->active, 0); | ||
| 524 | spin_unlock_bh(&li->lock); | ||
| 525 | } | ||
| 526 | |||
| 513 | void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu) | 527 | void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu) |
| 514 | { | 528 | { |
| 515 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | 529 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index ce5b659ec531..6e1b990e427f 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
| @@ -255,6 +255,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
| 255 | { | 255 | { |
| 256 | int rc; | 256 | int rc; |
| 257 | char debug_name[16]; | 257 | char debug_name[16]; |
| 258 | static unsigned long sca_offset; | ||
| 258 | 259 | ||
| 259 | rc = -EINVAL; | 260 | rc = -EINVAL; |
| 260 | #ifdef CONFIG_KVM_S390_UCONTROL | 261 | #ifdef CONFIG_KVM_S390_UCONTROL |
| @@ -276,6 +277,10 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
| 276 | kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL); | 277 | kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL); |
| 277 | if (!kvm->arch.sca) | 278 | if (!kvm->arch.sca) |
| 278 | goto out_err; | 279 | goto out_err; |
| 280 | spin_lock(&kvm_lock); | ||
| 281 | sca_offset = (sca_offset + 16) & 0x7f0; | ||
| 282 | kvm->arch.sca = (struct sca_block *) ((char *) kvm->arch.sca + sca_offset); | ||
| 283 | spin_unlock(&kvm_lock); | ||
| 279 | 284 | ||
| 280 | sprintf(debug_name, "kvm-%u", current->pid); | 285 | sprintf(debug_name, "kvm-%u", current->pid); |
| 281 | 286 | ||
| @@ -432,6 +437,7 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu) | |||
| 432 | vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID; | 437 | vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID; |
| 433 | kvm_clear_async_pf_completion_queue(vcpu); | 438 | kvm_clear_async_pf_completion_queue(vcpu); |
| 434 | atomic_set_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags); | 439 | atomic_set_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags); |
| 440 | kvm_s390_clear_local_irqs(vcpu); | ||
| 435 | } | 441 | } |
| 436 | 442 | ||
| 437 | int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) | 443 | int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) |
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 5502cc951868..660e79f8f8e8 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h | |||
| @@ -129,6 +129,7 @@ enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer); | |||
| 129 | void kvm_s390_tasklet(unsigned long parm); | 129 | void kvm_s390_tasklet(unsigned long parm); |
| 130 | void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu); | 130 | void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu); |
| 131 | void kvm_s390_deliver_pending_machine_checks(struct kvm_vcpu *vcpu); | 131 | void kvm_s390_deliver_pending_machine_checks(struct kvm_vcpu *vcpu); |
| 132 | void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu); | ||
| 132 | int __must_check kvm_s390_inject_vm(struct kvm *kvm, | 133 | int __must_check kvm_s390_inject_vm(struct kvm *kvm, |
| 133 | struct kvm_s390_interrupt *s390int); | 134 | struct kvm_s390_interrupt *s390int); |
| 134 | int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, | 135 | int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, |
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 3fe44c441609..26caeb530a78 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c | |||
| @@ -58,7 +58,9 @@ static int __sigp_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr) | |||
| 58 | struct kvm_s390_interrupt_info *inti; | 58 | struct kvm_s390_interrupt_info *inti; |
| 59 | struct kvm_vcpu *dst_vcpu = NULL; | 59 | struct kvm_vcpu *dst_vcpu = NULL; |
| 60 | 60 | ||
| 61 | if (cpu_addr >= KVM_MAX_VCPUS) | 61 | if (cpu_addr < KVM_MAX_VCPUS) |
| 62 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
| 63 | if (!dst_vcpu) | ||
| 62 | return SIGP_CC_NOT_OPERATIONAL; | 64 | return SIGP_CC_NOT_OPERATIONAL; |
| 63 | 65 | ||
| 64 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); | 66 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); |
| @@ -68,9 +70,6 @@ static int __sigp_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr) | |||
| 68 | inti->type = KVM_S390_INT_EMERGENCY; | 70 | inti->type = KVM_S390_INT_EMERGENCY; |
| 69 | inti->emerg.code = vcpu->vcpu_id; | 71 | inti->emerg.code = vcpu->vcpu_id; |
| 70 | 72 | ||
| 71 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
| 72 | if (!dst_vcpu) | ||
| 73 | return SIGP_CC_NOT_OPERATIONAL; | ||
| 74 | li = &dst_vcpu->arch.local_int; | 73 | li = &dst_vcpu->arch.local_int; |
| 75 | spin_lock_bh(&li->lock); | 74 | spin_lock_bh(&li->lock); |
| 76 | list_add_tail(&inti->list, &li->list); | 75 | list_add_tail(&inti->list, &li->list); |
| @@ -121,7 +120,9 @@ static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr) | |||
| 121 | struct kvm_s390_interrupt_info *inti; | 120 | struct kvm_s390_interrupt_info *inti; |
| 122 | struct kvm_vcpu *dst_vcpu = NULL; | 121 | struct kvm_vcpu *dst_vcpu = NULL; |
| 123 | 122 | ||
| 124 | if (cpu_addr >= KVM_MAX_VCPUS) | 123 | if (cpu_addr < KVM_MAX_VCPUS) |
| 124 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
| 125 | if (!dst_vcpu) | ||
| 125 | return SIGP_CC_NOT_OPERATIONAL; | 126 | return SIGP_CC_NOT_OPERATIONAL; |
| 126 | 127 | ||
| 127 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); | 128 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); |
| @@ -131,9 +132,6 @@ static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr) | |||
| 131 | inti->type = KVM_S390_INT_EXTERNAL_CALL; | 132 | inti->type = KVM_S390_INT_EXTERNAL_CALL; |
| 132 | inti->extcall.code = vcpu->vcpu_id; | 133 | inti->extcall.code = vcpu->vcpu_id; |
| 133 | 134 | ||
| 134 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
| 135 | if (!dst_vcpu) | ||
| 136 | return SIGP_CC_NOT_OPERATIONAL; | ||
| 137 | li = &dst_vcpu->arch.local_int; | 135 | li = &dst_vcpu->arch.local_int; |
| 138 | spin_lock_bh(&li->lock); | 136 | spin_lock_bh(&li->lock); |
| 139 | list_add_tail(&inti->list, &li->list); | 137 | list_add_tail(&inti->list, &li->list); |
