[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC PATCH] arm/vgic-v3: provide custom callbacks for pend_lpi_tree radix tree


  • To: Julien Grall <julien@xxxxxxx>
  • From: Luca Fancellu <luca.fancellu@xxxxxxx>
  • Date: Mon, 14 Feb 2022 17:20:46 +0000
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Q6ZTdptpjxbueCCMPaeWDSOHT05I9wowCjQfbNjENNY=; b=GLJzNU2qziNpg++c37XAnSvmGI0BwIaxWm0GWl+vkQqFiKERjR+ETwcZ9GyTkcWsOTSGvflJ6Tw12KSf+WaT25n1XCT4hYbIJuRur2UbazBl15PiEPWSI2BKRjUDspkiGDm6+3XLxCbHblRTB78NCxTTvAo7XyzGibtlfDcj8ruUNzzAs8fUVRuilbgYWV8mXmbn7LcyjqufeOLO86MQwUaj4DsfGlbekaebBZ2CffIhMKr8VGaEf6yG09y+oef9O2HdYKWZAVxd6o+NJJvIYTZQrZgPM2LqTrGAPyOY5h7LVnX+PFMkR8KU/B+qCpUqlze4gu/gKV0BuLMm28YneA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=LvBSVbByvZnadRpd3yDhNFARwOZy/XbG/RcabkZvzIGqNac+agLOulBgEEM1dy2GWckFecDqP7/ZVekpMZnrJ7Z8Cgh8CGCs0EjhT4e5gWEWe8qOxKpf/Rxiymgpa13oM/K54V/FfsrPId7YncI+qx0TLtCc0KXeANpH5AyLgKKE8wcoYXZOtipKW8Y9K/GDw17JtxiVm2HTW7Z7yibzMslwp5+yUjYejFiLmEkVTU1Z6L9ejgiKaVECWo0mRMG+1LhSnGPTfC9xJaj17c5F+YZ+7+BYvGFw8/XecnZs4NT+YRXHK81CSS7klvxjE1GkXF9abUzllJ+IHU86hpJxKg==
  • Authentication-results-original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Cc: Xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx>, wei.chen@xxxxxxx, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>
  • Delivery-date: Mon, 14 Feb 2022 17:21:29 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Original-authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;


> On 11 Feb 2022, at 16:12, Julien Grall <julien@xxxxxxx> wrote:
> 
> 
> 
> On 11/02/2022 15:45, Luca Fancellu wrote:
>>> On 11 Feb 2022, at 15:26, Julien Grall <julien@xxxxxxx> wrote:
>>> 
>>> Hi Luca,
>>> 
>>> On 11/02/2022 15:00, Luca Fancellu wrote:
>>>> pend_lpi_tree is a radix tree used to store pending irqs, the tree is
>>>> protected by a lock for read/write operations.
>>>> Currently the radix tree default function to free items uses the
>>>> RCU mechanism, calling call_rcu and deferring the operation.
>>>> However every access to the structure is protected by the lock so we
>>>> can avoid using the default free function that, by using RCU,
>>>> increases memory usage and impacts the predictability of the system.
>>> 
>>> I understand goal but looking at the implementation of 
>>> vgic_v3_lpi_to_pending() (Copied below for convenience). We would release 
>>> the lock as soon as the look-up finish, yet the element is returned.
>>> 
>>> static struct pending_irq *vgic_v3_lpi_to_pending(struct domain *d,
>>>                                                  unsigned int lpi)
>>> {
>>>    struct pending_irq *pirq;
>>> 
>>>    read_lock(&d->arch.vgic.pend_lpi_tree_lock);
>>>    pirq = radix_tree_lookup(&d->arch.vgic.pend_lpi_tree, lpi);
>>>    read_unlock(&d->arch.vgic.pend_lpi_tree_lock);
>>> 
>>>    return pirq;
>>> }
>>> 
>>> So the lock will not protect us against removal. If you want to drop the 
>>> RCU, you will need to ensure the structure pending_irq is suitably 
>>> protected. I haven't check whether there are other locks that may suit us 
>>> here.
>>> 
>> Hi Julien,
>> Yes you are right! I missed that, sorry for the noise.
> 
> Actually,... I think I am wrong :/.
> 
> I thought the lock pend_lpi_tre_lock would protect pending_irq, but it only 
> protects the radix tree element (not the value).
> 
> The use in its_discard_event() seems to confirm that because the
> pending_irq is re-initialized as soon as it gets destroyed.
> 
> I would like a second opinion though.
> 

Hi Julien,

I think you are right, the structure itself is protected but the usage of the 
element not. I guess now it’s safe because RCU
is freeing it when no cpus are using it anymore.

 - radix_tree_lookup
   - vgic_v3_lpi_to_pending (return pointer to item)
     - lpi_to_pending (function pointer to vgic_v3_lpi_to_pending)
       - irq_to_pending (return pointer to item if it is lpi -> is_lpi(irq))

         - vgic_vcpu_inject_lpi
           - gicv3_do_LPI (rcu_lock_domain_by_id on domain)
             - gic_interrupt (do_LPI function pointer)
               - do_trap_irq
               - do_trap_fiq
           - its_handle_int
             - vgic_its_handle_cmds
               - vgic_v3_its_mmio_write
                 - handle_write
                   - try_handle_mmio
                     - do_trap_stage2_abort_guest
                       - do_trap_guest_sync

         - vgic_get_hw_irq_desc 
           - release_guest_irq 
             - arch_do_domctl (XEN_DOMCTL_unbind_pt_irq)
               - do_domctl
             - domain_vgic_free
               - arch_domain_destroy

         - gic_raise_inflight_irq (assert v->arch.vgic.lock)
         - gic_raise_guest_irq (assert v->arch.vgic.lock)
         - gic_update_one_lr (assert v->arch.vgic.lock, irq are disabled)
         - vgic_connect_hw_irq
           - gic_route_irq_to_guest (Assert !is_lpi)
           - gic_remove_irq_from_guest (Assert !is_lpi(virq))
         - vgic_migrate_irq (lock old->arch.vgic.lock)
         - arch_move_irqs (Assert not lpi in loop)
         - vgic_disable_irqs (lock v_target->arch.vgic.lock)
         - vgic_enable_irqs (lock v_target->arch.vgic.lock)
         - vgic_inject_irq (lock v->arch.vgic.lock)
         - vgic_evtchn_irq_pending (assert !is_lpi(v->domain->arch.evtchn_irq))
         - vgic_check_inflight_irqs_pending (lock v_target->arch.vgic.lock)

   - vgic_v3_lpi_get_priority (return value from pointer)
     - lpi_get_priority (function pointer to vgic_v3_lpi_get_priority)

 - radix_tree_delete
   - its_discard_event (lock vcpu->arch.vgic.lock)

>From a quick analysis I see there are path using that pointer who doesn’t 
>share any lock.

I will put on hold this patch.

Cheers,
Luca


> Cheers,
> 
> -- 
> Julien Grall




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.