xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Julien Grall <julien.grall@arm.com>
To: Stefano Stabellini <sstabellini@kernel.org>
Cc: Andre Przywara <andre.przywara@arm.com>,
	nd@arm.com, xen-devel@lists.xenproject.org
Subject: Re: [RFC PATCH 01/10] ARM: vGIC: remove rank lock from IRQ routing functions
Date: Mon, 8 May 2017 23:13:22 +0100	[thread overview]
Message-ID: <a8ec8bbf-2c29-511e-5b04-ca255f1ead6b@arm.com> (raw)
In-Reply-To: <alpine.DEB.2.10.1705081408250.24729@sstabellini-ThinkPad-X260>

Hi Stefano,

On 08/05/2017 22:53, Stefano Stabellini wrote:
> On Mon, 8 May 2017, Julien Grall wrote:
>> Hi Andre,
>>
>> On 08/05/17 10:15, Andre Przywara wrote:
>>> On 04/05/17 16:53, Julien Grall wrote:
>>>> Hi Andre,
>>>>
>>>> On 04/05/17 16:31, Andre Przywara wrote:
>>>>> gic_route_irq_to_guest() and gic_remove_irq_from_guest() take the rank
>>>>> lock, however never actually access the rank structure.
>>>>> Avoid taking the lock in those two functions and remove some more
>>>>> unneeded code on the way.
>>>>
>>>> The rank is here to protect p->desc when checking that the virtual
>>>> interrupt was not yet routed to another physical interrupt.
>>>
>>> Really? To me that sounds quite surprising.
>>> My understanding is that the VGIC VCPU lock protected the pending_irq
>>> (and thus the desc pointer?) so far, and the desc itself has its own lock.
>>> According to the comment in the struct irq_rank declaration the lock
>>> protects the members of this struct only.
>>>
>>> Looking briefly at users of pending_irq->desc (for instance
>>> gicv[23]_update_lr() or gic_update_one_lr()) I can't see any hint that
>>> they care about the lock.
>>>
>>> So should that be fixed or at least documented?
>>
>> My understanding is this rank lock is preventing race between two updates of
>> p->desc. This can happen if gic_route_irq_to_guest(...) is called concurrently
>> with the same vIRQ but different pIRQ.
>>
>> If you drop this lock, nothing will protect that anymore.
>
> The desc->lock in route_irq_to_guest is protecting against concurrent
> changes to the same physical irq.
>
> The vgic_lock_rank in gic_route_irq_to_guest is protecting against
> concurrent changes to the same virtual irq.
>
> In other words, the current code does:
> 1) lock physical irq
> 2) lock virtual irq
> 3) establish mapping virtual irq - physical irq
>
> Andre, sorry for not seeing this earlier.
>
>
>>>> Without this locking, you can have two concurrent call of
>>>> gic_route_irq_to_guest that will update the same virtual interrupt but
>>>> with different physical interrupts.
>>>>
>>>> You would have to replace the rank lock by the per-pending_irq lock to
>>>> keep the code safe.
>>>
>>> That indeed sounds reasonable.
>>
>> As you mentioned IRL, the current code may lead to a deadlock due to locking
>> order.
>>
>> Indeed routing an IRQ (route_irq_to_guest) will take:
>> 	1) desc lock (in route_irq_to_guest)
>> 	2) rank lock (in gic_route_irq_to_guest)
>>
>> Whilst the MMIO emulation of ISENABLER_* will take:
>> 	1) rank lock
>> 	2) desc lock (in vgic_enable_irqs)
>
> Yes, you are right, but I don't think that is an issue because
> route_irq_to_guest is expected to be called before the domain is
> started, which is consistent with what you wrote below that routing
> should be done *before* running the VM.

I didn't consider as a big issue because of that and the fact it 
currently can only happen via a domctl or during dom0 building.

