From: "Michael S. Tsirkin" <mst@redhat.com>
To: avi@redhat.com, kvm@vger.kernel.org
Subject: [PATCH stub] kvm: caching API for interrupts
Date: Sun, 29 Jul 2012 23:00:58 +0300 [thread overview]
Message-ID: <20120729200058.GA13557@redhat.com> (raw)
I've been looking at adding caching for IRQs so that we don't need to
scan all VCPUs on each interrupt. One issue I had a problem with, is
how the cache structure can be used from both a thread (to fill out the
cache) and interrupt (to actually send if cache is valid).
For now just added a lock field in the cache so we don't need to worry
about this, and with such a lock in place we don't have to worry about
RCU as cache can be invalidated simply under this lock.
For now this just declares the structure and updates the APIs
so it's not intended to be applied, but just to give you
the idea.
Comments, flames wellcome.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
--
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 96c158a..3384b39 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -214,11 +214,28 @@ static inline unsigned long kvm_dirty_bitmap_bytes(struct kvm_memory_slot *memsl
return ALIGN(memslot->npages, BITS_PER_LONG) / 8;
}
+struct kvm_irq_cache {
+ spinlock_t lock;
+ bool valid;
+ struct kvm_vcpu *dest;
+ /* For now we only cache lapic irqs */
+ struct kvm_lapic_irq irq;
+ /* Protected by kvm->irq_cache_lock */
+ struct list_head list;
+};
+
+int kvm_set_irq_and_cache(struct kvm *kvm, int irq_source_id, u32 irq, int level,
+ struct kvm_irq_cache *cache);
+int kvm_set_irq_cached(struct kvm *kvm, struct kvm_irq_cache *cache);
+void kvm_irq_cache_init(struct kvm *kvm, struct kvm_irq_cache *cache);
+void kvm_irq_cache_cleanup(struct kvm_irq_cache *cache);
+
struct kvm_kernel_irq_routing_entry {
u32 gsi;
u32 type;
int (*set)(struct kvm_kernel_irq_routing_entry *e,
- struct kvm *kvm, int irq_source_id, int level);
+ struct kvm *kvm, int irq_source_id, int level,
+ struct kvm_irq_cache *cache);
union {
struct {
unsigned irqchip;
@@ -304,6 +321,8 @@ struct kvm {
struct kvm_irq_routing_table __rcu *irq_routing;
struct hlist_head mask_notifier_list;
struct hlist_head irq_ack_notifier_list;
+ struct mutex irq_cache_lock;
+ struct list_head irq_cache_list;
#endif
#ifdef KVM_ARCH_WANT_MMU_NOTIFIER
@@ -617,7 +636,8 @@ void kvm_get_intr_delivery_bitmask(struct kvm_ioapic *ioapic,
#endif
int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level);
int kvm_set_msi(struct kvm_kernel_irq_routing_entry *irq_entry, struct kvm *kvm,
- int irq_source_id, int level);
+ int irq_source_id, int level,
+ struct kvm_irq_cache *cache);
void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin);
void kvm_register_irq_ack_notifier(struct kvm *kvm,
struct kvm_irq_ack_notifier *kian);
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 7d7e2aa..9622076 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -138,7 +138,7 @@ irqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key)
irq = rcu_dereference(irqfd->irq_entry);
/* An event has been signaled, inject an interrupt */
if (irq)
- kvm_set_msi(irq, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1);
+ kvm_set_msi(irq, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, NULL);
else
schedule_work(&irqfd->inject);
rcu_read_unlock();
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index 5afb431..d92f3d3 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -46,7 +46,8 @@ static inline int kvm_irq_line_state(unsigned long *irq_state,
}
static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
- struct kvm *kvm, int irq_source_id, int level)
+ struct kvm *kvm, int irq_source_id, int level,
+ struct kvm_irq_cache *cache)
{
#ifdef CONFIG_X86
struct kvm_pic *pic = pic_irqchip(kvm);
@@ -59,7 +60,8 @@ static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
}
static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
- struct kvm *kvm, int irq_source_id, int level)
+ struct kvm *kvm, int irq_source_id, int level,
+ struct kvm_irq_cache *cache)
{
struct kvm_ioapic *ioapic = kvm->arch.vioapic;
level = kvm_irq_line_state(&ioapic->irq_states[e->irqchip.pin],
@@ -115,7 +117,8 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
}
int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
- struct kvm *kvm, int irq_source_id, int level)
+ struct kvm *kvm, int irq_source_id, int level,
+ struct kvm_irq_cache *cache)
{
struct kvm_lapic_irq irq;
@@ -149,7 +152,7 @@ int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)
route.msi.address_hi = msi->address_hi;
route.msi.data = msi->data;
- return kvm_set_msi(&route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1);
+ return kvm_set_msi(&route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, NULL);
}
/*
@@ -180,7 +183,7 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level)
while(i--) {
int r;
- r = irq_set[i].set(&irq_set[i], kvm, irq_source_id, level);
+ r = irq_set[i].set(&irq_set[i], kvm, irq_source_id, level, NULL);
if (r < 0)
continue;
next reply other threads:[~2012-07-29 20:00 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-29 20:00 Michael S. Tsirkin [this message]
2012-07-29 20:03 ` [PATCH stub] kvm: caching API for interrupts Paolo Bonzini
2012-07-29 20:29 ` Michael S. Tsirkin
2012-07-30 6:57 ` Paolo Bonzini
2012-07-30 7:09 ` Gleb Natapov
2012-07-30 8:34 ` Avi Kivity
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120729200058.GA13557@redhat.com \
--to=mst@redhat.com \
--cc=avi@redhat.com \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).