diff options
author | He, Qing <qing.he@intel.com> | 2007-09-03 18:01:36 +0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-10-13 12:18:26 +0400 |
commit | 932f72adbe76f098922c746737cb0bd75fc21e27 (patch) | |
tree | 55a98bd0692094289d4bea4f5b2c58835f8b59df /drivers/kvm/lapic.c | |
parent | 40487c680d5855459dfdce340df13d40071bb774 (diff) | |
download | linux-932f72adbe76f098922c746737cb0bd75fc21e27.tar.xz |
KVM: round robin for APIC lowest priority delivery mode
Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/lapic.c')
-rw-r--r-- | drivers/kvm/lapic.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/drivers/kvm/lapic.c b/drivers/kvm/lapic.c index 01e769672dcc..ca1db3852ace 100644 --- a/drivers/kvm/lapic.c +++ b/drivers/kvm/lapic.c @@ -371,12 +371,35 @@ struct kvm_lapic *kvm_apic_round_robin(struct kvm *kvm, u8 vector, unsigned long bitmap) { int vcpu_id; + int last; + int next; + struct kvm_lapic *apic; + + last = kvm->round_robin_prev_vcpu; + next = last; + + do { + if (++next == KVM_MAX_VCPUS) + next = 0; + if (kvm->vcpus[next] == NULL || !test_bit(next, &bitmap)) + continue; + apic = kvm->vcpus[next]->apic; + if (apic && apic_enabled(apic)) + break; + apic = NULL; + } while (next != last); + kvm->round_robin_prev_vcpu = next; + + if (!apic) { + vcpu_id = ffs(bitmap) - 1; + if (vcpu_id < 0) { + vcpu_id = 0; + printk(KERN_DEBUG "vcpu not ready for apic_round_robin\n"); + } + apic = kvm->vcpus[vcpu_id]->apic; + } - /* TODO for real round robin */ - vcpu_id = fls(bitmap) - 1; - if (vcpu_id < 0) - printk(KERN_DEBUG "vcpu not ready for apic_round_robin\n"); - return kvm->vcpus[vcpu_id]->apic; + return apic; } static void apic_set_eoi(struct kvm_lapic *apic) |