All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] use eoi to track RTC interrupt delivery status
@ 2013-03-15  8:04 Yang Zhang
  2013-03-15  8:04 ` [PATCH 1/5] KVM: parse ioapic entry to get destination vcpu Yang Zhang
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Yang Zhang @ 2013-03-15  8:04 UTC (permalink / raw
  To: kvm; +Cc: gleb, mtosatti, xiantao.zhang, avi.kivity, Yang Zhang

From: Yang Zhang <yang.z.zhang@Intel.com>

Current interrupt coalescing logci which only used by RTC has conflict
with Posted Interrupt.

This patch introduces a new mechinism to use eoi to track interrupt:
When delivering an interrupt to vcpu, the need_eoi set to number of
vcpu that received the interrupt. And decrease it when each vcpu writing
eoi. No subsequent RTC interrupt can deliver to vcpu until all vcpus
write eoi.

Yang Zhang (5):
  KVM: parse ioapic entry to get destination vcpu
  KVM: add vcpu info to ioapic_update_eoi()
  KVM: introduce struct rtc_status
  KVM: register rtc eoi notifier
  KVM: use eoi to track RTC interrupt delivery status

 arch/x86/kvm/lapic.c |   44 +++++++++------
 arch/x86/kvm/lapic.h |    4 ++
 virt/kvm/ioapic.c    |  143 +++++++++++++++++++++++++++++++++++++++++++++++--
 virt/kvm/ioapic.h    |   12 ++++-
 4 files changed, 178 insertions(+), 25 deletions(-)


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/5] KVM: parse ioapic entry to get destination vcpu
  2013-03-15  8:04 [PATCH 0/5] use eoi to track RTC interrupt delivery status Yang Zhang
@ 2013-03-15  8:04 ` Yang Zhang
  2013-03-15  8:04 ` [PATCH 2/5] KVM: add vcpu info to ioapic_update_eoi() Yang Zhang
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Yang Zhang @ 2013-03-15  8:04 UTC (permalink / raw
  To: kvm; +Cc: gleb, mtosatti, xiantao.zhang, avi.kivity, Yang Zhang

From: Yang Zhang <yang.z.zhang@Intel.com>

Introduce new function kvm_get_dest_vcpu() to parse ioapic entry to get
destionation vcpu bitmap.

Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com>
---
 arch/x86/kvm/lapic.c |   40 ++++++++++++++++++++++++----------------
 arch/x86/kvm/lapic.h |    3 +++
 2 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 02b51dd..b4339a5 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -145,28 +145,26 @@ static inline int kvm_apic_id(struct kvm_lapic *apic)
 	return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
 }
 
-void kvm_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
-				struct kvm_lapic_irq *irq,
-				u64 *eoi_exit_bitmap)
+void kvm_get_dest_vcpu(struct kvm *kvm, struct kvm_lapic_irq *irq,
+				unsigned long *vcpu_map)
 {
 	struct kvm_lapic **dst;
 	struct kvm_apic_map *map;
 	unsigned long bitmap = 1;
+	struct kvm_vcpu *vcpu;
 	int i;
 
 	rcu_read_lock();
-	map = rcu_dereference(vcpu->kvm->arch.apic_map);
+	map = rcu_dereference(kvm->arch.apic_map);
 
-	if (unlikely(!map)) {
-		__set_bit(irq->vector, (unsigned long *)eoi_exit_bitmap);
+	if (unlikely(!map))
 		goto out;
-	}
 
 	if (irq->dest_mode == 0) { /* physical mode */
-		if (irq->delivery_mode == APIC_DM_LOWEST ||
-				irq->dest_id == 0xff) {
-			__set_bit(irq->vector,
-				  (unsigned long *)eoi_exit_bitmap);
+		if (irq->dest_id == 0xff) {
+			kvm_for_each_vcpu(i, vcpu, kvm)
+				if (apic_enabled(vcpu->arch.apic))
+					set_bit(vcpu->vcpu_id, vcpu_map);
 			goto out;
 		}
 		dst = &map->phys_map[irq->dest_id & 0xff];
@@ -181,17 +179,27 @@ void kvm_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
 	for_each_set_bit(i, &bitmap, 16) {
 		if (!dst[i])
 			continue;
-		if (dst[i]->vcpu == vcpu) {
-			__set_bit(irq->vector,
-				  (unsigned long *)eoi_exit_bitmap);
-			break;
-		}
+		set_bit(dst[i]->vcpu->vcpu_id, vcpu_map);
 	}
 
 out:
 	rcu_read_unlock();
 }
 
+void kvm_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
+				struct kvm_lapic_irq *irq,
+				u64 *eoi_exit_bitmap)
+{
+	DECLARE_BITMAP(vcpu_map, KVM_MAX_VCPUS);
+
+	memset(vcpu_map, 0, sizeof(vcpu_map));
+
+	kvm_get_dest_vcpu(vcpu->kvm, irq, vcpu_map);
+	if (test_bit(vcpu->vcpu_id, vcpu_map) ||
+			bitmap_empty(vcpu_map, sizeof(vcpu_map)))
+		__set_bit(irq->vector, (unsigned long *)eoi_exit_bitmap);
+}
+
 static void recalculate_apic_map(struct kvm *kvm)
 {
 	struct kvm_apic_map *new, *old = NULL;
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 1676d34..3a0f9d8 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -158,4 +158,7 @@ void kvm_calculate_eoi_exitmap(struct kvm_vcpu *vcpu,
 				struct kvm_lapic_irq *irq,
 				u64 *eoi_bitmap);
 
+void kvm_get_dest_vcpu(struct kvm *kvm, struct kvm_lapic_irq *irq,
+				unsigned long *vcpu_map);
+
 #endif
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/5] KVM: add vcpu info to ioapic_update_eoi()
  2013-03-15  8:04 [PATCH 0/5] use eoi to track RTC interrupt delivery status Yang Zhang
  2013-03-15  8:04 ` [PATCH 1/5] KVM: parse ioapic entry to get destination vcpu Yang Zhang
