[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
> 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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |