All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Beulich <jbeulich@suse.com>
To: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: "Roger Pau Monné" <roger.pau@citrix.com>,
	"Stefano Stabellini" <sstabellini@kernel.org>,
	"Julien Grall" <julien@xen.org>,
	"Volodymyr Babchuk" <Volodymyr_Babchuk@epam.com>,
	"Bertrand Marquis" <bertrand.marquis@arm.com>,
	"Michal Orzel" <michal.orzel@amd.com>,
	"Oleksii Kurochko" <oleksii.kurochko@gmail.com>,
	Xen-devel <xen-devel@lists.xenproject.org>
Subject: Re: [PATCH v2 4/4] x86/vmx: Rewrite vmx_sync_pir_to_irr() to be more efficient
Date: Thu, 29 Aug 2024 08:35:56 +0200	[thread overview]
Message-ID: <84476add-72a3-46c0-84a8-aeb91307ff22@suse.com> (raw)
In-Reply-To: <cb2609f0-ed06-40ab-9983-9dad59c589d9@citrix.com>

On 28.08.2024 20:08, Andrew Cooper wrote:
> On 28/08/2024 10:19 am, Jan Beulich wrote:
>> On 27.08.2024 15:57, Andrew Cooper wrote:
>>> There are two issues.  First, pi_test_and_clear_on() pulls the cache-line to
>>> the CPU and dirties it even if there's nothing outstanding, but the final
>>> for_each_set_bit() is O(256) when O(8) would do,
>> Nit: That's bitmap_for_each() now, I think. And again ...
>>
>>> and would avoid multiple
>>> atomic updates to the same IRR word.
>>>
>>> Rewrite it from scratch, explaining what's going on at each step.
>>>
>>> Bloat-o-meter reports 177 -> 145 (net -32), but the better aspect is the
>>> removal calls to __find_{first,next}_bit() hidden behind for_each_set_bit().
>> ... here, and no underscore prefixes on the two find functions.
> 
> Yes, and fixed.
> 
>>
>>> --- a/xen/arch/x86/hvm/vmx/vmx.c
>>> +++ b/xen/arch/x86/hvm/vmx/vmx.c
>>> @@ -2317,18 +2317,72 @@ static void cf_check vmx_deliver_posted_intr(struct vcpu *v, u8 vector)
>>>  
>>>  static void cf_check vmx_sync_pir_to_irr(struct vcpu *v)
>>>  {
>>> -    struct vlapic *vlapic = vcpu_vlapic(v);
>>> -    unsigned int group, i;
>>> -    DECLARE_BITMAP(pending_intr, X86_NR_VECTORS);
>>> +    struct pi_desc *desc = &v->arch.hvm.vmx.pi_desc;
>>> +    union {
>>> +        uint64_t _64[X86_NR_VECTORS / (sizeof(uint64_t) * 8)];
>> Using unsigned long here would imo be better, as that's what matches
>> struct pi_desc's DECLARE_BITMAP().
> 
> Why?  It was also the primary contribution to particularly-bad code
> generation in this function.

I answered the "why" already: Because of you copying from something ...

>>> +        uint32_t _32[X86_NR_VECTORS / (sizeof(uint32_t) * 8)];
>>> +    } vec;
>>> +    uint32_t *irr;
>>> +    bool on;
>>>  
>>> -    if ( !pi_test_and_clear_on(&v->arch.hvm.vmx.pi_desc) )
>>> +    /*
>>> +     * The PIR is a contended cacheline which bounces between the CPU(s) and
>>> +     * IOMMU(s).  An IOMMU updates the entire PIR atomically, but we can't
>>> +     * express the same on the CPU side, so care has to be taken.
>>> +     *
>>> +     * First, do a plain read of ON.  If the PIR hasn't been modified, this
>>> +     * will keep the cacheline Shared and not pull it Excusive on the current
>>> +     * CPU.
>>> +     */
>>> +    if ( !pi_test_on(desc) )
>>>          return;
>>>  
>>> -    for ( group = 0; group < ARRAY_SIZE(pending_intr); group++ )
>>> -        pending_intr[group] = pi_get_pir(&v->arch.hvm.vmx.pi_desc, group);
>>> +    /*
>>> +     * Second, if the plain read said that ON was set, we must clear it with
>>> +     * an atomic action.  This will bring the cachline to Exclusive on the
>> Nit (from my spell checker): cacheline.
>>
>>> +     * current CPU.
>>> +     *
>>> +     * This should always succeed because noone else should be playing with
>>> +     * the PIR behind our back, but assert so just in case.
>>> +     */
>>> +    on = pi_test_and_clear_on(desc);
>>> +    ASSERT(on);
>>> +
>>> +    /*
>>> +     * The cacheline is now Exclusive on the current CPU, and because ON was
>> "is" is pretty ambitious. We can only hope it (still) is.
> 
> I can't think of a clearer way of saying this.  "will have become
> Exclusive" perhaps, but this is getting into some subtle tense gymnastics.
> 
>>> +     * get it back again.
>>> +     */
>>> +    for ( unsigned int i = 0; i < ARRAY_SIZE(vec._64); ++i )
>>> +        vec._64[i] = xchg(&desc->pir[i], 0);

... that is the result of DECLARE_BITMAP(), i.e. an array of unsigned longs.
If you make that part of the new union unsigned long[] too, you'll have code
which is bitness-independent (i.e. would also have worked correctly in 32-bit
Xen, and would work correctly in hypothetical 128-bit Xen). I don't think the
array _type_ was "the primary contribution to particularly-bad code
generation in this function"; it was how that bitmap was used.

Jan


      parent reply	other threads:[~2024-08-29  6:36 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-27 13:57 [PATCH 0/4] xen/bitops: More for_each_bit() conversions Andrew Cooper
2024-08-27 13:57 ` [PATCH 1/4] xen/evtchn: Use bitmap_for_each() in evtchn_check_pollers() Andrew Cooper
2024-08-27 15:57   ` Jan Beulich
2024-08-27 13:57 ` [PATCH 2/4] x86/hvm: Use for_each_set_bit() in hvm_emulate_writeback() Andrew Cooper
2024-08-27 16:07   ` Jan Beulich
2024-08-28 14:44     ` Andrew Cooper
2024-08-28 14:56       ` Jan Beulich
2024-08-28 18:56         ` Andrew Cooper
2024-08-29  6:13           ` Jan Beulich
2024-08-27 13:57 ` [PATCH 3/4] x86/hvm: Rework hpet_write() for improved code generation Andrew Cooper
2024-08-28  8:13   ` Jan Beulich
2024-08-28 17:50     ` Andrew Cooper
2024-08-29  6:25       ` Jan Beulich
2024-08-27 13:57 ` [PATCH v2 4/4] x86/vmx: Rewrite vmx_sync_pir_to_irr() to be more efficient Andrew Cooper
2024-08-27 16:25   ` Andrew Cooper
2024-08-28  9:19   ` Jan Beulich
2024-08-28 18:08     ` Andrew Cooper
2024-08-28 19:36       ` Andrew Cooper
2024-08-29  6:35       ` Jan Beulich [this message]

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=84476add-72a3-46c0-84a8-aeb91307ff22@suse.com \
    --to=jbeulich@suse.com \
    --cc=Volodymyr_Babchuk@epam.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=bertrand.marquis@arm.com \
    --cc=julien@xen.org \
    --cc=michal.orzel@amd.com \
    --cc=oleksii.kurochko@gmail.com \
    --cc=roger.pau@citrix.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.