@ 2013-03-15  8:04 ` Yang Zhang
  2013-03-15  8:04 ` [PATCH 3/5] KVM: introduce struct rtc_status Yang Zhang
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Yang Zhang @ 2013-03-15  8:04 UTC (permalink / raw
  To: kvm; +Cc: gleb, mtosatti, xiantao.zhang, avi.kivity, Yang Zhang

From: Yang Zhang <yang.z.zhang@Intel.com>

Add vcpu info for ioapic when handling eoi.

Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com>
---
 arch/x86/kvm/lapic.c |    2 +-
 virt/kvm/ioapic.c    |   12 ++++++------
 virt/kvm/ioapic.h    |    3 ++-
 3 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index b4339a5..ad97f1f 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -790,7 +790,7 @@ static void kvm_ioapic_send_eoi(struct kvm_lapic *apic, int vector)
 			trigger_mode = IOAPIC_LEVEL_TRIG;
 		else
 			trigger_mode = IOAPIC_EDGE_TRIG;
-		kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode);
+		kvm_ioapic_update_eoi(apic->vcpu, vector, trigger_mode);
 	}
 }
 
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index ce82b94..ed6f111 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -264,8 +264,8 @@ void kvm_ioapic_clear_all(struct kvm_ioapic *ioapic, int irq_source_id)
 	spin_unlock(&ioapic->lock);
 }
 
-static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int vector,
-				     int trigger_mode)
+static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu,
+			struct kvm_ioapic *ioapic, int vector, int trigger_mode)
 {
 	int i;
 
@@ -304,12 +304,12 @@ bool kvm_ioapic_handles_vector(struct kvm *kvm, int vector)
 	return test_bit(vector, ioapic->handled_vectors);
 }
 
-void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode)
+void kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, int vector, int trigger_mode)
 {
-	struct kvm_ioapic *ioapic = kvm->arch.vioapic;
+	struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
 
 	spin_lock(&ioapic->lock);
-	__kvm_ioapic_update_eoi(ioapic, vector, trigger_mode);
+	__kvm_ioapic_update_eoi(vcpu, ioapic, vector, trigger_mode);
 	spin_unlock(&ioapic->lock);
 }
 
@@ -407,7 +407,7 @@ static int ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len,
 		break;
 #ifdef	CONFIG_IA64
 	case IOAPIC_REG_EOI:
-		__kvm_ioapic_update_eoi(ioapic, data, IOAPIC_LEVEL_TRIG);
+		__kvm_ioapic_update_eoi(NULL, ioapic, data, IOAPIC_LEVEL_TRIG);
 		break;
 #endif
 
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h
index 0400a46..2fc61a5 100644
--- a/virt/kvm/ioapic.h
+++ b/virt/kvm/ioapic.h
@@ -70,7 +70,8 @@ static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm)
 int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
 		int short_hand, int dest, int dest_mode);
 int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2);
-void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode);
+void kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, int vector,
+			int trigger_mode);
 bool kvm_ioapic_handles_vector(struct kvm *kvm, int vector);
 int kvm_ioapic_init(struct kvm *kvm);
 void kvm_ioapic_destroy(struct kvm *kvm);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/5] KVM: introduce struct rtc_status
  2013-03-15  8:04 [PATCH 0/5] use eoi to track RTC interrupt delivery status Yang Zhang
  2013-03-15  8:04 ` [PATCH 1/5] KVM: parse ioapic entry to get destination vcpu Yang Zhang
  2013-03-15  8:04 ` [PATCH 2/5] KVM: add vcpu info to ioapic_update_eoi() Yang Zhang
@ 2013-03-15  8:04 ` Yang Zhang
  2013-03-15  8:04 ` [PATCH 4/5] KVM: register rtc eoi notifier Yang Zhang
  2013-03-15  8:05 ` [PATCH 5/5] KVM: use eoi to track RTC interrupt delivery status Yang Zhang
  4 siblings, 0 replies; 10+ messages in thread
From: Yang Zhang @ 2013-03-15  8:04 UTC (permalink / raw
  To: kvm; +Cc: gleb, mtosatti, xiantao.zhang, avi.kivity, Yang Zhang

From: Yang Zhang <yang.z.zhang@Intel.com>

New rtc_status structure to record rtc irq info.

Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com>
---
 virt/kvm/ioapic.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h
index 2fc61a5..2aea926 100644
--- a/virt/kvm/ioapic.h
+++ b/virt/kvm/ioapic.h
@@ -34,6 +34,12 @@ struct kvm_vcpu;
 #define	IOAPIC_INIT			0x5
 #define	IOAPIC_EXTINT			0x7
 
+struct rtc_status {
+	int need_eoi;
+	DECLARE_BITMAP(vcpu_map, KVM_MAX_VCPUS);
+	struct kvm_irq_ack_notifier irq_ack_notifier;
+};
+
 struct kvm_ioapic {
 	u64 base_address;
 	u32 ioregsel;
@@ -47,6 +53,9 @@ struct kvm_ioapic {
 	void (*ack_notifier)(void *opaque, int irq);
 	spinlock_t lock;
 	DECLARE_BITMAP(handled_vectors, 256);
+#ifdef CONFIG_X86
+	struct rtc_status rtc_status;
+#endif
 };
 
 #ifdef DEBUG
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/5] KVM: register rtc eoi notifier
  2013-03-15  8:04 [PATCH 0/5] use eoi to track RTC interrupt delivery status Yang Zhang
                   ` (2 preceding siblings ...)
  2013-03-15  8:04 ` [PATCH 3/5] KVM: introduce struct rtc_status Yang Zhang
@ 2013-03-15  8:04 ` Yang Zhang
  2013-03-17 10:19   ` Gleb Natapov
  2013-03-15  8:05 ` [PATCH 5/5] KVM: use eoi to track RTC interrupt delivery status Yang Zhang
  4 siblings, 1 reply; 10+ messages in thread
