Hi Marc, On 6/6/19 6:54 PM, Marc Zyngier wrote: > Our LPI translation cache needs to be able to drop the refcount > on an LPI whilst already holding the lpi_list_lock. > > Let's add a new primitive for this. > > Signed-off-by: Marc Zyngier <marc.zyngier@xxxxxxx> Reviewed-by: Eric Auger <eric.auger@xxxxxxxxxx> Thanks Eric > --- > virt/kvm/arm/vgic/vgic.c | 26 +++++++++++++++++--------- > virt/kvm/arm/vgic/vgic.h | 1 + > 2 files changed, 18 insertions(+), 9 deletions(-) > > diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c > index 191deccf60bf..376a297e2169 100644 > --- a/virt/kvm/arm/vgic/vgic.c > +++ b/virt/kvm/arm/vgic/vgic.c > @@ -130,6 +130,22 @@ static void vgic_irq_release(struct kref *ref) > { > } > > +/* > + * Drop the refcount on the LPI. Must be called with lpi_list_lock held. > + */ > +void __vgic_put_lpi_locked(struct kvm *kvm, struct vgic_irq *irq) > +{ > + struct vgic_dist *dist = &kvm->arch.vgic; > + > + if (!kref_put(&irq->refcount, vgic_irq_release)) > + return; > + > + list_del(&irq->lpi_list); > + dist->lpi_list_count--; > + > + kfree(irq); > +} > + > void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq) > { > struct vgic_dist *dist = &kvm->arch.vgic; > @@ -139,16 +155,8 @@ void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq) > return; > > raw_spin_lock_irqsave(&dist->lpi_list_lock, flags); > - if (!kref_put(&irq->refcount, vgic_irq_release)) { > - raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags); > - return; > - }; > - > - list_del(&irq->lpi_list); > - dist->lpi_list_count--; > + __vgic_put_lpi_locked(kvm, irq); > raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags); > - > - kfree(irq); > } > > void vgic_flush_pending_lpis(struct kvm_vcpu *vcpu) > diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h > index a58e1b263dca..80cd40575bc9 100644 > --- a/virt/kvm/arm/vgic/vgic.h > +++ b/virt/kvm/arm/vgic/vgic.h > @@ -172,6 +172,7 @@ vgic_get_mmio_region(struct kvm_vcpu *vcpu, struct vgic_io_device *iodev, > gpa_t addr, int len); > struct vgic_irq *vgic_get_irq(struct kvm *kvm, struct kvm_vcpu *vcpu, > u32 intid); > +void __vgic_put_lpi_locked(struct kvm *kvm, struct vgic_irq *irq); > void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq); > bool vgic_get_phys_line_level(struct vgic_irq *irq); > void vgic_irq_set_phys_pending(struct vgic_irq *irq, bool pending); > _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm