aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>2014-05-13 10:54:32 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-07-21 07:22:16 -0400
commit0759d0681cae279e77ebb4b76175e330360b01d9 (patch)
tree42ce3eb00b2041e40441f2faf7382fd0805adbfe /arch/s390
parent6352e4d2dd9a349024a41356148eced553e1dce4 (diff)
KVM: s390: cleanup handle_wait by reusing kvm_vcpu_block
This patch cleans up the code in handle_wait by reusing the common code function kvm_vcpu_block. signal_pending(), kvm_cpu_has_pending_timer() and kvm_arch_vcpu_runnable() are sufficient for checking if we need to wake-up that VCPU. kvm_vcpu_block uses these functions, so no checks are lost. The flag "timer_due" can be removed - kvm_cpu_has_pending_timer() tests whether the timer is pending, thus the vcpu is correctly woken up. Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Acked-by: Christian Borntraeger <borntraeger@de.ibm.com> Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/kvm_host.h1
-rw-r--r--arch/s390/kvm/interrupt.c41
-rw-r--r--arch/s390/kvm/kvm-s390.c3
3 files changed, 8 insertions, 37 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index c2ba0208a0e1..b3acf28c8c96 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -305,7 +305,6 @@ struct kvm_s390_local_interrupt {
305 struct list_head list; 305 struct list_head list;
306 atomic_t active; 306 atomic_t active;
307 struct kvm_s390_float_interrupt *float_int; 307 struct kvm_s390_float_interrupt *float_int;
308 int timer_due; /* event indicator for waitqueue below */
309 wait_queue_head_t *wq; 308 wait_queue_head_t *wq;
310 atomic_t *cpuflags; 309 atomic_t *cpuflags;
311 unsigned int action_bits; 310 unsigned int action_bits;
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 90c8de22a2a0..5fd11ce3dc3d 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -585,60 +585,32 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
585int kvm_s390_handle_wait(struct kvm_vcpu *vcpu) 585int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)
586{ 586{
587 u64 now, sltime; 587 u64 now, sltime;
588 DECLARE_WAITQUEUE(wait, current);
589 588
590 vcpu->stat.exit_wait_state++; 589 vcpu->stat.exit_wait_state++;
591 if (kvm_cpu_has_interrupt(vcpu))
592 return 0;
593 590
594 __set_cpu_idle(vcpu); 591 /* fast path */
595 spin_lock_bh(&vcpu->arch.local_int.lock); 592 if (kvm_cpu_has_pending_timer(vcpu) || kvm_arch_vcpu_runnable(vcpu))
596 vcpu->arch.local_int.timer_due = 0; 593 return 0;
597 spin_unlock_bh(&vcpu->arch.local_int.lock);
598 594
599 if (psw_interrupts_disabled(vcpu)) { 595 if (psw_interrupts_disabled(vcpu)) {
600 VCPU_EVENT(vcpu, 3, "%s", "disabled wait"); 596 VCPU_EVENT(vcpu, 3, "%s", "disabled wait");
601 __unset_cpu_idle(vcpu);
602 return -EOPNOTSUPP; /* disabled wait */ 597 return -EOPNOTSUPP; /* disabled wait */
603 } 598 }
604 599
600 __set_cpu_idle(vcpu);
605 if (!ckc_interrupts_enabled(vcpu)) { 601 if (!ckc_interrupts_enabled(vcpu)) {
606 VCPU_EVENT(vcpu, 3, "%s", "enabled wait w/o timer"); 602 VCPU_EVENT(vcpu, 3, "%s", "enabled wait w/o timer");
607 goto no_timer; 603 goto no_timer;
608 } 604 }
609 605
610 now = get_tod_clock_fast() + vcpu->arch.sie_block->epoch; 606 now = get_tod_clock_fast() + vcpu->arch.sie_block->epoch;
611 if (vcpu->arch.sie_block->ckc < now) {
612 __unset_cpu_idle(vcpu);
613 return 0;
614 }
615
616 sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now); 607 sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now);
617
618 hrtimer_start(&vcpu->arch.ckc_timer, ktime_set (0, sltime) , HRTIMER_MODE_REL); 608 hrtimer_start(&vcpu->arch.ckc_timer, ktime_set (0, sltime) , HRTIMER_MODE_REL);
619 VCPU_EVENT(vcpu, 5, "enabled wait via clock comparator: %llx ns", sltime); 609 VCPU_EVENT(vcpu, 5, "enabled wait via clock comparator: %llx ns", sltime);
620no_timer: 610no_timer:
621 srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); 611 srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
622 spin_lock(&vcpu->arch.local_int.float_int->lock); 612 kvm_vcpu_block(vcpu);
623 spin_lock_bh(&vcpu->arch.local_int.lock);
624 add_wait_queue(&vcpu->wq, &wait);
625 while (list_empty(&vcpu->arch.local_int.list) &&
626 list_empty(&vcpu->arch.local_int.float_int->list) &&
627 (!vcpu->arch.local_int.timer_due) &&
628 !signal_pending(current) &&
629 !kvm_s390_si_ext_call_pending(vcpu)) {
630 set_current_state(TASK_INTERRUPTIBLE);
631 spin_unlock_bh(&vcpu->arch.local_int.lock);
632 spin_unlock(&vcpu->arch.local_int.float_int->lock);
633 schedule();
634 spin_lock(&vcpu->arch.local_int.float_int->lock);
635 spin_lock_bh(&vcpu->arch.local_int.lock);
636 }
637 __unset_cpu_idle(vcpu); 613 __unset_cpu_idle(vcpu);
638 __set_current_state(TASK_RUNNING);
639 remove_wait_queue(&vcpu->wq, &wait);
640 spin_unlock_bh(&vcpu->arch.local_int.lock);
641 spin_unlock(&vcpu->arch.local_int.float_int->lock);
642 vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); 614 vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
643 615
644 hrtimer_try_to_cancel(&vcpu->arch.ckc_timer); 616 hrtimer_try_to_cancel(&vcpu->arch.ckc_timer);
@@ -649,11 +621,8 @@ void kvm_s390_tasklet(unsigned long parm)
649{ 621{
650 struct kvm_vcpu *vcpu = (struct kvm_vcpu *) parm; 622 struct kvm_vcpu *vcpu = (struct kvm_vcpu *) parm;
651 623
652 spin_lock(&vcpu->arch.local_int.lock);
653 vcpu->arch.local_int.timer_due = 1;
654 if (waitqueue_active(&vcpu->wq)) 624 if (waitqueue_active(&vcpu->wq))
655 wake_up_interruptible(&vcpu->wq); 625 wake_up_interruptible(&vcpu->wq);
656 spin_unlock(&vcpu->arch.local_int.lock);
657} 626}
658 627
659/* 628/*
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index fdf88f7a539c..ecb135702313 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -1068,6 +1068,9 @@ retry:
1068 goto retry; 1068 goto retry;
1069 } 1069 }
1070 1070
1071 /* nothing to do, just clear the request */
1072 clear_bit(KVM_REQ_UNHALT, &vcpu->requests);
1073
1071 return 0; 1074 return 0;
1072} 1075}
1073 1076