From: Yang Zhang @ 2013-03-15  8:04 UTC (permalink / raw
  To: kvm; +Cc: gleb, mtosatti, xiantao.zhang, avi.kivity, Yang Zhang

From: Yang Zhang <yang.z.zhang@Intel.com>

when virtual interrupt delivery avaliable, register a rtc eoi notifier
to force vmexit when writing eoi for rtc interupt

Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com>
---
 virt/kvm/ioapic.c |   26 ++++++++++++++++++++++++++
 1 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index ed6f111..2c6235c 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -87,6 +87,30 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
 	return result;
 }
 
+#ifdef CONFIG_X86
+static void kvm_rtc_ack_irq(struct kvm_irq_ack_notifier *kian)
+{
+	return;
+}
+
+static void rtc_register_notifier(struct kvm_ioapic *ioapic)
+{
+	if (!kvm_apic_vid_enabled(ioapic->kvm))
+		return;
+
+	ioapic->rtc_status.irq_ack_notifier.gsi = 8;
+	ioapic->rtc_status.irq_ack_notifier.irq_acked = kvm_rtc_ack_irq;
+	kvm_register_irq_ack_notifier(ioapic->kvm,
+				&ioapic->rtc_status.irq_ack_notifier);
+}
+#else
+
+static void rtc_register_notifier(struct kvm_ioapic *ioapic)
+{
+	return;
+}
+#endif
+
 static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx)
 {
 	union kvm_ioapic_redirect_entry *pent;
@@ -458,6 +482,8 @@ int kvm_ioapic_init(struct kvm *kvm)
 		kfree(ioapic);
 	}
 
+	rtc_register_notifier(ioapic);
+
 	return ret;
 }
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/5] KVM: use eoi to track RTC interrupt delivery status
  2013-03-15  8:04 [PATCH 0/5] use eoi to track RTC interrupt delivery status Yang Zhang
                   ` (3 preceding siblings ...)
  2013-03-15  8:04 ` [PATCH 4/5] KVM: register rtc eoi notifier Yang Zhang
@ 2013-03-15  8:05 ` Yang Zhang
  2013-03-17 10:28   ` Gleb Natapov
  4 siblings, 1 reply; 10+ messages in thread
From: Yang Zhang @ 2013-03-15  8:05 UTC (permalink / raw
  To: kvm; +Cc: gleb, mtosatti, xiantao.zhang, avi.kivity, Yang Zhang

From: Yang Zhang <yang.z.zhang@Intel.com>

Current interrupt coalescing logci which only used by RTC has conflict
with Posted Interrupt.
This patch introduces a new mechinism to use eoi to track interrupt:
When delivering an interrupt to vcpu, the need_eoi set to number of
vcpu that received the interrupt. And decrease it when each vcpu writing
eoi. No subsequent RTC interrupt can deliver to vcpu until all vcpus
write eoi.

Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com>
---
 arch/x86/kvm/lapic.c |    2 +-
 arch/x86/kvm/lapic.h |    1 +
 virt/kvm/ioapic.c    |  105 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 107 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index ad97f1f..bf2d208 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -89,7 +89,7 @@ static inline int apic_test_and_clear_vector(int vec, void *bitmap)
 	return test_and_clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
 }
 
-static inline int apic_test_vector(int vec, void *bitmap)
+int apic_test_vector(int vec, void *bitmap)
 {
 	return test_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
 }
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 3a0f9d8..02da8b8 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -84,6 +84,7 @@ static inline bool kvm_hv_vapic_assist_page_enabled(struct kvm_vcpu *vcpu)
 
 int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data);
 void kvm_lapic_init(void);
+int apic_test_vector(int vec, void *bitmap);
 
 static inline u32 kvm_apic_get_reg(struct kvm_lapic *apic, int reg_off)
 {
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index 2c6235c..46cb8ed 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -103,12 +103,110 @@ static void rtc_register_notifier(struct kvm_ioapic *ioapic)
 	kvm_register_irq_ack_notifier(ioapic->kvm,
 				&ioapic->rtc_status.irq_ack_notifier);
 }