>
> To be clear: I am not arguing for keeping the code as-is, just trying to
> understand it.
>
>
>> Using the per-pending_irq lock will not solve the deadlock. I though a bit
>> more to the code. I believe the routing of SPIs/PPIs after domain creation
>> time is a call to mistake and locking nightmare. Similarly an interrupt should
>> stay routed for the duration of the domain life.
>
> It looks like current routing code was already written with that assumption.
>
>
>> So I would forbid IRQ routing after domain creation (see d->creation_finished)
>> and remove IRQ whilst routing (I think with d->is_dying). This would have an
>> race between the routing and the rest of the vGIC code.
>
> I am fine with that.
>
>
>> However, this would not prevent the routing function to race against itself.
>> For that I would take the vgic domain lock, it is fine because routing is not
>> something we expect to happen often.
>>
>> Any opinions?
>
> The changes done by gic_route_irq_to_guest are specific to one virtual
> irq and one physical irq. In fact, they establish the mapping between
> the two.
>
> Given that concurrent changes to a physical irq are protected by the
> desc->lock in route_irq_to_guest, why do you think that taking the new
> pending_irq lock in gic_route_irq_to_guest would not be sufficient?
> (gic_route_irq_to_guest is always called by route_irq_to_guest.)

Because if we just replace the rank lock by the pending lock there 
deadlock would still be there. I guess we can take the pending_irq lock 
in route_irq_to_guest before the desc lock.

But I like the idea of hiding the vgic locking in gic_route_irq_to_guest 
to keep irq.c fairly Interrupt Controller agnostic.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

  reply	other threads:[~2017-05-08 22:13 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-04 15:31 [RFC PATCH 00/10] ARM VGIC rework: remove rank, introduce per-IRQ lock Andre Przywara
2017-05-04 15:31 ` [RFC PATCH 01/10] ARM: vGIC: remove rank lock from IRQ routing functions Andre Przywara
2017-05-04 15:53   ` Julien Grall
2017-05-08  9:15     ` Andre Przywara
2017-05-08 14:26       ` Julien Grall
2017-05-08 21:53         ` Stefano Stabellini
2017-05-08 22:13           ` Julien Grall [this message]
2017-05-09  0:47             ` Stefano Stabellini
2017-05-09 15:24               ` Julien Grall
2017-05-04 15:31 ` [RFC PATCH 02/10] ARM: vGIC: rework gic_raise_*_irq() functions Andre Przywara
2017-05-04 15:31 ` [RFC PATCH 03/10] ARM: vGIC: introduce and initialize pending_irq lock Andre Przywara
2017-05-04 15:31 ` [RFC PATCH 04/10] ARM: vGIC: add struct pending_irq locking Andre Przywara
2017-05-04 16:21   ` Julien Grall
2017-05-05  9:02     ` Andre Przywara
2017-05-05 23:29       ` Stefano Stabellini
2017-05-06  6:41       ` Julien Grall
2017-05-05 23:42     ` Stefano Stabellini
2017-05-04 16:54   ` Julien Grall
2017-05-05 23:26     ` Stefano Stabellini
2017-05-04 15:31 ` [RFC PATCH 05/10] ARM: vGIC: move priority from irq_rank to struct pending_irq Andre Przywara
2017-05-04 16:39   ` Julien Grall
2017-05-04 16:47     ` Julien Grall
2017-05-04 15:31 ` [RFC PATCH 06/10] ARM: vGIC: move config " Andre Przywara
2017-05-04 16:55   ` Julien Grall
2017-05-04 15:31 ` [RFC PATCH 07/10] ARM: vGIC: move enable status " Andre Przywara
2017-05-04 15:31 ` [RFC PATCH 08/10] ARM: vGIC: move target vcpu " Andre Przywara
2017-05-04 17:20   ` Julien Grall
2017-05-04 15:31 ` [RFC PATCH 09/10] ARM: vGIC: introduce vgic_get/put_pending_irq Andre Przywara
2017-05-04 17:36   ` Julien Grall
2017-05-04 22:42     ` Stefano Stabellini
2017-05-04 15:31 ` [RFC PATCH 10/10] ARM: vGIC: remove struct irq_rank and support functions Andre Przywara

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=a8ec8bbf-2c29-511e-5b04-ca255f1ead6b@arm.com \
    --to=julien.grall@arm.com \
    --cc=andre.przywara@arm.com \
    --cc=nd@arm.com \
    --cc=sstabellini@kernel.org \
    --cc=xen-devel@lists.xenproject.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: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).