diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2012-10-17 12:06:06 -0400 |
---|---|---|
committer | Gleb Natapov <gleb@redhat.com> | 2012-12-05 08:10:53 -0500 |
commit | 78c634402a1825f1f5bef13077f0985f3b8a3212 (patch) | |
tree | 1dac3b54821c39c1b893f0a2db4806dacc917bdc /virt/kvm/assigned-dev.c | |
parent | 01f218803757c9ec1152ac2fd39d03c27c452634 (diff) |
kvm: deliver msi interrupts from irq handler
We can deliver certain interrupts, notably MSI,
from atomic context. Use kvm_set_irq_inatomic,
to implement an irq handler for msi.
This reduces the pressure on scheduler in case
where host and guest irq share a host cpu.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'virt/kvm/assigned-dev.c')
-rw-r--r-- | virt/kvm/assigned-dev.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index 23a41a9f8db9..3642239252b0 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c | |||
@@ -105,6 +105,15 @@ static irqreturn_t kvm_assigned_dev_thread_intx(int irq, void *dev_id) | |||
105 | } | 105 | } |
106 | 106 | ||
107 | #ifdef __KVM_HAVE_MSI | 107 | #ifdef __KVM_HAVE_MSI |
108 | static irqreturn_t kvm_assigned_dev_msi(int irq, void *dev_id) | ||
109 | { | ||
110 | struct kvm_assigned_dev_kernel *assigned_dev = dev_id; | ||
111 | int ret = kvm_set_irq_inatomic(assigned_dev->kvm, | ||
112 | assigned_dev->irq_source_id, | ||
113 | assigned_dev->guest_irq, 1); | ||
114 | return unlikely(ret == -EWOULDBLOCK) ? IRQ_WAKE_THREAD : IRQ_HANDLED; | ||
115 | } | ||
116 | |||
108 | static irqreturn_t kvm_assigned_dev_thread_msi(int irq, void *dev_id) | 117 | static irqreturn_t kvm_assigned_dev_thread_msi(int irq, void *dev_id) |
109 | { | 118 | { |
110 | struct kvm_assigned_dev_kernel *assigned_dev = dev_id; | 119 | struct kvm_assigned_dev_kernel *assigned_dev = dev_id; |
@@ -117,6 +126,23 @@ static irqreturn_t kvm_assigned_dev_thread_msi(int irq, void *dev_id) | |||
117 | #endif | 126 | #endif |
118 | 127 | ||
119 | #ifdef __KVM_HAVE_MSIX | 128 | #ifdef __KVM_HAVE_MSIX |
129 | static irqreturn_t kvm_assigned_dev_msix(int irq, void *dev_id) | ||
130 | { | ||
131 | struct kvm_assigned_dev_kernel *assigned_dev = dev_id; | ||
132 | int index = find_index_from_host_irq(assigned_dev, irq); | ||
133 | u32 vector; | ||
134 | int ret = 0; | ||
135 | |||
136 | if (index >= 0) { | ||
137 | vector = assigned_dev->guest_msix_entries[index].vector; | ||
138 | ret = kvm_set_irq_inatomic(assigned_dev->kvm, | ||
139 | assigned_dev->irq_source_id, | ||
140 | vector, 1); | ||
141 | } | ||
142 | |||
143 | return unlikely(ret == -EWOULDBLOCK) ? IRQ_WAKE_THREAD : IRQ_HANDLED; | ||
144 | } | ||
145 | |||
120 | static irqreturn_t kvm_assigned_dev_thread_msix(int irq, void *dev_id) | 146 | static irqreturn_t kvm_assigned_dev_thread_msix(int irq, void *dev_id) |
121 | { | 147 | { |
122 | struct kvm_assigned_dev_kernel *assigned_dev = dev_id; | 148 | struct kvm_assigned_dev_kernel *assigned_dev = dev_id; |
@@ -334,11 +360,6 @@ static int assigned_device_enable_host_intx(struct kvm *kvm, | |||
334 | } | 360 | } |
335 | 361 | ||
336 | #ifdef __KVM_HAVE_MSI | 362 | #ifdef __KVM_HAVE_MSI |
337 | static irqreturn_t kvm_assigned_dev_msi(int irq, void *dev_id) | ||
338 | { | ||
339 | return IRQ_WAKE_THREAD; | ||
340 | } | ||
341 | |||
342 | static int assigned_device_enable_host_msi(struct kvm *kvm, | 363 | static int assigned_device_enable_host_msi(struct kvm *kvm, |
343 | struct kvm_assigned_dev_kernel *dev) | 364 | struct kvm_assigned_dev_kernel *dev) |
344 | { | 365 | { |
@@ -363,11 +384,6 @@ static int assigned_device_enable_host_msi(struct kvm *kvm, | |||
363 | #endif | 384 | #endif |
364 | 385 | ||
365 | #ifdef __KVM_HAVE_MSIX | 386 | #ifdef __KVM_HAVE_MSIX |
366 | static irqreturn_t kvm_assigned_dev_msix(int irq, void *dev_id) | ||
367 | { | ||
368 | return IRQ_WAKE_THREAD; | ||
369 | } | ||
370 | |||
371 | static int assigned_device_enable_host_msix(struct kvm *kvm, | 387 | static int assigned_device_enable_host_msix(struct kvm *kvm, |
372 | struct kvm_assigned_dev_kernel *dev) | 388 | struct kvm_assigned_dev_kernel *dev) |
373 | { | 389 | { |