diff options
author | Gleb Natapov <gleb@redhat.com> | 2009-08-24 10:54:25 +0200 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-12-03 08:32:08 +0100 |
commit | eba0226bdfffe262e72b8360e4d0d12070e9a0f0 (patch) | |
tree | 93da785e3bba63a9232e529a2572541ef87c0615 /virt/kvm/irq_comm.c | |
parent | KVM: Convert irq notifiers lists to RCU locking (diff) | |
download | linux-eba0226bdfffe262e72b8360e4d0d12070e9a0f0.tar.xz linux-eba0226bdfffe262e72b8360e4d0d12070e9a0f0.zip |
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.c | 23 |
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, */ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level) { - struct kvm_kernel_irq_routing_entry *e; - int ret = -1; + struct kvm_kernel_irq_routing_entry *e, irq_set[KVM_NR_IRQCHIPS]; + int ret = -1, i = 0; struct kvm_irq_routing_table *irq_rt; struct hlist_node *n; @@ -162,14 +162,19 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level) rcu_read_lock(); irq_rt = rcu_dereference(kvm->irq_routing); if (irq < irq_rt->nr_rt_entries) - hlist_for_each_entry(e, n, &irq_rt->map[irq], link) { - int r = e->set(e, kvm, irq_source_id, level); - if (r < 0) - continue; - - ret = r + ((ret < 0) ? 0 : ret); - } + hlist_for_each_entry(e, n, &irq_rt->map[irq], link) + irq_set[i++] = *e; rcu_read_unlock(); + + while(i--) { + int r; + r = irq_set[i].set(&irq_set[i], kvm, irq_source_id, level); + if (r < 0) + continue; + + ret = r + ((ret < 0) ? 0 : ret); + } + return ret; } |