aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/irq_comm.c
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2009-08-24 04:54:25 -0400
committerAvi Kivity <avi@redhat.com>2009-12-03 02:32:08 -0500
commiteba0226bdfffe262e72b8360e4d0d12070e9a0f0 (patch)
tree93da785e3bba63a9232e529a2572541ef87c0615 /virt/kvm/irq_comm.c
parent280aa177dcd1edc718d8a92f17f235b783ec6307 (diff)
KVM: Move IO APIC to its own lock
The allows removal of irq_lock from the injection path. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'virt/kvm/irq_comm.c')
-rw-r--r--virt/kvm/irq_comm.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index 6c946141dbcc..fadf4408a820 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -146,8 +146,8 @@ static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
146 */ 146 */
147int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level) 147int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level)
148{ 148{
149 struct kvm_kernel_irq_routing_entry *e; 149 struct kvm_kernel_irq_routing_entry *e, irq_set[KVM_NR_IRQCHIPS];
150 int ret = -1; 150 int ret = -1, i = 0;
151 struct kvm_irq_routing_table *irq_rt; 151 struct kvm_irq_routing_table *irq_rt;
152 struct hlist_node *n; 152 struct hlist_node *n;
153 153
@@ -162,14 +162,19 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level)
162 rcu_read_lock(); 162 rcu_read_lock();
163 irq_rt = rcu_dereference(kvm->irq_routing); 163 irq_rt = rcu_dereference(kvm->irq_routing);
164 if (irq < irq_rt->nr_rt_entries) 164 if (irq < irq_rt->nr_rt_entries)
165 hlist_for_each_entry(e, n, &irq_rt->map[irq], link) { 165 hlist_for_each_entry(e, n, &irq_rt->map[irq], link)
166 int r = e->set(e, kvm, irq_source_id, level); 166 irq_set[i++] = *e;
167 if (r < 0)
168 continue;
169
170 ret = r + ((ret < 0) ? 0 : ret);
171 }
172 rcu_read_unlock(); 167 rcu_read_unlock();
168
169 while(i--) {
170 int r;
171 r = irq_set[i].set(&irq_set[i], kvm, irq_source_id, level);
172 if (r < 0)
173 continue;
174
175 ret = r + ((ret < 0) ? 0 : ret);
176 }
177
173 return ret; 178 return ret;
174} 179}
175 180