From: Eric Auger <eric.auger@linaro.org> To: eric.auger@st.com, eric.auger@linaro.org, christoffer.dall@linaro.org, marc.zyngier@arm.com, andre.przywara@arm.com, linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, alex.williamson@redhat.com Cc: patches@linaro.org, a.motakis@virtualopensystems.com, a.rigo@virtualopensystems.com, b.reynal@virtualopensystems.com Subject: [RFC v2 3/4] KVM: arm: vgic: add forwarded irq rbtree lock Date: Wed, 11 Feb 2015 09:20:56 +0100 [thread overview] Message-ID: <1423642857-24240-4-git-send-email-eric.auger@linaro.org> (raw) In-Reply-To: <1423642857-24240-1-git-send-email-eric.auger@linaro.org> Add a lock related to the rb tree manipulation. The rb tree can be searched in one thread (irqfd handler for instance) and map/unmap may happen in another. Signed-off-by: Eric Auger <eric.auger@linaro.org> --- v2 -> v3: re-arrange lock sequence in vgic_map_phys_irq --- include/kvm/arm_vgic.h | 1 + virt/kvm/arm/vgic.c | 56 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 1a49108..ad7229b 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -220,6 +220,7 @@ struct vgic_dist { unsigned long *irq_pending_on_cpu; struct rb_root irq_phys_map; + spinlock_t rb_tree_lock; #endif }; diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 433ecba..dd72ca2 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c @@ -1756,9 +1756,22 @@ static struct rb_root *vgic_get_irq_phys_map(struct kvm_vcpu *vcpu, int vgic_map_phys_irq(struct kvm_vcpu *vcpu, int virt_irq, int phys_irq) { - struct rb_root *root = vgic_get_irq_phys_map(vcpu, virt_irq); - struct rb_node **new = &root->rb_node, *parent = NULL; + struct rb_root *root; + struct rb_node **new, *parent = NULL; struct irq_phys_map *new_map; + struct vgic_dist *dist = &vcpu->kvm->arch.vgic; + + root = vgic_get_irq_phys_map(vcpu, virt_irq); + new = &root->rb_node; + + new_map = kzalloc(sizeof(*new_map), GFP_KERNEL); + if (!new_map) + return -ENOMEM; + + new_map->virt_irq = virt_irq; + new_map->phys_irq = phys_irq; + + spin_lock(&dist->rb_tree_lock); /* Boilerplate rb_tree code */ while (*new) { @@ -1770,19 +1783,16 @@ int vgic_map_phys_irq(struct kvm_vcpu *vcpu, int virt_irq, int phys_irq) new = &(*new)->rb_left; else if (this->virt_irq > virt_irq) new = &(*new)->rb_right; - else + else { + kfree(new_map); + spin_unlock(&dist->rb_tree_lock); return -EEXIST; + } } - new_map = kzalloc(sizeof(*new_map), GFP_KERNEL); - if (!new_map) - return -ENOMEM; - - new_map->virt_irq = virt_irq; - new_map->phys_irq = phys_irq; - rb_link_node(&new_map->node, parent, new); rb_insert_color(&new_map->node, root); + spin_unlock(&dist->rb_tree_lock); return 0; } @@ -1811,24 +1821,39 @@ static struct irq_phys_map *vgic_irq_map_search(struct kvm_vcpu *vcpu, int vgic_get_phys_irq(struct kvm_vcpu *vcpu, int virt_irq) { - struct irq_phys_map *map = vgic_irq_map_search(vcpu, virt_irq); + struct irq_phys_map *map; + struct vgic_dist *dist = &vcpu->kvm->arch.vgic; + int ret; + + spin_lock(&dist->rb_tree_lock); + map = vgic_irq_map_search(vcpu, virt_irq); if (map) - return map->phys_irq; + ret = map->phys_irq; + else + ret = -ENOENT; + + spin_unlock(&dist->rb_tree_lock); + return ret; - return -ENOENT; } int vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, int virt_irq, int phys_irq) { - struct irq_phys_map *map = vgic_irq_map_search(vcpu, virt_irq); + struct irq_phys_map *map; + struct vgic_dist *dist = &vcpu->kvm->arch.vgic; + + spin_lock(&dist->rb_tree_lock); + + map = vgic_irq_map_search(vcpu, virt_irq); if (map && map->phys_irq == phys_irq) { rb_erase(&map->node, vgic_get_irq_phys_map(vcpu, virt_irq)); kfree(map); + spin_unlock(&dist->rb_tree_lock); return 0; } - + spin_unlock(&dist->rb_tree_lock); return -ENOENT; } @@ -2071,6 +2096,7 @@ int kvm_vgic_create(struct kvm *kvm) ret = 0; spin_lock_init(&kvm->arch.vgic.lock); + spin_lock_init(&kvm->arch.vgic.rb_tree_lock); kvm->arch.vgic.in_kernel = true; kvm->arch.vgic.vctrl_base = vgic->vctrl_base; kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF; -- 1.9.1
WARNING: multiple messages have this Message-ID (diff)
From: eric.auger@linaro.org (Eric Auger) To: linux-arm-kernel@lists.infradead.org Subject: [RFC v2 3/4] KVM: arm: vgic: add forwarded irq rbtree lock Date: Wed, 11 Feb 2015 09:20:56 +0100 [thread overview] Message-ID: <1423642857-24240-4-git-send-email-eric.auger@linaro.org> (raw) In-Reply-To: <1423642857-24240-1-git-send-email-eric.auger@linaro.org> Add a lock related to the rb tree manipulation. The rb tree can be searched in one thread (irqfd handler for instance) and map/unmap may happen in another. Signed-off-by: Eric Auger <eric.auger@linaro.org> --- v2 -> v3: re-arrange lock sequence in vgic_map_phys_irq --- include/kvm/arm_vgic.h | 1 + virt/kvm/arm/vgic.c | 56 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 1a49108..ad7229b 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -220,6 +220,7 @@ struct vgic_dist { unsigned long *irq_pending_on_cpu; struct rb_root irq_phys_map; + spinlock_t rb_tree_lock; #endif }; diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 433ecba..dd72ca2 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c @@ -1756,9 +1756,22 @@ static struct rb_root *vgic_get_irq_phys_map(struct kvm_vcpu *vcpu, int vgic_map_phys_irq(struct kvm_vcpu *vcpu, int virt_irq, int phys_irq) { - struct rb_root *root = vgic_get_irq_phys_map(vcpu, virt_irq); - struct rb_node **new = &root->rb_node, *parent = NULL; + struct rb_root *root; + struct rb_node **new, *parent = NULL; struct irq_phys_map *new_map; + struct vgic_dist *dist = &vcpu->kvm->arch.vgic; + + root = vgic_get_irq_phys_map(vcpu, virt_irq); + new = &root->rb_node; + + new_map = kzalloc(sizeof(*new_map), GFP_KERNEL); + if (!new_map) + return -ENOMEM; + + new_map->virt_irq = virt_irq; + new_map->phys_irq = phys_irq; + + spin_lock(&dist->rb_tree_lock); /* Boilerplate rb_tree code */ while (*new) { @@ -1770,19 +1783,16 @@ int vgic_map_phys_irq(struct kvm_vcpu *vcpu, int virt_irq, int phys_irq) new = &(*new)->rb_left; else if (this->virt_irq > virt_irq) new = &(*new)->rb_right; - else + else { + kfree(new_map); + spin_unlock(&dist->rb_tree_lock); return -EEXIST; + } } - new_map = kzalloc(sizeof(*new_map), GFP_KERNEL); - if (!new_map) - return -ENOMEM; - - new_map->virt_irq = virt_irq; - new_map->phys_irq = phys_irq; - rb_link_node(&new_map->node, parent, new); rb_insert_color(&new_map->node, root); + spin_unlock(&dist->rb_tree_lock); return 0; } @@ -1811,24 +1821,39 @@ static struct irq_phys_map *vgic_irq_map_search(struct kvm_vcpu *vcpu, int vgic_get_phys_irq(struct kvm_vcpu *vcpu, int virt_irq) { - struct irq_phys_map *map = vgic_irq_map_search(vcpu, virt_irq); + struct irq_phys_map *map; + struct vgic_dist *dist = &vcpu->kvm->arch.vgic; + int ret; + + spin_lock(&dist->rb_tree_lock); + map = vgic_irq_map_search(vcpu, virt_irq); if (map) - return map->phys_irq; + ret = map->phys_irq; + else + ret = -ENOENT; + + spin_unlock(&dist->rb_tree_lock); + return ret; - return -ENOENT; } int vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, int virt_irq, int phys_irq) { - struct irq_phys_map *map = vgic_irq_map_search(vcpu, virt_irq); + struct irq_phys_map *map; + struct vgic_dist *dist = &vcpu->kvm->arch.vgic; + + spin_lock(&dist->rb_tree_lock); + + map = vgic_irq_map_search(vcpu, virt_irq); if (map && map->phys_irq == phys_irq) { rb_erase(&map->node, vgic_get_irq_phys_map(vcpu, virt_irq)); kfree(map); + spin_unlock(&dist->rb_tree_lock); return 0; } - + spin_unlock(&dist->rb_tree_lock); return -ENOENT; } @@ -2071,6 +2096,7 @@ int kvm_vgic_create(struct kvm *kvm) ret = 0; spin_lock_init(&kvm->arch.vgic.lock); + spin_lock_init(&kvm->arch.vgic.rb_tree_lock); kvm->arch.vgic.in_kernel = true; kvm->arch.vgic.vctrl_base = vgic->vctrl_base; kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF; -- 1.9.1
next prev parent reply other threads:[~2015-02-11 8:23 UTC|newest] Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top 2015-02-11 8:20 [RFC v2 0/4] chip/vgic adaptations for forwarded irq Eric Auger 2015-02-11 8:20 ` Eric Auger 2015-02-11 8:20 ` [RFC v2 1/4] chip.c: complete the forwarded IRQ in case the handler is not reached Eric Auger 2015-02-11 8:20 ` Eric Auger 2015-02-11 8:20 ` [RFC v2 2/4] KVM: arm: vgic: fix state machine for forwarded IRQ Eric Auger 2015-02-11 8:20 ` Eric Auger 2015-05-06 14:26 ` Christoffer Dall 2015-05-06 14:26 ` Christoffer Dall 2015-05-07 7:48 ` Eric Auger 2015-05-07 7:48 ` Eric Auger 2015-05-07 9:20 ` Christoffer Dall 2015-05-07 9:20 ` Christoffer Dall 2015-05-07 9:38 ` Eric Auger 2015-05-07 9:38 ` Eric Auger 2015-02-11 8:20 ` Eric Auger [this message] 2015-02-11 8:20 ` [RFC v2 3/4] KVM: arm: vgic: add forwarded irq rbtree lock Eric Auger 2015-02-11 8:20 ` [RFC v2 4/4] KVM: arm: vgic: cleanup forwarded IRQs on destroy Eric Auger 2015-02-11 8:20 ` Eric Auger 2015-05-06 14:27 ` [RFC v2 0/4] chip/vgic adaptations for forwarded irq Christoffer Dall 2015-05-06 14:27 ` Christoffer Dall 2015-05-06 15:32 ` Eric Auger 2015-05-06 15:32 ` Eric Auger 2015-05-07 9:17 ` Christoffer Dall 2015-05-07 9:17 ` Christoffer Dall 2015-05-07 9:39 ` Eric Auger 2015-05-07 9:39 ` Eric Auger
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1423642857-24240-4-git-send-email-eric.auger@linaro.org \ --to=eric.auger@linaro.org \ --cc=a.motakis@virtualopensystems.com \ --cc=a.rigo@virtualopensystems.com \ --cc=alex.williamson@redhat.com \ --cc=andre.przywara@arm.com \ --cc=b.reynal@virtualopensystems.com \ --cc=christoffer.dall@linaro.org \ --cc=eric.auger@st.com \ --cc=kvm@vger.kernel.org \ --cc=kvmarm@lists.cs.columbia.edu \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=marc.zyngier@arm.com \ --cc=patches@linaro.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.