+
+static void rtc_irq_reset(struct kvm_ioapic *ioapic)
+{
+	ioapic->rtc_status.need_eoi = 0;
+	bitmap_zero(ioapic->rtc_status.vcpu_map, KVM_MAX_VCPUS);
+}
+
+static void rtc_irq_restore(struct kvm_ioapic *ioapic)
+{
+	struct kvm_vcpu *vcpu;
+	struct kvm_lapic *apic;
+	int vector, i, need_eoi = 0, rtc_pin = 8;
+
+	vector = ioapic->redirtbl[rtc_pin].fields.vector;
+	kvm_for_each_vcpu(i, vcpu, ioapic->kvm) {
+		apic = vcpu->arch.apic;
+		if (apic_test_vector(vector, apic->regs + APIC_ISR) ||
+			    apic_test_vector(vector, apic->regs + APIC_IRR)) {
+			need_eoi++;
+			set_bit(vcpu->vcpu_id, ioapic->rtc_status.vcpu_map);
+		}
+	}
+	ioapic->rtc_status.need_eoi = need_eoi;
+}
+
+static void rtc_irq_update(struct kvm_ioapic *ioapic,
+		struct kvm_lapic_irq *irqe, int irq)
+{
+	int weight;
+
+	if (irq != 8)
+		return;
+
+	rtc_irq_reset(ioapic);
+
+	kvm_get_dest_vcpu(ioapic->kvm, irqe, ioapic->rtc_status.vcpu_map);
+	if (likely(!bitmap_empty(ioapic->rtc_status.vcpu_map, KVM_MAX_VCPUS))) {
+		if (irqe->delivery_mode == APIC_DM_LOWEST)
+			ioapic->rtc_status.need_eoi = 1;
+		else {
+			weight = bitmap_weight(ioapic->rtc_status.vcpu_map,
+					sizeof(ioapic->rtc_status.vcpu_map));
+			ioapic->rtc_status.need_eoi = weight;
+		}
+	}
+}
+
+static void rtc_irq_ack_eoi(struct kvm_vcpu *vcpu,
+			struct rtc_status *rtc_status, int irq)
+{
+	if (irq != 8)
+		return;
+
+	if (test_and_clear_bit(vcpu->vcpu_id, rtc_status->vcpu_map)) {
+		if (!(--rtc_status->need_eoi))
+			/* Clear irr to accept subsequent RTC interrupt */
+			vcpu->kvm->arch.vioapic->irr &= ~(1 << 8);
+	}
+}
+
+static bool rtc_irq_check(struct kvm_ioapic *ioapic, int irq)
+{
+	if (irq != 8)
+		return false;
+
+	if (ioapic->rtc_status.need_eoi > 0)
+		return true; /* coalesced */
+
+	return false;
+}
+
 #else
 
 static void rtc_register_notifier(struct kvm_ioapic *ioapic)
 {
 	return;
 }
+
+static void rtc_irq_reset(struct kvm_ioapic *ioapic)
+{
+	return;
+}
+
+static void rtc_irq_restore(struct kvm_ioapic *ioapic)
+{
+	return;
+}
+
+static void rtc_irq_update(struct kvm_ioapic *ioapic,
+		struct kvm_lapic_irq *irqe, int irq)
+{
+	return;
+}
+
+static void rtc_irq_ack_eoi(struct kvm_vcpu *vcpu,
+			struct rtc_status *rtc_status, int irq)
+{
+	return;
+}
+
+static bool rtc_irq_check(struct kvm_ioapic *ioapic, int irq)
+{
+	return false;
+}
 #endif
 
 static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx)
@@ -119,6 +217,8 @@ static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx)
 	pent = &ioapic->redirtbl[idx];
 
 	if (!pent->fields.mask) {
+		if (rtc_irq_check(ioapic, idx))
+			return 0; /* coalesced */
 		injected = ioapic_deliver(ioapic, idx);
 		if (injected && pent->fields.trig_mode == IOAPIC_LEVEL_TRIG)
 			pent->fields.remote_irr = 1;
@@ -241,6 +341,8 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
 	irqe.level = 1;
 	irqe.shorthand = 0;
 
+	rtc_irq_update(ioapic, &irqe, irq);
+
 	return kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe);
 }
 
@@ -299,6 +401,7 @@ static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu,
 		if (ent->fields.vector != vector)
 			continue;
 
