diff mbox

[v3,2/2] kvm: x86: Deliver MSI IRQ to only lowest prio cpu if msi_redir_hint is true

Message ID 1426555822-3280-3-git-send-email-sullivan.james.f@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

James Sullivan March 17, 2015, 1:30 a.m. UTC
An MSI interrupt should only be delivered to the lowest priority CPU
when it has RH=1, regardless of the delivery mode. Modified
kvm_is_dm_lowest_prio() to check for either irq->delivery_mode == APIC_DM_LOWPRI
or irq->msi_redir_hint.

Moved kvm_is_dm_lowest_prio() into lapic.h and renamed to
kvm_lowest_prio_delivery().

Changed a check in kvm_irq_delivery_to_apic_fast() from
irq->delivery_mode == APIC_DM_LOWPRI to kvm_is_dm_lowest_prio().

Signed-off-by: James Sullivan <sullivan.james.f@gmail.com>
---
Changes since v1:
    * Squashed a number of smaller commits into this one commit,
        which implements MSI delivery to only the lowest-priority
        CPU whenever RH=1 using the above helper
        kvm_lowest_prio_delivery().
Changes since v2:
    * Patch formatting

 arch/x86/kvm/irq_comm.c | 11 ++++-------
 arch/x86/kvm/lapic.c    |  3 +--
 arch/x86/kvm/lapic.h    |  6 ++++++
 3 files changed, 11 insertions(+), 9 deletions(-)

Comments

Radim Krčmář March 17, 2015, 2:18 p.m. UTC | #1
2015-03-16 19:30-0600, James Sullivan:
> An MSI interrupt should only be delivered to the lowest priority CPU
> when it has RH=1, regardless of the delivery mode. Modified
> kvm_is_dm_lowest_prio() to check for either irq->delivery_mode == APIC_DM_LOWPRI
> or irq->msi_redir_hint.
> 
> Moved kvm_is_dm_lowest_prio() into lapic.h and renamed to
> kvm_lowest_prio_delivery().
> 
> Changed a check in kvm_irq_delivery_to_apic_fast() from
> irq->delivery_mode == APIC_DM_LOWPRI to kvm_is_dm_lowest_prio().
> 
> Signed-off-by: James Sullivan <sullivan.james.f@gmail.com>
> ---

Reviewed-by: Radim Kr?má? <rkrcmar@redhat.com>

> diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
> @@ -31,6 +31,8 @@
>  #include "ioapic.h"
>  
> +#include "lapic.h"
> +

(No need for the empty line between them.)

> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> @@ -701,8 +701,7 @@ bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src,
>  		dst = map->logical_map[cid];
>  
>  		bitmap = apic_logical_id(map, mda);
> -

(It's polite to preserve blank lines.)

> -		if (irq->delivery_mode == APIC_DM_LOWEST) {
> +		if (kvm_lowest_prio_delivery(irq)) {

lapic.c does not directly include lapic.h, (gets pulled via irq.h)
it would be nicer to fix it here, but can also be done later ...

> diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
> @@ -168,6 +168,12 @@ static inline bool kvm_apic_has_events(struct kvm_vcpu *vcpu)
> +static inline bool kvm_lowest_prio_delivery(struct kvm_lapic_irq *irq)
> +{
> +	return (irq->delivery_mode == APIC_DM_LOWEST ||
> +			irq->msi_redir_hint);

(These parentheses improve readability?)
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
index 5c33cca..69cdaab 100644
--- a/arch/x86/kvm/irq_comm.c
+++ b/arch/x86/kvm/irq_comm.c
@@ -31,6 +31,8 @@ 
 
 #include "ioapic.h"
 
+#include "lapic.h"
+
 static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
 			   struct kvm *kvm, int irq_source_id, int level,
 			   bool line_status)
@@ -48,11 +50,6 @@  static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
 				line_status);
 }
 
-inline static bool kvm_is_dm_lowest_prio(struct kvm_lapic_irq *irq)
-{
-	return irq->delivery_mode == APIC_DM_LOWEST;
-}
-
 int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
 		struct kvm_lapic_irq *irq, unsigned long *dest_map)
 {
@@ -60,7 +57,7 @@  int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
 	struct kvm_vcpu *vcpu, *lowest = NULL;
 
 	if (irq->dest_mode == 0 && irq->dest_id == 0xff &&
-			kvm_is_dm_lowest_prio(irq)) {
+			kvm_lowest_prio_delivery(irq)) {
 		printk(KERN_INFO "kvm: apic: phys broadcast and lowest prio\n");
 		irq->delivery_mode = APIC_DM_FIXED;
 	}
@@ -76,7 +73,7 @@  int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
 					irq->dest_id, irq->dest_mode))
 			continue;
 
-		if (!kvm_is_dm_lowest_prio(irq)) {
+		if (!kvm_lowest_prio_delivery(irq)) {
 			if (r < 0)
 				r = 0;
 			r += kvm_apic_set_irq(vcpu, irq, dest_map);
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index a15c444..f8b21d5 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -701,8 +701,7 @@  bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src,
 		dst = map->logical_map[cid];
 
 		bitmap = apic_logical_id(map, mda);
-
-		if (irq->delivery_mode == APIC_DM_LOWEST) {
+		if (kvm_lowest_prio_delivery(irq)) {
 			int l = -1;
 			for_each_set_bit(i, &bitmap, 16) {
 				if (!dst[i])
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 0bc6c65..ed7e2fa 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -168,6 +168,12 @@  static inline bool kvm_apic_has_events(struct kvm_vcpu *vcpu)
 	return vcpu->arch.apic->pending_events;
 }
 
+static inline bool kvm_lowest_prio_delivery(struct kvm_lapic_irq *irq)
+{
+	return (irq->delivery_mode == APIC_DM_LOWEST ||
+			irq->msi_redir_hint);
+}
+
 bool kvm_apic_pending_eoi(struct kvm_vcpu *vcpu, int vector);
 
 void wait_lapic_expire(struct kvm_vcpu *vcpu);