> Subject: Re: [PATCH 1/2] arm: irqchip: add lock in irqchip_inject_pending
> 
> On 03.12.19 09:58, Peng Fan wrote:
> >> Subject: Re: [PATCH 1/2] arm: irqchip: add lock in
> >> irqchip_inject_pending
> >>
> >> On 03.12.19 09:27, Peng Fan wrote:
> >>> Thinking about core0 is inject SGI to core1, core1 is handling SGI
> >>> interrupt.
> >>>
> >>> That means core0 might be in path to enqueue SGI into the
> >>> pending_irqs array, core1 might be in path handling SGI and pick one
> >>> from pending_irqs array. So need to use lock to protect unqueue, not
> >>> only enqueue.
> >>>
> >>> Signed-off-by: Peng Fan <peng....@nxp.com>
> >>> ---
> >>>
> >>> V1:
> >>>  The best case is only lock one entry, so no good solution, because
> >>> there is possibility that inject fail.
> >>>
> >>>  hypervisor/arch/arm-common/irqchip.c | 5 +++++
> >>>  1 file changed, 5 insertions(+)
> >>>
> >>> diff --git a/hypervisor/arch/arm-common/irqchip.c
> >>> b/hypervisor/arch/arm-common/irqchip.c
> >>> index 1c881b64..fbaa3099 100644
> >>> --- a/hypervisor/arch/arm-common/irqchip.c
> >>> +++ b/hypervisor/arch/arm-common/irqchip.c
> >>> @@ -279,11 +279,14 @@ void irqchip_inject_pending(void)
> >>>   struct pending_irqs *pending = &this_cpu_public()->pending_irqs;
> >>>   u16 irq_id, sender;
> >>>
> >>> + spin_lock(&pending->lock);
> >>> +
> >>>   while (pending->head != pending->tail) {
> >>>           irq_id = pending->irqs[pending->head];
> >>>           sender = pending->sender[pending->head];
> >>>
> >>>           if (irqchip.inject_irq(irq_id, sender) == -EBUSY) {
> >>> +                 spin_unlock(&pending->lock);
> >>>                   /*
> >>>                    * The list registers are full, trigger maintenance
> >>>                    * interrupt and leave.
> >>> @@ -295,6 +298,8 @@ void irqchip_inject_pending(void)
> >>>           pending->head = (pending->head + 1) % MAX_PENDING_IRQS;
> >>>   }
> >>>
> >>> + spin_unlock(&pending->lock);
> >>> +
> >>>   /*
> >>>    * The software interrupt queue is empty - turn off the
> maintenance
> >>>    * interrupt.
> >>>
> >>
> >> Did you see real corruptions?
> >
> > No. just code inspection currently. We met some SGI inject return
> > -EBUSY, so go through the code, and think this piece code needs a lock.
> >
> >>
> >> The idea behind this was that the injection to the lock-less queue
> >> happens in a way that it won't make changes visible to the consumer
> >> that are inconsistent, hence the barrier in irqchip_set_pending.
> >> Looking that again, though, we possibly need another barrier, right
> >> before updating
> >> pending->tail.
> >
> > Barrier could not prohibit enqueue/unqueue contention.
> > enqueue will check head, unqueue will update head.
> 
> Some topic as with lockless enqueuing: We need a barrier to shield the
> readout of the head entry from the update of pending->head. So, we are
> definitely lacking barriers here, but I don't think we need the spinlock
> between producer and consumer because there is only one consumer.

Lock-free should be possible, let me work out a non-lock solution.

Regards,
Peng.

> 
> Jan
> 
> --
> Siemens AG, Corporate Technology, CT RDA IOT SES-DE Corporate
> Competence Center Embedded Linux

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jailhouse-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/AM0PR04MB44811BEC3EDE072313C1F3B888420%40AM0PR04MB4481.eurprd04.prod.outlook.com.

Reply via email to