xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Andre Przywara <andre.przywara@arm.com>
To: Julien Grall <julien.grall@arm.com>,
	Stefano Stabellini <sstabellini@kernel.org>
Cc: xen-devel@lists.xenproject.org,
	Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>,
	nd@arm.com, Shanker Donthineni <shankerd@codeaurora.org>,
	Vijay Kilari <vijay.kilari@gmail.com>
Subject: Re: [PATCH v9 12/28] ARM: vGIC: advertise LPI support
Date: Fri, 26 May 2017 18:12:13 +0100	[thread overview]
Message-ID: <3767a1b6-3449-cf8a-18a3-4543a408608b@arm.com> (raw)
In-Reply-To: <8d377065-30fc-8a35-aad7-d8770ad02373@arm.com>

Hi,

On 26/05/17 11:19, Julien Grall wrote:
> Hi Stefano,
> 
> On 25/05/17 22:05, Stefano Stabellini wrote:
>> On Thu, 25 May 2017, Julien Grall wrote:
>>> Hi Stefano,
>>>
>>> On 25/05/2017 19:49, Stefano Stabellini wrote:
>>>> On Thu, 25 May 2017, Andre Przywara wrote:
>>>>> Hi,
>>>>>
>>>>> On 23/05/17 18:47, Stefano Stabellini wrote:
>>>>>> On Tue, 23 May 2017, Julien Grall wrote:
>>>>>>> Hi Stefano,
>>>>>>>
>>>>>>> On 22/05/17 23:19, Stefano Stabellini wrote:
>>>>>>>> On Tue, 16 May 2017, Julien Grall wrote:
>>>>>>>>>> @@ -436,8 +473,26 @@ static int
>>>>>>>>>> __vgic_v3_rdistr_rd_mmio_write(struct
>>>>>>>>>> vcpu
>>>>>>>>>> *v, mmio_info_t *info,
>>>>>>>>>>      switch ( gicr_reg )
>>>>>>>>>>      {
>>>>>>>>>>      case VREG32(GICR_CTLR):
>>>>>>>>>> -        /* LPI's not implemented */
>>>>>>>>>> -        goto write_ignore_32;
>>>>>>>>>> +    {
>>>>>>>>>> +        unsigned long flags;
>>>>>>>>>> +
>>>>>>>>>> +        if ( !v->domain->arch.vgic.has_its )
>>>>>>>>>> +            goto write_ignore_32;
>>>>>>>>>> +        if ( dabt.size != DABT_WORD ) goto bad_width;
>>>>>>>>>> +
>>>>>>>>>> +        vgic_lock(v);                   /* protects
>>>>>>>>>> rdists_enabled */
>>>>>>>>>
>>>>>>>>> Getting back to the locking. I don't see any place where we get
>>>>>>>>> the domain
>>>>>>>>> vgic lock before vCPU vgic lock. So this raises the question why
>>>>>>>>> this
>>>>>>>>> ordering
>>>>>>>>> and not moving this lock into vgic_vcpu_enable_lpis.
>>>>>>>>>
>>>>>>>>> At least this require documentation in the code and explanation in
>>>>>>>>> the
>>>>>>>>> commit
>>>>>>>>> message.
>>>>>>>>
>>>>>>>> It doesn't look like we need to take the v->arch.vgic.lock here.
>>>>>>>> What is
>>>>>>>> it protecting?
>>>>>>>
>>>>>>> The name of the function is a bit confusion. It does not take the
>>>>>>> vCPU
>>>>>>> vgic
>>>>>>> lock but the domain vgic lock.
>>>>>>>
>>>>>>> I believe the vcpu is passed to avoid have v->domain in most of the
>>>>>>> callers.
>>>>>>> But we should probably rename the function.
>>>>>>>
>>>>>>> In this case it protects vgic_vcpu_enable_lpis because you can
>>>>>>> configure the
>>>>>>> number of LPIs per re-distributor but this is a domain wide value. I
>>>>>>> know the
>>>>>>> spec is confusing on this.
>>>>>>
>>>>>> The quoting here is very unhelpful. In Andre's patch:
>>>>>>
>>>>>> @@ -436,8 +473,26 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct
>>>>>> vcpu *v, mmio_info_t *info,
>>>>>>      switch ( gicr_reg )
>>>>>>      {
>>>>>>      case VREG32(GICR_CTLR):
>>>>>> -        /* LPI's not implemented */
>>>>>> -        goto write_ignore_32;
>>>>>> +    {
>>>>>> +        unsigned long flags;
>>>>>> +
>>>>>> +        if ( !v->domain->arch.vgic.has_its )
>>>>>> +            goto write_ignore_32;
>>>>>> +        if ( dabt.size != DABT_WORD ) goto bad_width;
>>>>>> +
>>>>>> +        vgic_lock(v);                   /* protects
>>>>>> rdists_enabled */
>>>>>> +        spin_lock_irqsave(&v->arch.vgic.lock, flags);
>>>>>> +
>>>>>> +        /* LPIs can only be enabled once, but never disabled
>>>>>> again. */
>>>>>> +        if ( (r & GICR_CTLR_ENABLE_LPIS) &&
>>>>>> +             !(v->arch.vgic.flags & VGIC_V3_LPIS_ENABLED) )
>>>>>> +            vgic_vcpu_enable_lpis(v);
>>>>>> +
>>>>>> +        spin_unlock_irqrestore(&v->arch.vgic.lock, flags);
>>>>>> +        vgic_unlock(v);
>>>>>> +
>>>>>> +        return 1;
>>>>>> +    }
>>>>>>
>>>>>> My question is: do we need to take both vgic_lock and
>>>>>> v->arch.vgic.lock?
>>>>>
>>>>> The domain lock (taken by vgic_lock()) protects rdists_enabled. This
>>>>> variable stores whether at least one redistributor has LPIs
>>>>> enabled. In
>>>>> this case the property table gets into use and since the table is
>>>>> shared
>>>>> across all redistributors, we must not change it anymore, even on
>>>>> another redistributor which has its LPIs still disabled.
>>>>> So while this looks like this is a per-redistributor (=per-VCPU)
>>>>> property, it is actually per domain, hence this lock.
>>>>> The VGIC VCPU lock is then used to naturally protect the enable bit
>>>>> against multiple VCPUs accessing this register simultaneously - the
>>>>> redists are MMIO mapped, but not banked, so this is possible.
>>>>>
>>>>> Does that make sense?
>>>>
>>>> If the VGIC VCPU lock is only used to protect VGIC_V3_LPIS_ENABLED,
>>>> couldn't we just read/write the bit atomically? It's just a bit after
>>>> all, it doesn't need a lock.
>>>
>>> The vGIC vCPU lock is also here to serialize access to the
>>> re-distributor
>>> state when necessary.
>>>
>>> For instance you don't want to allow write in PENDBASER after LPIs
>>> have been
>>> enabled.
>>>
>>> If you don't take the lock here, you would have a small race where
>>> PENDBASER
>>> might be written whilst the LPIs are getting enabled.
>>>
>>> The code in PENDBASER today does not strictly require the locking,
>>> but I think
>>> we should keep the lock around. Moving to the atomic will not really
>>> benefit
>>> here as write to those registers will be very unlikely so we don't
>>> need very
>>> good performance.
>>
>> I suggested the atomic as a way to replace the lock, to reduce the
>> number of lock order dependencies, rather than for performance (who
>> cares about performance for this case). If all accesses to
>> VGIC_V3_LPIS_ENABLED are atomic, then we wouldn't need the lock.
>>
>> Another maybe simpler way to keep the vgic vcpu lock but avoid
>> introducing the vgic domain lock -> vgic vcpu lock dependency (the less
>> the better) would be to take the vgic vcpu lock first, release it, then
>> take the vgic domain lock and call vgic_vcpu_enable_lpis after.  In
>> pseudo-code:
>>
>>     vgic vcpu lock
>>     read old value of VGIC_V3_LPIS_ENABLED
>>     write new value of VGIC_V3_LPIS_ENABLED
>>     vgic vcpu unlock
>>
>>     vgic domain lock
>>     vgic_vcpu_enable_lpis (minus the setting of arch.vgic.flags)
>>     vgic domain unlock
>>
>> It doesn't look like we need to set VGIC_V3_LPIS_ENABLED within
>> vgic_vcpu_enable_lpis, so this seems to be working. What do you think?
> 
> From a point of view of the vGIC you want to enable VGIC_V3_LPIS_ENABLED
> after all the sanity checks have been done.
> 
> I would have expected the ITS to check if the redistributor has been
> enabled before enabling it (see vgic_v3_verify_its_status). This is
> because the ITS is using the priority table and also the number of LPIs.
> 
> So you effectively want to have VGIC_V3_LPIS_ENABLED set after in
> vgic_vcpu_enable_lpis to avoid potential race condition. You may also
> want to have a mb() before writing to it so you can using
> VGIC_V3_LPIS_ENABLED without any lock safely.

Right, I added an smp_mb() after the rdists_enabled write to make sure
this is in sync.

> Andre, can you explain why the ITS does not check whether the
> rdists_enabled are enabled?

So architecturally it's not required to have LPIs enabled, and from a
spec point of view the ITS does not care about the LPI's properties.
We check for LPIs being enabled on that redistributor before injecting LPI.

But I think you are right that our implementation is a bit sloppy with
the separation between LPIs and the ITS, and reads the property table
while handling commands - because we only keep track of mapped LPIs.
So I added a check now in update_lpi_properties() to bail out (without
an error) if no redistributor has LPIs enabled yet. That should solve
that corner case.

Cheers,
Andre.

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

  reply	other threads:[~2017-05-26 17:12 UTC|newest]

Thread overview: 108+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-11 17:53 [PATCH v9 00/28] arm64: Dom0 ITS emulation Andre Przywara
2017-05-11 17:53 ` [PATCH v9 01/28] ARM: GICv3: setup number of LPI bits for a GICv3 guest Andre Przywara
2017-05-11 18:34   ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 02/28] ARM: VGIC: move irq_to_pending() calls under the VGIC VCPU lock Andre Przywara
2017-05-20  0:34   ` Stefano Stabellini
2017-05-11 17:53 ` [PATCH v9 03/28] ARM: GIC: Add checks for NULL pointer pending_irq's Andre Przywara
2017-05-12 14:19   ` Julien Grall
2017-05-22 16:49     ` Andre Przywara
2017-05-22 17:15       ` Julien Grall
2017-05-25 16:14         ` Andre Przywara
2017-05-20  1:25   ` Stefano Stabellini
2017-05-11 17:53 ` [PATCH v9 04/28] ARM: GICv3: introduce separate pending_irq structs for LPIs Andre Przywara
2017-05-12 14:22   ` Julien Grall
2017-05-22 21:52   ` Stefano Stabellini
2017-05-11 17:53 ` [PATCH v9 05/28] ARM: GICv3: forward pending LPIs to guests Andre Przywara
2017-05-12 14:55   ` Julien Grall
2017-05-22 22:03   ` Stefano Stabellini
2017-05-25 16:42     ` Andre Przywara
2017-05-11 17:53 ` [PATCH v9 06/28] ARM: GICv3: enable ITS and LPIs on the host Andre Przywara
2017-05-11 17:53 ` [PATCH v9 07/28] ARM: vGICv3: handle virtual LPI pending and property tables Andre Przywara
2017-05-12 15:23   ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 08/28] ARM: introduce vgic_access_guest_memory() Andre Przywara
2017-05-12 15:30   ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 09/28] ARM: vGICv3: re-use vgic_reg64_check_access Andre Przywara
2017-05-11 17:53 ` [PATCH v9 10/28] ARM: GIC: export and extend vgic_init_pending_irq() Andre Przywara
2017-05-16 12:26   ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 11/28] ARM: VGIC: add vcpu_id to struct pending_irq Andre Przywara
2017-05-16 12:31   ` Julien Grall
2017-05-22 22:15     ` Stefano Stabellini
2017-05-23  9:49       ` Andre Przywara
2017-05-11 17:53 ` [PATCH v9 12/28] ARM: vGIC: advertise LPI support Andre Przywara
2017-05-16 13:03   ` Julien Grall
2017-05-22 22:19     ` Stefano Stabellini
2017-05-23 10:49       ` Julien Grall
2017-05-23 17:47         ` Stefano Stabellini
2017-05-24 10:10           ` Julien Grall
2017-05-25 18:02           ` Andre Przywara
2017-05-25 18:49             ` Stefano Stabellini
2017-05-25 20:07               ` Julien Grall
2017-05-25 21:05                 ` Stefano Stabellini
2017-05-26 10:19                   ` Julien Grall
2017-05-26 17:12                     ` Andre Przywara [this message]
2017-05-23 17:23     ` Andre Przywara
2017-05-11 17:53 ` [PATCH v9 13/28] ARM: vITS: add command handling stub and MMIO emulation Andre Przywara
2017-05-16 15:24   ` Julien Grall
2017-05-17 16:16   ` Julien Grall
2017-05-22 22:32   ` Stefano Stabellini
2017-05-23 10:54     ` Julien Grall
2017-05-23 17:43       ` Stefano Stabellini
2017-05-11 17:53 ` [PATCH v9 14/28] ARM: vITS: introduce translation table walks Andre Przywara
2017-05-16 15:57   ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 15/28] ARM: vITS: provide access to struct pending_irq Andre Przywara
2017-05-17 15:35   ` Julien Grall
2017-05-22 16:50     ` Andre Przywara
2017-05-22 17:19       ` Julien Grall
2017-05-26  9:10         ` Andre Przywara
2017-05-26 10:00           ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 16/28] ARM: vITS: handle INT command Andre Przywara
2017-05-17 16:17   ` Julien Grall
2017-05-23 17:24     ` Andre Przywara
2017-05-11 17:53 ` [PATCH v9 17/28] ARM: vITS: handle MAPC command Andre Przywara
2017-05-17 17:22   ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 18/28] ARM: vITS: handle CLEAR command Andre Przywara
2017-05-17 17:45   ` Julien Grall
2017-05-23 17:24     ` Andre Przywara
2017-05-24  9:04       ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 19/28] ARM: vITS: handle MAPD command Andre Przywara
2017-05-17 18:07   ` Julien Grall
2017-05-24  9:10     ` Andre Przywara
2017-05-24  9:56       ` Julien Grall
2017-05-24 13:09         ` Andre Przywara
2017-05-25 18:55           ` Stefano Stabellini
2017-05-25 20:17             ` Julien Grall
2017-05-25 20:44               ` Stefano Stabellini
2017-05-26  8:16                 ` Andre Przywara
2017-05-11 17:53 ` [PATCH v9 20/28] ARM: GICv3: handle unmapped LPIs Andre Przywara
2017-05-17 18:37   ` Julien Grall
2017-05-20  1:25   ` Stefano Stabellini
2017-05-22 23:48     ` Stefano Stabellini
2017-05-23 11:10       ` Julien Grall
2017-05-23 18:23         ` Stefano Stabellini
2017-05-24  9:47           ` Julien Grall
2017-05-24 17:49             ` Stefano Stabellini
2017-05-23 14:41     ` Andre Przywara
2017-05-11 17:53 ` [PATCH v9 21/28] ARM: vITS: handle MAPTI command Andre Przywara
2017-05-18 14:04   ` Julien Grall
2017-05-22 23:39   ` Stefano Stabellini
2017-05-23 10:01     ` Andre Przywara
2017-05-23 17:44       ` Stefano Stabellini
2017-05-11 17:53 ` [PATCH v9 22/28] ARM: vITS: handle MOVI command Andre Przywara
2017-05-18 14:17   ` Julien Grall
2017-05-23  0:28   ` Stefano Stabellini
2017-05-11 17:53 ` [PATCH v9 23/28] ARM: vITS: handle DISCARD command Andre Przywara
2017-05-18 14:23   ` Julien Grall
2017-05-22 16:50     ` Andre Przywara
2017-05-22 17:20       ` Julien Grall
2017-05-23  9:40         ` Andre Przywara
2017-05-11 17:53 ` [PATCH v9 24/28] ARM: vITS: handle INV command Andre Przywara
2017-05-23  0:01   ` Stefano Stabellini
2017-05-11 17:53 ` [PATCH v9 25/28] ARM: vITS: handle INVALL command Andre Przywara
2017-06-02 17:24   ` Julien Grall
2017-06-02 17:25     ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 26/28] ARM: vITS: increase mmio_count for each ITS Andre Przywara
2017-05-18 14:34   ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 27/28] ARM: vITS: create and initialize virtual ITSes for Dom0 Andre Przywara
2017-05-18 14:41   ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 28/28] ARM: vITS: create ITS subnodes for Dom0 DT Andre Przywara
2017-05-11 18:31 ` [PATCH v9 00/28] arm64: Dom0 ITS emulation Julien Grall

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=3767a1b6-3449-cf8a-18a3-4543a408608b@arm.com \
    --to=andre.przywara@arm.com \
    --cc=Vijaya.Kumar@caviumnetworks.com \
    --cc=julien.grall@arm.com \
    --cc=nd@arm.com \
    --cc=shankerd@codeaurora.org \
    --cc=sstabellini@kernel.org \
    --cc=vijay.kilari@gmail.com \
    --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).