+		rtc_irq_ack_eoi(vcpu, &ioapic->rtc_status, i);
 		/*
 		 * We are dropping lock while calling ack notifiers because ack
 		 * notifier callbacks for assigned devices call into IOAPIC
@@ -452,6 +555,7 @@ void kvm_ioapic_reset(struct kvm_ioapic *ioapic)
 	ioapic->ioregsel = 0;
 	ioapic->irr = 0;
 	ioapic->id = 0;
+	rtc_irq_reset(ioapic);
 	update_handled_vectors(ioapic);
 }
 
@@ -519,6 +623,7 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
 	spin_lock(&ioapic->lock);
 	memcpy(ioapic, state, sizeof(struct kvm_ioapic_state));
 	update_handled_vectors(ioapic);
+	rtc_irq_restore(ioapic);
 	kvm_ioapic_make_eoibitmap_request(kvm);
 	spin_unlock(&ioapic->lock);
 	return 0;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/5] KVM: register rtc eoi notifier
  2013-03-15  8:04 ` [PATCH 4/5] KVM: register rtc eoi notifier Yang Zhang
@ 2013-03-17 10:19   ` Gleb Natapov
  0 siblings, 0 replies; 10+ messages in thread
From: Gleb Natapov @ 2013-03-17 10:19 UTC (permalink / raw
  To: Yang Zhang; +Cc: kvm, mtosatti, xiantao.zhang, avi.kivity

On Fri, Mar 15, 2013 at 04:04:59PM +0800, Yang Zhang wrote:
> From: Yang Zhang <yang.z.zhang@Intel.com>
> 
> when virtual interrupt delivery avaliable, register a rtc eoi notifier
> to force vmexit when writing eoi for rtc interupt
> 
> Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com>
> ---
>  virt/kvm/ioapic.c |   26 ++++++++++++++++++++++++++
>  1 files changed, 26 insertions(+), 0 deletions(-)
> 
> diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
> index ed6f111..2c6235c 100644
> --- a/virt/kvm/ioapic.c
> +++ b/virt/kvm/ioapic.c
> @@ -87,6 +87,30 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
>  	return result;
>  }
>  
> +#ifdef CONFIG_X86
> +static void kvm_rtc_ack_irq(struct kvm_irq_ack_notifier *kian)
> +{
> +	return;
> +}
No need to register fake ack notifier to request EOI exit from APICv.
IOAPIC can do it directly.

> +
> +static void rtc_register_notifier(struct kvm_ioapic *ioapic)
> +{
> +	if (!kvm_apic_vid_enabled(ioapic->kvm))
> +		return;
> +
> +	ioapic->rtc_status.irq_ack_notifier.gsi = 8;
> +	ioapic->rtc_status.irq_ack_notifier.irq_acked = kvm_rtc_ack_irq;
> +	kvm_register_irq_ack_notifier(ioapic->kvm,
> +				&ioapic->rtc_status.irq_ack_notifier);
> +}
> +#else
> +
> +static void rtc_register_notifier(struct kvm_ioapic *ioapic)
> +{
> +	return;
> +}
> +#endif
> +
>  static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx)
>  {
>  	union kvm_ioapic_redirect_entry *pent;
> @@ -458,6 +482,8 @@ int kvm_ioapic_init(struct kvm *kvm)
>  		kfree(ioapic);
>  	}
>  
> +	rtc_register_notifier(ioapic);
> +
>  	return ret;
>  }
>  
> -- 
> 1.7.1

--
			Gleb.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 5/5] KVM: use eoi to track RTC interrupt delivery status
  2013-03-15  8:05 ` [PATCH 5/5] KVM: use eoi to track RTC interrupt delivery status Yang Zhang
@ 2013-03-17 10:28   ` Gleb Natapov
  2013-03-17 13:09     ` Zhang, Yang Z
  0 siblings, 1 reply; 10+ messages in thread
From: Gleb Natapov @ 2013-03-17 10:28 UTC (permalink / raw
  To: Yang Zhang; +Cc: kvm, mtosatti, xiantao.zhang, avi.kivity

On Fri, Mar 15, 2013 at 04:05:00PM +0800, Yang Zhang wrote:
> From: Yang Zhang <yang.z.zhang@Intel.com>
> 
> Current interrupt coalescing logci which only used by RTC has conflict
> with Posted Interrupt.
> This patch introduces a new mechinism to use eoi to track interrupt:
> When delivering an interrupt to vcpu, the need_eoi set to number of
> vcpu that received the interrupt. And decrease it when each vcpu writing
> eoi. No subsequent RTC interrupt can deliver to vcpu until all vcpus
> write eoi.
> 
> Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com>
> ---
>  arch/x86/kvm/lapic.c |    2 +-
>  arch/x86/kvm/lapic.h |    1 +
>  virt/kvm/ioapic.c    |  105 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 107 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> index ad97f1f..bf2d208 100644
> --- a/arch/x86/kvm/lapic.c
> +++ b/arch/x86/kvm/lapic.c
> @@ -89,7 +89,7 @@ static inline int apic_test_and_clear_vector(int vec, void *bitmap)
>  	return test_and_clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
>  }
>  
> -static inline int apic_test_vector(int vec, void *bitmap)
> +int apic_test_vector(int vec, void *bitmap)
>  {
>  	return test_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
>  }
That's too low level to call from IOAPIC. Put kvm_apic_pending_eoi()
here instead.

> diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
> index 3a0f9d8..02da8b8 100644
> --- a/arch/x86/kvm/lapic.h
> +++ b/arch/x86/kvm/lapic.h
> @@ -84,6 +84,7 @@ static inline bool kvm_hv_vapic_assist_page_enabled(struct kvm_vcpu *vcpu)
>  
>  int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data);
>  void kvm_lapic_init(void);
> +int apic_test_vector(int vec, void *bitmap);
>  
>  static inline u32 kvm_apic_get_reg(struct kvm_lapic *apic, int reg_off)
>  {
> diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
> index 2c6235c..46cb8ed 100644
> --- a/virt/kvm/ioapic.c
> +++ b/virt/kvm/ioapic.c
> @@ -103,12 +103,110 @@ static void rtc_register_notifier(struct kvm_ioapic *ioapic)
>  	kvm_register_irq_ack_notifier(ioapic->kvm,
>  				&ioapic->rtc_status.irq_ack_notifier);
>  }
> +
> +static void rtc_irq_reset(struct kvm_ioapic *ioapic)
> +{
> +	ioapic->rtc_status.need_eoi = 0;
> +	bitmap_zero(ioapic->rtc_status.vcpu_map, KVM_MAX_VCPUS);
> +}
> +
> +static void rtc_irq_restore(struct kvm_ioapic *ioapic)
> +{
> +	struct kvm_vcpu *vcpu;
> +	struct kvm_lapic *apic;
> +	int vector, i, need_eoi = 0, rtc_pin = 8;
> +
> +	vector = ioapic->redirtbl[rtc_pin].fields.vector;
> +	kvm_for_each_vcpu(i, vcpu, ioapic->kvm) {
> +		apic = vcpu->arch.apic;
> +		if (apic_test_vector(vector, apic->regs + APIC_ISR) ||
> +			    apic_test_vector(vector, apic->regs + APIC_IRR)) {
> +			need_eoi++;
> +			set_bit(vcpu->vcpu_id, ioapic->rtc_status.vcpu_map);
> +		}
> +	}
> +	ioapic->rtc_status.need_eoi = need_eoi;
> +}
> +
> +static void rtc_irq_update(struct kvm_ioapic *ioapic,
> +		struct kvm_lapic_irq *irqe, int irq)
> +{
> +	int weight;
> +
> +	if (irq != 8)
> +		return;
> +
> +	rtc_irq_reset(ioapic);
> +
> +	kvm_get_dest_vcpu(ioapic->kvm, irqe, ioapic->rtc_status.vcpu_map);
> +	if (likely(!bitmap_empty(ioapic->rtc_status.vcpu_map, KVM_MAX_VCPUS))) {
> +		if (irqe->delivery_mode == APIC_DM_LOWEST)
> +			ioapic->rtc_status.need_eoi = 1;
> +		else {
> +			weight = bitmap_weight(ioapic->rtc_status.vcpu_map,
> +					sizeof(ioapic->rtc_status.vcpu_map));
> +			ioapic->rtc_status.need_eoi = weight;
> +		}
> +	}
> +}
> +
> +static void rtc_irq_ack_eoi(struct kvm_vcpu *vcpu,
> +			struct rtc_status *rtc_status, int irq)
> +{
> +	if (irq != 8)
> +		return;
> +
> +	if (test_and_clear_bit(vcpu->vcpu_id, rtc_status->vcpu_map)) {
> +		if (!(--rtc_status->need_eoi))
WARN_ON(need_eoi < 0)?

> +			/* Clear irr to accept subsequent RTC interrupt */
> +			vcpu->kvm->arch.vioapic->irr &= ~(1 << 8);
This is not needed if you do not set irr if irq is coalesced.

