aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorSasha Levin <levinsasha928@gmail.com>2011-07-27 09:00:48 -0400
committerAvi Kivity <avi@redhat.com>2011-09-25 12:17:59 -0400
commit743eeb0b01d2fbf4154bf87bff1ebb6fb18aeb7a (patch)
tree5392464930f7e77131d65f32ba96ce4665307629 /include
parent0d460ffc0956d2dbe12ca9f5f6aa0f8701ea9d73 (diff)
KVM: Intelligent device lookup on I/O bus
Currently the method of dealing with an IO operation on a bus (PIO/MMIO) is to call the read or write callback for each device registered on the bus until we find a device which handles it. Since the number of devices on a bus can be significant due to ioeventfds and coalesced MMIO zones, this leads to a lot of overhead on each IO operation. Instead of registering devices, we now register ranges which points to a device. Lookup is done using an efficient bsearch instead of a linear search. Performance test was conducted by comparing exit count per second with 200 ioeventfds created on one byte and the guest is trying to access a different byte continuously (triggering usermode exits). Before the patch the guest has achieved 259k exits per second, after the patch the guest does 274k exits per second. Cc: Avi Kivity <avi@redhat.com> Cc: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Sasha Levin <levinsasha928@gmail.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/kvm_host.h18
1 files changed, 9 insertions, 9 deletions
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index ff4d4062af9d..d0e42f30edf6 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -55,16 +55,16 @@ struct kvm;
55struct kvm_vcpu; 55struct kvm_vcpu;
56extern struct kmem_cache *kvm_vcpu_cache; 56extern struct kmem_cache *kvm_vcpu_cache;
57 57
58/* 58struct kvm_io_range {
59 * It would be nice to use something smarter than a linear search, TBD... 59 gpa_t addr;
60 * Thankfully we dont expect many devices to register (famous last words :), 60 int len;
61 * so until then it will suffice. At least its abstracted so we can change 61 struct kvm_io_device *dev;
62 * in one place. 62};
63 */ 63
64struct kvm_io_bus { 64struct kvm_io_bus {
65 int dev_count; 65 int dev_count;
66#define NR_IOBUS_DEVS 300 66#define NR_IOBUS_DEVS 300
67 struct kvm_io_device *devs[NR_IOBUS_DEVS]; 67 struct kvm_io_range range[NR_IOBUS_DEVS];
68}; 68};
69 69
70enum kvm_bus { 70enum kvm_bus {
@@ -77,8 +77,8 @@ int kvm_io_bus_write(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
77 int len, const void *val); 77 int len, const void *val);
78int kvm_io_bus_read(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, int len, 78int kvm_io_bus_read(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, int len,
79 void *val); 79 void *val);
80int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, 80int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
81 struct kvm_io_device *dev); 81 int len, struct kvm_io_device *dev);
82int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx, 82int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
83 struct kvm_io_device *dev); 83 struct kvm_io_device *dev);
84 84