* [PATCH] [APIC] Optimize searching for highest IRR
@ 2009-05-18 8:44 Gleb Natapov
2009-05-19 10:09 ` Avi Kivity
0 siblings, 1 reply; 2+ messages in thread
From: Gleb Natapov @ 2009-05-18 8:44 UTC (permalink / raw)
To: avi; +Cc: kvm
Most of the time IRR is empty, so instead of scanning the whole IRR on
each VM entry keep a variable that tells us if IRR is not empty. IRR
will have to be scanned twice on each IRQ delivery, but this is much more
rare than VM entry.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
---
arch/x86/kvm/lapic.c | 19 ++++++++++++++++---
arch/x86/kvm/lapic.h | 1 +
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index ae99d83..2c25b07 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -165,24 +165,36 @@ static int find_highest_vector(void *bitmap)
static inline int apic_test_and_set_irr(int vec, struct kvm_lapic *apic)
{
+ apic->irr_pending = true;
return apic_test_and_set_vector(vec, apic->regs + APIC_IRR);
}
-static inline void apic_clear_irr(int vec, struct kvm_lapic *apic)
+static inline int apic_search_irr(struct kvm_lapic *apic)
{
- apic_clear_vector(vec, apic->regs + APIC_IRR);
+ return find_highest_vector(apic->regs + APIC_IRR);
}
static inline int apic_find_highest_irr(struct kvm_lapic *apic)
{
int result;
- result = find_highest_vector(apic->regs + APIC_IRR);
+ if (!apic->irr_pending)
+ return -1;
+
+ result = apic_search_irr(apic);
ASSERT(result == -1 || result >= 16);
return result;
}
+static inline void apic_clear_irr(int vec, struct kvm_lapic *apic)
+{
+ apic->irr_pending = false;
+ apic_clear_vector(vec, apic->regs + APIC_IRR);
+ if (apic_search_irr(apic) != -1)
+ apic->irr_pending = true;
+}
+
int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu)
{
struct kvm_lapic *apic = vcpu->arch.apic;
@@ -842,6 +854,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
apic_set_reg(apic, APIC_ISR + 0x10 * i, 0);
apic_set_reg(apic, APIC_TMR + 0x10 * i, 0);
}
+ apic->irr_pending = false;
update_divide_count(apic);
atomic_set(&apic->lapic_timer.pending, 0);
if (vcpu->vcpu_id == 0)
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index a587f83..3f3ecc6 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -12,6 +12,7 @@ struct kvm_lapic {
struct kvm_timer lapic_timer;
u32 divide_count;
struct kvm_vcpu *vcpu;
+ bool irr_pending;
struct page *regs_page;
void *regs;
gpa_t vapic_addr;
--
1.6.2.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] [APIC] Optimize searching for highest IRR
2009-05-18 8:44 [PATCH] [APIC] Optimize searching for highest IRR Gleb Natapov
@ 2009-05-19 10:09 ` Avi Kivity
0 siblings, 0 replies; 2+ messages in thread
From: Avi Kivity @ 2009-05-19 10:09 UTC (permalink / raw)
To: Gleb Natapov; +Cc: kvm
Gleb Natapov wrote:
> Most of the time IRR is empty, so instead of scanning the whole IRR on
> each VM entry keep a variable that tells us if IRR is not empty. IRR
> will have to be scanned twice on each IRQ delivery, but this is much more
> rare than VM entry.
>
>
> static inline int apic_find_highest_irr(struct kvm_lapic *apic)
> {
> int result;
>
> - result = find_highest_vector(apic->regs + APIC_IRR);
> + if (!apic->irr_pending)
> + return -1;
>
smp_mb__before_clear_bit(), to prevent the cpu speculating the IRR.
> +
> + result = apic_search_irr(apic);
> ASSERT(result == -1 || result >= 16);
>
> return result;
> }
>
> +static inline void apic_clear_irr(int vec, struct kvm_lapic *apic)
> +{
> + apic->irr_pending = false;
> + apic_clear_vector(vec, apic->regs + APIC_IRR);
>
smp_rmb()
> + if (apic_search_irr(apic) != -1)
> + apic->irr_pending = true;
>
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-05-19 10:09 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-18 8:44 [PATCH] [APIC] Optimize searching for highest IRR Gleb Natapov
2009-05-19 10:09 ` Avi Kivity
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.