> +	}
> +}
> +
> +static bool rtc_irq_check(struct kvm_ioapic *ioapic, int irq)
> +{
> +	if (irq != 8)
> +		return false;
> +
> +	if (ioapic->rtc_status.need_eoi > 0)
> +		return true; /* coalesced */
> +
> +	return false;
> +}
> +
>  #else
>  
>  static void rtc_register_notifier(struct kvm_ioapic *ioapic)
>  {
>  	return;
>  }
> +
> +static void rtc_irq_reset(struct kvm_ioapic *ioapic)
> +{
> +	return;
> +}
> +
> +static void rtc_irq_restore(struct kvm_ioapic *ioapic)
> +{
> +	return;
> +}
> +
> +static void rtc_irq_update(struct kvm_ioapic *ioapic,
> +		struct kvm_lapic_irq *irqe, int irq)
> +{
> +	return;
> +}
> +
> +static void rtc_irq_ack_eoi(struct kvm_vcpu *vcpu,
> +			struct rtc_status *rtc_status, int irq)
> +{
> +	return;
> +}
> +
> +static bool rtc_irq_check(struct kvm_ioapic *ioapic, int irq)
> +{
> +	return false;
> +}
>  #endif
>  
>  static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx)
> @@ -119,6 +217,8 @@ static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx)
>  	pent = &ioapic->redirtbl[idx];
>  
>  	if (!pent->fields.mask) {
> +		if (rtc_irq_check(ioapic, idx))
> +			return 0; /* coalesced */
>  		injected = ioapic_deliver(ioapic, idx);
>  		if (injected && pent->fields.trig_mode == IOAPIC_LEVEL_TRIG)
>  			pent->fields.remote_irr = 1;
> @@ -241,6 +341,8 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
>  	irqe.level = 1;
>  	irqe.shorthand = 0;
>  
> +	rtc_irq_update(ioapic, &irqe, irq);
> +
Do it once when GSI is configured.

>  	return kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe);
>  }
>  
> @@ -299,6 +401,7 @@ static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu,
>  		if (ent->fields.vector != vector)
>  			continue;
>  
> +		rtc_irq_ack_eoi(vcpu, &ioapic->rtc_status, i);
>  		/*
>  		 * We are dropping lock while calling ack notifiers because ack
>  		 * notifier callbacks for assigned devices call into IOAPIC
> @@ -452,6 +555,7 @@ void kvm_ioapic_reset(struct kvm_ioapic *ioapic)
>  	ioapic->ioregsel = 0;
>  	ioapic->irr = 0;
>  	ioapic->id = 0;
> +	rtc_irq_reset(ioapic);
>  	update_handled_vectors(ioapic);
>  }
>  
> @@ -519,6 +623,7 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
>  	spin_lock(&ioapic->lock);
>  	memcpy(ioapic, state, sizeof(struct kvm_ioapic_state));
>  	update_handled_vectors(ioapic);
> +	rtc_irq_restore(ioapic);
>  	kvm_ioapic_make_eoibitmap_request(kvm);
>  	spin_unlock(&ioapic->lock);
>  	return 0;
> -- 
> 1.7.1

--
			Gleb.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH 5/5] KVM: use eoi to track RTC interrupt delivery status
  2013-03-17 10:28   ` Gleb Natapov
@ 2013-03-17 13:09     ` Zhang, Yang Z
  2013-03-17 14:00       ` Gleb Natapov
  0 siblings, 1 reply; 10+ messages in thread
From: Zhang, Yang Z @ 2013-03-17 13:09 UTC (permalink / raw
  To: Gleb Natapov
  Cc: kvm@vger.kernel.org, mtosatti@redhat.com, Zhang, Xiantao,
	avi.kivity@gmail.com

Gleb Natapov wrote on 2013-03-17:
> On Fri, Mar 15, 2013 at 04:05:00PM +0800, Yang Zhang wrote:
>> From: Yang Zhang <yang.z.zhang@Intel.com>
>> 
>> Current interrupt coalescing logci which only used by RTC has conflict
>> with Posted Interrupt.
>> This patch introduces a new mechinism to use eoi to track interrupt:
>> When delivering an interrupt to vcpu, the need_eoi set to number of
>> vcpu that received the interrupt. And decrease it when each vcpu writing
>> eoi. No subsequent RTC interrupt can deliver to vcpu until all vcpus
>> write eoi.
>> 
>> Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com>
>> ---
>>  arch/x86/kvm/lapic.c |    2 +- arch/x86/kvm/lapic.h |    1 +
>>  virt/kvm/ioapic.c    |  105
>>  ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed,
>>  107 insertions(+), 1 deletions(-)
>> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
>> index ad97f1f..bf2d208 100644
>> --- a/arch/x86/kvm/lapic.c
>> +++ b/arch/x86/kvm/lapic.c
>> @@ -89,7 +89,7 @@ static inline int apic_test_and_clear_vector(int vec, void
> *bitmap)
>>  	return test_and_clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
>>  }
>> -static inline int apic_test_vector(int vec, void *bitmap)
>> +int apic_test_vector(int vec, void *bitmap)
>>  {
>>  	return test_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
>>  }
> That's too low level to call from IOAPIC. Put kvm_apic_pending_eoi()
> here instead.
> 
>> diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index
>> 3a0f9d8..02da8b8 100644 --- a/arch/x86/kvm/lapic.h +++
>> b/arch/x86/kvm/lapic.h @@ -84,6 +84,7 @@ static inline bool
>> kvm_hv_vapic_assist_page_enabled(struct kvm_vcpu *vcpu)
>> 
>>  int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data);
>>  void kvm_lapic_init(void);
>> +int apic_test_vector(int vec, void *bitmap);
>> 
>>  static inline u32 kvm_apic_get_reg(struct kvm_lapic *apic, int reg_off)
>>  {
>> diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
>> index 2c6235c..46cb8ed 100644
>> --- a/virt/kvm/ioapic.c
>> +++ b/virt/kvm/ioapic.c
>> @@ -103,12 +103,110 @@ static void rtc_register_notifier(struct kvm_ioapic
> *ioapic)
>>  	kvm_register_irq_ack_notifier(ioapic->kvm,
>>  				&ioapic->rtc_status.irq_ack_notifier);
>>  }
>> + +static void rtc_irq_reset(struct kvm_ioapic *ioapic) +{
>> +	ioapic->rtc_status.need_eoi = 0;
>> +	bitmap_zero(ioapic->rtc_status.vcpu_map, KVM_MAX_VCPUS); +} + +static
>> void rtc_irq_restore(struct kvm_ioapic *ioapic) +{ +	struct kvm_vcpu
>> *vcpu; +	struct kvm_lapic *apic; +	int vector, i, need_eoi = 0, rtc_pin
>> = 8; + +	vector = ioapic->redirtbl[rtc_pin].fields.vector;
>> +	kvm_for_each_vcpu(i, vcpu, ioapic->kvm) { +		apic = vcpu->arch.apic;
>> +		if (apic_test_vector(vector, apic->regs + APIC_ISR) || +			   
>> apic_test_vector(vector, apic->regs + APIC_IRR)) { +			need_eoi++;
>> +			set_bit(vcpu->vcpu_id, ioapic->rtc_status.vcpu_map); +		} +	}
>> +	ioapic->rtc_status.need_eoi = need_eoi; +} + +static void
>> rtc_irq_update(struct kvm_ioapic *ioapic, +		struct kvm_lapic_irq
>> *irqe, int irq) +{ +	int weight; + +	if (irq != 8) +		return; +
>> +	rtc_irq_reset(ioapic); + +	kvm_get_dest_vcpu(ioapic->kvm, irqe,
>> ioapic->rtc_status.vcpu_map); +	if
>> (likely(!bitmap_empty(ioapic->rtc_status.vcpu_map, KVM_MAX_VCPUS))) {
>> +		if (irqe->delivery_mode == APIC_DM_LOWEST)
>> +			ioapic->rtc_status.need_eoi = 1; +		else { +			weight =
>> bitmap_weight(ioapic->rtc_status.vcpu_map,
>> +					sizeof(ioapic->rtc_status.vcpu_map));
>> +			ioapic->rtc_status.need_eoi = weight; +		} +	} +} + +static void
>> rtc_irq_ack_eoi(struct kvm_vcpu *vcpu, +			struct rtc_status
>> *rtc_status, int irq) +{ +	if (irq != 8) +		return; + +	if
>> (test_and_clear_bit(vcpu->vcpu_id, rtc_status->vcpu_map)) { +		if
>> (!(--rtc_status->need_eoi))
> WARN_ON(need_eoi < 0)?
> 
>> +			/* Clear irr to accept subsequent RTC interrupt */
>> +			vcpu->kvm->arch.vioapic->irr &= ~(1 << 8);
> This is not needed if you do not set irr if irq is coalesced.
> 
>> +	}
>> +}
>> +
>> +static bool rtc_irq_check(struct kvm_ioapic *ioapic, int irq)
>> +{
>> +	if (irq != 8)
>> +		return false;
>> +
>> +	if (ioapic->rtc_status.need_eoi > 0)
>> +		return true; /* coalesced */
>> +
>> +	return false;
>> +}
>> +
>>  #else
>>  
>>  static void rtc_register_notifier(struct kvm_ioapic *ioapic)
>>  {
>>  	return;
>>  }
>> +
>> +static void rtc_irq_reset(struct kvm_ioapic *ioapic)
>> +{
>> +	return;
>> +}
>> +
>> +static void rtc_irq_restore(struct kvm_ioapic *ioapic)
>> +{
>> +	return;
>> +}
>> +
>> +static void rtc_irq_update(struct kvm_ioapic *ioapic,
>> +		struct kvm_lapic_irq *irqe, int irq)
>> +{
>> +	return;
>> +}
>> +
>> +static void rtc_irq_ack_eoi(struct kvm_vcpu *vcpu,
>> +			struct rtc_status *rtc_status, int irq)
>> +{
>> +	return;
>> +}
>> +
>> +static bool rtc_irq_check(struct kvm_ioapic *ioapic, int irq)
>> +{
>> +	return false;
>> +}
>>  #endif
>>  
>>  static int ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx)
>> @@ -119,6 +217,8 @@ static int ioapic_service(struct kvm_ioapic *ioapic,
> unsigned int idx)
>>  	pent = &ioapic->redirtbl[idx];
>>  
>>  	if (!pent->fields.mask) {
>> +		if (rtc_irq_check(ioapic, idx))
>> +			return 0; /* coalesced */
>>  		injected = ioapic_deliver(ioapic, idx);
>>  		if (injected && pent->fields.trig_mode == IOAPIC_LEVEL_TRIG)
>>  			pent->fields.remote_irr = 1;
>> @@ -241,6 +341,8 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int
> irq)
>>  	irqe.level = 1;
>>  	irqe.shorthand = 0;
>> +	rtc_irq_update(ioapic, &irqe, irq);
>> +
> Do it once when GSI is configured.
This function will set need_eoi to number of CPU received RTC interrupt. When GSI is configured, there is no real interrupt generated and if set need_eoi, no EOI will decrease it. 

