KVM: x86: add apic_timer_expired()
authorRadim Krčmář <rkrcmar@redhat.com>
Fri, 10 Oct 2014 17:15:08 +0000 (19:15 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Mon, 3 Nov 2014 11:07:27 +0000 (12:07 +0100)
Make the code reusable.

If the timer was already pending, we shouldn't be waiting in a queue,
so wake_up can be skipped, simplifying the path.

There is no 'reinject' case => the comment is removed.
Current race behaves correctly.

Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/lapic.c

index ee04adf6c73a5913d823c9be5b4827ba8b491eb8..1ebd7ff33ac7af0f01d3245c2dcf390fdf2d7742 100644 (file)
@@ -1050,6 +1050,26 @@ static void update_divide_count(struct kvm_lapic *apic)
                                   apic->divide_count);
 }
 
+static void apic_timer_expired(struct kvm_lapic *apic)
+{
+       struct kvm_vcpu *vcpu = apic->vcpu;
+       wait_queue_head_t *q = &vcpu->wq;
+
+       /*
+        * Note: KVM_REQ_PENDING_TIMER is implicitly checked in
+        * vcpu_enter_guest.
+        */
+       if (atomic_read(&apic->lapic_timer.pending))
+               return;
+
+       atomic_inc(&apic->lapic_timer.pending);
+       /* FIXME: this code should not know anything about vcpus */
+       kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu);
+
+       if (waitqueue_active(q))
+               wake_up_interruptible(q);
+}
+
 static void start_apic_timer(struct kvm_lapic *apic)
 {
        ktime_t now;
@@ -1554,23 +1574,8 @@ static enum hrtimer_restart apic_timer_fn(struct hrtimer *data)
 {
        struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer);
        struct kvm_lapic *apic = container_of(ktimer, struct kvm_lapic, lapic_timer);
-       struct kvm_vcpu *vcpu = apic->vcpu;
-       wait_queue_head_t *q = &vcpu->wq;
-
-       /*
-        * There is a race window between reading and incrementing, but we do
-        * not care about potentially losing timer events in the !reinject
-        * case anyway. Note: KVM_REQ_PENDING_TIMER is implicitly checked
-        * in vcpu_enter_guest.
-        */
-       if (!atomic_read(&ktimer->pending)) {
-               atomic_inc(&ktimer->pending);
-               /* FIXME: this code should not know anything about vcpus */
-               kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu);
-       }
 
-       if (waitqueue_active(q))
-               wake_up_interruptible(q);
+       apic_timer_expired(apic);
 
        if (lapic_is_periodic(apic)) {
                hrtimer_add_expires_ns(&ktimer->timer, ktimer->period);