aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/kvm_host.h
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2010-11-18 12:09:08 -0500
committerAvi Kivity <avi@redhat.com>2011-01-12 04:29:38 -0500
commitbd2b53b20fcd0d6c4c815b54e6d464e34429d3a4 (patch)
tree1f225ea8b74368056bc144de14a1015fa4ebde29 /include/linux/kvm_host.h
parent104f226bfd0a607ca0e804ae4907555374f72cd9 (diff)
KVM: fast-path msi injection with irqfd
Store irq routing table pointer in the irqfd object, and use that to inject MSI directly without bouncing out to a kernel thread. While we touch this structure, rearrange irqfd fields to make fastpath better packed for better cache utilization. This also adds some comments about locking rules and rcu usage in code. Some notes on the design: - Use pointer into the rt instead of copying an entry, to make it possible to use rcu, thus side-stepping locking complexities. We also save some memory this way. - Old workqueue code is still used for level irqs. I don't think we DTRT with level anyway, however, it seems easier to keep the code around as it has been thought through and debugged, and fix level later than rip out and re-instate it later. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Acked-by: Marcelo Tosatti <mtosatti@redhat.com> Acked-by: Gregory Haskins <ghaskins@novell.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'include/linux/kvm_host.h')
-rw-r--r--include/linux/kvm_host.h16
1 files changed, 16 insertions, 0 deletions
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 4bd663d6443d..f17beae3cca0 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -17,6 +17,7 @@
17#include <linux/preempt.h> 17#include <linux/preempt.h>
18#include <linux/msi.h> 18#include <linux/msi.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/rcupdate.h>
20#include <asm/signal.h> 21#include <asm/signal.h>
21 22
22#include <linux/kvm.h> 23#include <linux/kvm.h>
@@ -240,6 +241,10 @@ struct kvm {
240 241
241 struct mutex irq_lock; 242 struct mutex irq_lock;
242#ifdef CONFIG_HAVE_KVM_IRQCHIP 243#ifdef CONFIG_HAVE_KVM_IRQCHIP
244 /*
245 * Update side is protected by irq_lock and,
246 * if configured, irqfds.lock.
247 */
243 struct kvm_irq_routing_table __rcu *irq_routing; 248 struct kvm_irq_routing_table __rcu *irq_routing;
244 struct hlist_head mask_notifier_list; 249 struct hlist_head mask_notifier_list;
245 struct hlist_head irq_ack_notifier_list; 250 struct hlist_head irq_ack_notifier_list;
@@ -511,6 +516,8 @@ void kvm_get_intr_delivery_bitmask(struct kvm_ioapic *ioapic,
511 unsigned long *deliver_bitmask); 516 unsigned long *deliver_bitmask);
512#endif 517#endif
513int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level); 518int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level);
519int kvm_set_msi(struct kvm_kernel_irq_routing_entry *irq_entry, struct kvm *kvm,
520 int irq_source_id, int level);
514void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin); 521void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin);
515void kvm_register_irq_ack_notifier(struct kvm *kvm, 522void kvm_register_irq_ack_notifier(struct kvm *kvm,
516 struct kvm_irq_ack_notifier *kian); 523 struct kvm_irq_ack_notifier *kian);
@@ -652,17 +659,26 @@ static inline void kvm_free_irq_routing(struct kvm *kvm) {}
652void kvm_eventfd_init(struct kvm *kvm); 659void kvm_eventfd_init(struct kvm *kvm);
653int kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags); 660int kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags);
654void kvm_irqfd_release(struct kvm *kvm); 661void kvm_irqfd_release(struct kvm *kvm);
662void kvm_irq_routing_update(struct kvm *, struct kvm_irq_routing_table *);
655int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args); 663int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args);
656 664
657#else 665#else
658 666
659static inline void kvm_eventfd_init(struct kvm *kvm) {} 667static inline void kvm_eventfd_init(struct kvm *kvm) {}
668
660static inline int kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags) 669static inline int kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags)
661{ 670{
662 return -EINVAL; 671 return -EINVAL;
663} 672}
664 673
665static inline void kvm_irqfd_release(struct kvm *kvm) {} 674static inline void kvm_irqfd_release(struct kvm *kvm) {}
675
676static inline void kvm_irq_routing_update(struct kvm *kvm,
677 struct kvm_irq_routing_table *irq_rt)
678{
679 rcu_assign_pointer(kvm->irq_routing, irq_rt);
680}
681
666static inline int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args) 682static inline int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
667{ 683{
668 return -ENOSYS; 684 return -ENOSYS;