>>  	return kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe);
>>  }
>> @@ -299,6 +401,7 @@ static void __kvm_ioapic_update_eoi(struct kvm_vcpu
> *vcpu,
>>  		if (ent->fields.vector != vector)
>>  			continue;
>> +		rtc_irq_ack_eoi(vcpu, &ioapic->rtc_status, i);
>>  		/* 		 * We are dropping lock while calling ack notifiers because ack
>>  		 * notifier callbacks for assigned devices call into IOAPIC @@
>>  -452,6 +555,7 @@ void kvm_ioapic_reset(struct kvm_ioapic *ioapic)
>>  	ioapic->ioregsel = 0; 	ioapic->irr = 0; 	ioapic->id = 0;
>>  +	rtc_irq_reset(ioapic); 	update_handled_vectors(ioapic); }
>> @@ -519,6 +623,7 @@ int kvm_set_ioapic(struct kvm *kvm, struct
> kvm_ioapic_state *state)
>>  	spin_lock(&ioapic->lock); 	memcpy(ioapic, state, sizeof(struct
>>  kvm_ioapic_state)); 	update_handled_vectors(ioapic);
>>  +	rtc_irq_restore(ioapic); 	kvm_ioapic_make_eoibitmap_request(kvm);
>>  	spin_unlock(&ioapic->lock); 	return 0;
>> --
>> 1.7.1
> 
> --
> 			Gleb.
> --
> 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


Best regards,
Yang



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 5/5] KVM: use eoi to track RTC interrupt delivery status
  2013-03-17 13:09     ` Zhang, Yang Z
@ 2013-03-17 14:00       ` Gleb Natapov
  0 siblings, 0 replies; 10+ messages in thread
From: Gleb Natapov @ 2013-03-17 14:00 UTC (permalink / raw
  To: Zhang, Yang Z
  Cc: kvm@vger.kernel.org, mtosatti@redhat.com, Zhang, Xiantao,
	avi.kivity@gmail.com

On Sun, Mar 17, 2013 at 01:09:09PM +0000, Zhang, Yang Z wrote:
> >> @@ -241,6 +341,8 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int
> > irq)
> >>  	irqe.level = 1;
> >>  	irqe.shorthand = 0;
> >> +	rtc_irq_update(ioapic, &irqe, irq);
> >> +
> > Do it once when GSI is configured.
> This function will set need_eoi to number of CPU received RTC interrupt. When GSI is configured, there is no real interrupt generated and if set need_eoi, no EOI will decrease it. 
> 
You made this function do two unrelated things: recalculate vcpu map and
track need_info. Former should be done during GSI configuration, later
here.

--
			Gleb.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2013-03-17 14:00 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-15  8:04 [PATCH 0/5] use eoi to track RTC interrupt delivery status Yang Zhang
2013-03-15  8:04 ` [PATCH 1/5] KVM: parse ioapic entry to get destination vcpu Yang Zhang
2013-03-15  8:04 ` [PATCH 2/5] KVM: add vcpu info to ioapic_update_eoi() Yang Zhang
2013-03-15  8:04 ` [PATCH 3/5] KVM: introduce struct rtc_status Yang Zhang
2013-03-15  8:04 ` [PATCH 4/5] KVM: register rtc eoi notifier Yang Zhang
2013-03-17 10:19   ` Gleb Natapov
2013-03-15  8:05 ` [PATCH 5/5] KVM: use eoi to track RTC interrupt delivery status Yang Zhang
2013-03-17 10:28   ` Gleb Natapov
2013-03-17 13:09     ` Zhang, Yang Z
2013-03-17 14:00       ` Gleb Natapov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.