aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2009-03-05 09:34:59 -0500
committerAvi Kivity <avi@redhat.com>2009-06-10 04:48:27 -0400
commite1035715ef8d3171e29f9c6aee6f40d57b3fead5 (patch)
tree1ead65420a4d1653692d0e4b66a4e4f7fcbef425
parent343f94fe4d16ec898da77720c03da9e09f8523d2 (diff)
KVM: change the way how lowest priority vcpu is calculated
The new way does not require additional loop over vcpus to calculate the one with lowest priority as one is chosen during delivery bitmap construction. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r--arch/ia64/kvm/kvm-ia64.c15
-rw-r--r--arch/ia64/kvm/lapic.h1
-rw-r--r--arch/x86/include/asm/kvm_host.h2
-rw-r--r--arch/x86/kvm/lapic.c43
-rw-r--r--virt/kvm/ioapic.h3
-rw-r--r--virt/kvm/irq_comm.c19
6 files changed, 22 insertions, 61 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index 8eea9cba7b7c..1887a93a2bd5 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -1836,20 +1836,9 @@ int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda)
1836 return 0; 1836 return 0;
1837} 1837}
1838 1838
1839struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, 1839int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2)
1840 unsigned long *bitmap)
1841{ 1840{
1842 struct kvm_vcpu *lvcpu = kvm->vcpus[0]; 1841 return vcpu1->arch.xtp - vcpu2->arch.xtp;
1843 int i;
1844
1845 for (i = 1; i < kvm->arch.online_vcpus; i++) {
1846 if (!kvm->vcpus[i])
1847 continue;
1848 if (lvcpu->arch.xtp > kvm->vcpus[i]->arch.xtp)
1849 lvcpu = kvm->vcpus[i];
1850 }
1851
1852 return lvcpu;
1853} 1842}
1854 1843
1855int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, 1844int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
diff --git a/arch/ia64/kvm/lapic.h b/arch/ia64/kvm/lapic.h
index 31602e7338d7..e42109e6ca47 100644
--- a/arch/ia64/kvm/lapic.h
+++ b/arch/ia64/kvm/lapic.h
@@ -22,6 +22,7 @@ int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest);
22int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); 22int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda);
23int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, 23int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
24 int short_hand, int dest, int dest_mode); 24 int short_hand, int dest, int dest_mode);
25int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2);
25bool kvm_apic_present(struct kvm_vcpu *vcpu); 26bool kvm_apic_present(struct kvm_vcpu *vcpu);
26int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 dmode, u8 trig); 27int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 dmode, u8 trig);
27 28
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index f0faf58044ff..46276273a1a1 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -286,6 +286,7 @@ struct kvm_vcpu_arch {
286 u64 shadow_efer; 286 u64 shadow_efer;
287 u64 apic_base; 287 u64 apic_base;
288 struct kvm_lapic *apic; /* kernel irqchip context */ 288 struct kvm_lapic *apic; /* kernel irqchip context */
289 int32_t apic_arb_prio;
289 int mp_state; 290 int mp_state;
290 int sipi_vector; 291 int sipi_vector;
291 u64 ia32_misc_enable_msr; 292 u64 ia32_misc_enable_msr;
@@ -400,7 +401,6 @@ struct kvm_arch{
400 struct hlist_head irq_ack_notifier_list; 401 struct hlist_head irq_ack_notifier_list;
401 int vapics_in_nmi_mode; 402 int vapics_in_nmi_mode;
402 403
403 int round_robin_prev_vcpu;
404 unsigned int tss_addr; 404 unsigned int tss_addr;
405 struct page *apic_access_page; 405 struct page *apic_access_page;
406 406
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 998862a3c267..814466f455d9 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -338,8 +338,9 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
338 struct kvm_vcpu *vcpu = apic->vcpu; 338 struct kvm_vcpu *vcpu = apic->vcpu;
339 339
340 switch (delivery_mode) { 340 switch (delivery_mode) {
341 case APIC_DM_FIXED:
342 case APIC_DM_LOWEST: 341 case APIC_DM_LOWEST:
342 vcpu->arch.apic_arb_prio++;
343 case APIC_DM_FIXED:
343 /* FIXME add logic for vcpu on reset */ 344 /* FIXME add logic for vcpu on reset */
344 if (unlikely(!apic_enabled(apic))) 345 if (unlikely(!apic_enabled(apic)))
345 break; 346 break;
@@ -416,43 +417,9 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
416 return result; 417 return result;
417} 418}
418 419
419static struct kvm_lapic *kvm_apic_round_robin(struct kvm *kvm, u8 vector, 420int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2)
420 unsigned long *bitmap)
421{ 421{
422 int last; 422 return vcpu1->arch.apic_arb_prio - vcpu2->arch.apic_arb_prio;
423 int next;
424 struct kvm_lapic *apic = NULL;
425
426 last = kvm->arch.round_robin_prev_vcpu;
427 next = last;
428
429 do {
430 if (++next == KVM_MAX_VCPUS)
431 next = 0;
432 if (kvm->vcpus[next] == NULL || !test_bit(next, bitmap))
433 continue;
434 apic = kvm->vcpus[next]->arch.apic;
435 if (apic && apic_enabled(apic))
436 break;
437 apic = NULL;
438 } while (next != last);
439 kvm->arch.round_robin_prev_vcpu = next;
440
441 if (!apic)
442 printk(KERN_DEBUG "vcpu not ready for apic_round_robin\n");
443
444 return apic;
445}
446
447struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector,
448 unsigned long *bitmap)
449{
450 struct kvm_lapic *apic;
451
452 apic = kvm_apic_round_robin(kvm, vector, bitmap);
453 if (apic)
454 return apic->vcpu;
455 return NULL;
456} 423}
457 424
458static void apic_set_eoi(struct kvm_lapic *apic) 425static void apic_set_eoi(struct kvm_lapic *apic)
@@ -908,6 +875,8 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
908 vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP; 875 vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP;
909 apic_update_ppr(apic); 876 apic_update_ppr(apic);
910 877
878 vcpu->arch.apic_arb_prio = 0;
879
911 apic_debug(KERN_INFO "%s: vcpu=%p, id=%d, base_msr=" 880 apic_debug(KERN_INFO "%s: vcpu=%p, id=%d, base_msr="
912 "0x%016" PRIx64 ", base_address=0x%0lx.\n", __func__, 881 "0x%016" PRIx64 ", base_address=0x%0lx.\n", __func__,
913 vcpu, kvm_apic_id(apic), 882 vcpu, kvm_apic_id(apic),
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h
index d996c7abc466..e7bc92d895ff 100644
--- a/virt/kvm/ioapic.h
+++ b/virt/kvm/ioapic.h
@@ -64,10 +64,9 @@ static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm)
64 return kvm->arch.vioapic; 64 return kvm->arch.vioapic;
65} 65}
66 66
67struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector,
68 unsigned long *bitmap);
69int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, 67int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
70 int short_hand, int dest, int dest_mode); 68 int short_hand, int dest, int dest_mode);
69int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2);
71void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode); 70void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode);
72int kvm_ioapic_init(struct kvm *kvm); 71int kvm_ioapic_init(struct kvm *kvm);
73int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level); 72int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level);
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index e43701c0a5c4..f5e059b67cd4 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -47,7 +47,7 @@ void kvm_get_intr_delivery_bitmask(struct kvm *kvm, struct kvm_lapic *src,
47 int dest_id, int dest_mode, bool low_prio, int short_hand, 47 int dest_id, int dest_mode, bool low_prio, int short_hand,
48 unsigned long *deliver_bitmask) 48 unsigned long *deliver_bitmask)
49{ 49{
50 int i; 50 int i, lowest = -1;
51 struct kvm_vcpu *vcpu; 51 struct kvm_vcpu *vcpu;
52 52
53 if (dest_mode == 0 && dest_id == 0xff && low_prio) 53 if (dest_mode == 0 && dest_id == 0xff && low_prio)
@@ -64,15 +64,18 @@ void kvm_get_intr_delivery_bitmask(struct kvm *kvm, struct kvm_lapic *src,
64 dest_mode)) 64 dest_mode))
65 continue; 65 continue;
66 66
67 __set_bit(i, deliver_bitmask); 67 if (!low_prio) {
68 __set_bit(i, deliver_bitmask);
69 } else {
70 if (lowest < 0)
71 lowest = i;
72 if (kvm_apic_compare_prio(vcpu, kvm->vcpus[lowest]) < 0)
73 lowest = i;
74 }
68 } 75 }
69 76
70 if (low_prio) { 77 if (lowest != -1)
71 vcpu = kvm_get_lowest_prio_vcpu(kvm, 0, deliver_bitmask); 78 __set_bit(lowest, deliver_bitmask);
72 bitmap_zero(deliver_bitmask, KVM_MAX_VCPUS);
73 if (vcpu)
74 __set_bit(vcpu->vcpu_id, deliver_bitmask);
75 }
76} 79}
77 80
78static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, 81static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,