[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v4 05/12] x86/hvm: allowing registering EOI callbacks for GSIs


  • To: Jan Beulich <jbeulich@xxxxxxxx>
  • From: Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Date: Tue, 4 May 2021 12:27:08 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=rMbsXZI1ILwSgYxitoIFgSUXxsw7I48Mp9yc+OCjGCA=; b=TVJcjPwuF4eUoEosVOAQjHj5/yGRYVvth36eVqoBM/pKImEGM5KDEcTieS34OvTgWVSG/Dub+GvTMX5INFuhiiHN2nb+2M7RSbi7kF1Dij28BjhPbK4jfrQP1jcI/onYYSHU1q/l/QpJXgKuZMTXNtC8v0WgRWSw2GBUXo7Bka58GfQntWlmShfJfd0NhUHVG8ziVDwWPvliJ17MryKvQfnK+zffWZpaioX46I7d0XaCpbh2y1+1y9TT0+BraSCOOlyHPhnWZKhl1uwj7ukzJY4UTlLBtO4Ho9wXue3qr0m7uBrQJegWwpbwhvf2y1cQF8AOTE+dxGQQNVE86NpG0Q==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=f+kLTFSEK4mDkfOomMLrnhwT9ZPrg7YlRPK/6GjgnphGUasD2uEeUuO06JORbdo+V4uL+vYizIjV4xqfTfELde4//4dI74nz62ABlrY269iwVeQgWSzV0FILS+t4WBEV54gwNpcGkAIB//psRZ/X/ciXX3jITBn9RnwW0t3HnWAX9kk37LC/fPhhsyFuBRiSR4PayIRqN536oh4wkDwiWYPLD/2TiR3gb1dbBwyFlFLuRDafhnv8QVfEkc+18Y7ffcheHj5LL0zUQ6mwBkz/y30/fg4Yjh6WkUm2xv6uF20RnMP/3dHlqlTIZtgda4mBDl0rUquibkOrhtZ1gNN3Ow==
  • Authentication-results: esa6.hc3370-68.iphmx.com; dkim=pass (signature verified) header.i=@citrix.onmicrosoft.com
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • Delivery-date: Tue, 04 May 2021 10:27:32 +0000
  • Ironport-hdrordr: A9a23:t/huD6ilrcRieYtzMWBGIr09U3BQX2hw3DAbvn1ZSRFFG/Gwv/ uF2NwGyB75jysQUnk8mdaGfJKNW2/Y6IQd2+csFJ+Ydk3DtHGzJI9vqbHjzTrpBjHk+odmup tIW5NVTOf9BV0St6rHySGlDtctx8SG+qi0heHYi0xgVx1udrsI1WdEIyywe3cGIjVuL5w/CZ aa+45rpyC4f24Wc8S8ARA+LpX+jvfMk4/rZgNDOgUu7xOAgSjtxLnxFRWZ2Rl2aUIy/Z4J92 /Znwvlopiyqv3T8G6n60b/zbRz3OHgxNxKGdCWhqEuSwnEpw60aO1aKti/lR8vpuXH0idPrP DtpFMaM913+zfteAiO0GTQ8i3B9Bpr1HP401+fhhLY0L/EbRY3EdBIi44cUjax0TtZgPhG3K hG332UuvNsZHuq9kmNhKmrJmRXv3G5rnY4nekYg2Y3a/pkVJZroZEC50QQKZ8cHUvBmfAaOd NzB8LR7us+SyLiU1nluABUsbuRd0V2NBKHTk8eg9eSwjhbkVtopnFotfA3rzMu8okwRIJD4P mBGqN0lKtWRstTVq5lAvwdKPHHRVDlcFbpCia/MF7nHKYINzbkrIP22qw84KWPdIYTxJU/tZ zdWDpjxCAPUnOrLffL8IxA8xjLTmn4dy/q0Nti659wvaC5bKb3MAWYIWpe0PeIkrE6OIn2Sv yzMJVZD7vINm31A7tE2AX4Rt17NWQeassIodw2Mmj+4v7jG8nPjKj2YfzTLL3iHXIPQWXkGE YOWzD1OYFu9UaudnjkgAXAen/kd0DllKgAVZTyzqw28swgJ4dMug8ahRCS/ceQMwBPtaQwYQ 9fLdrc4+eGjFjz2VyNw3RiOxJbAEoQyq7nSWl2qQgDNF6xVb4Cvt6YaF1DxXfvHG45c+rmVC pk43hn86O+KJKdgQo4Dci8D26ch3wP4FWHUokbga/Gwcv+YJs3AtIHVcVKZET2Pi0wvTwvhH ZIaQcCSEOaPCjpk7+ZgJsdA/yaUcJ9jgetKct9smneqk2YmMEqShIgLnyTeP/SpTxraytfh1 V3/aNaqqGHgyyTJWw2h/l9DEdBc12NALVNDB2MYaJdnryDQnA3cU66wRihzz0jcGvj8Esfwk jsNzedd/3wDl1BgXxAyarx/FRodmKSQlJoZhlBwP9APFWDnkw2/f6AZ6K13WfUUFcEz+0HGB zuYDcZIGpVtpqK/S/QvAzHOWQtx50oMOCYMa8qdKvL3GixbKeSk7sdIvNS9JF5Fdznv+MRS9 iDcwuNID6QMZJx5yWl4lIefAVkongtlv3lnCD/5G+jxXglHL78Jk9lS7xzGaDU00HUA9KzlL N3gtI+sbHubiHfatuaxbrWaDAGABXJumKyR/wpr5cRna9ajsoFI7DrFR/zkFdA11ECCe2xsm U0aqFy+qrANY9iZNZ6QVMTwnMZ0PC0aHI2uQn3CNIkdV4jj3XnL8qEioC43YYHMwmknk/MIl GR/C1WwufdUwaC3bAcDbgsIW4+UjlL1F1SuMeDfZbXEgOkaqVq+0e7KGa0dNZmOeW4MIRVih Zx+NeTmeCLMwL+xQDLpDN+ZoZD6XyuT8/3IAWCH4dzgpCHEGXJpquh+8ioijjrDRO9dkQDnI VAMXUqUf4rsEhrsKQHlg6oSqL2pUo5k1xRpRFf/2SdpLSO0SP8BkFJMQrQn5NMeyJcW0L41f j4zQ==
  • Ironport-sdr: y42Gwvmg6SwfujHWV+n0DnwO6IuuNxfHPkg2Z2zv8dd1wOAwoa0gtQTOjibgUPPoDgIpAQiZqk L/fQiyfKIlm+E5HVMlAzAAR4I6A7Im70e1CeUXQuqHUtQjuQQdAqTva8/IcGOnMdYJv54oTV+9 8yvOOjhZ3HM/sMe4NWlLW7DHqpy/RnCGh6lTe2/wL7mIqG0JCe/g+CuDSJdWqaJhb2bZ2sWQ/B vg5IoFLLizU6SOahDoHl6e1sQOzIZcfJ/vIbi7+ahJTIAmH5h8wwB3Ubbqariz05sfuPP4gRq1 WWc=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On Mon, May 03, 2021 at 05:50:39PM +0200, Jan Beulich wrote:
> On 20.04.2021 16:07, Roger Pau Monne wrote:
> > Such callbacks will be executed once a EOI is performed by the guest,
> > regardless of whether the interrupts are injected from the vIO-APIC or
> > the vPIC, as ISA IRQs are translated to GSIs and then the
> > corresponding callback is executed at EOI.
> > 
> > The vIO-APIC infrastructure for handling EOIs is build on top of the
> > existing vlapic EOI callback functionality, while the vPIC one is
> > handled when writing to the vPIC EOI register.
> > 
> > Note that such callbacks need to be registered and de-registered, and
> > that a single GSI can have multiple callbacks associated. That's
> > because GSIs can be level triggered and shared, as that's the case
> > with legacy PCI interrupts shared between several devices.
> > 
> > Strictly speaking this is a non-functional change, since there are no
> > users of this new interface introduced by this change.
> > 
> > Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
> 
> In principle, as everything looks functionally correct to me,
> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
> 
> Nevertheless, besides a few remarks further down, I have to admit I'm
> concerned of the direct-to-indirect calls conversion (not just here,
> but also covering earlier patches), which (considering we're talking
> of EOI) I expect may occur quite frequently for at least some guests.

I would expect the vmexit cost for each EOI would shadow any gain
between using direct vs indirect calls.

> There aren't that many different callback functions which get
> registered, are there? Hence I wonder whether enumerating them and
> picking the right one via, say, an enum wouldn't be more efficient
> and still allow elimination of (in the case here) unconditional calls
> to hvm_dpci_eoi() for every EOI.

So for the vlapic (vector) callbacks we have the current consumers:
 - MSI passthrough.
 - vPT.
 - IO-APIC.

For GSI callbacks we have:
 - GSI passthrough.
 - vPT.

I could see about implementing this.

This is also kind of blocked on the RTC stuff, since vPT cannot be
migrated to this new model unless we remove strict_mode or changfe the
logic here to allow GSI callbacks to de-register themselves.

> 
> > --- a/xen/arch/x86/hvm/irq.c
> > +++ b/xen/arch/x86/hvm/irq.c
> > @@ -595,6 +595,81 @@ int hvm_local_events_need_delivery(struct vcpu *v)
> >      return !hvm_interrupt_blocked(v, intack);
> >  }
> >  
> > +int hvm_gsi_register_callback(struct domain *d, unsigned int gsi,
> > +                              struct hvm_gsi_eoi_callback *cb)
> > +{
> > +    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
> > +
> > +    if ( gsi >= hvm_irq->nr_gsis )
> > +    {
> > +        ASSERT_UNREACHABLE();
> > +        return -EINVAL;
> > +    }
> > +
> > +    write_lock(&hvm_irq->gsi_callbacks_lock);
> > +    list_add(&cb->list, &hvm_irq->gsi_callbacks[gsi]);
> > +    write_unlock(&hvm_irq->gsi_callbacks_lock);
> > +
> > +    return 0;
> > +}
> > +
> > +int hvm_gsi_unregister_callback(struct domain *d, unsigned int gsi,
> > +                                struct hvm_gsi_eoi_callback *cb)
> > +{
> > +    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
> > +    const struct list_head *tmp;
> > +    bool found = false;
> > +
> > +    if ( gsi >= hvm_irq->nr_gsis )
> > +    {
> > +        ASSERT_UNREACHABLE();
> > +        return -EINVAL;
> > +    }
> > +
> > +    write_lock(&hvm_irq->gsi_callbacks_lock);
> > +    list_for_each ( tmp, &hvm_irq->gsi_callbacks[gsi] )
> > +        if ( tmp == &cb->list )
> > +        {
> > +            list_del(&cb->list);
> 
> Minor remark: Would passing "tmp" here lead to better generated
> code?

Maybe? I don't mind doing so.

> > @@ -419,13 +421,25 @@ static void eoi_callback(struct vcpu *v, unsigned int 
> > vector, void *data)
> >              if ( is_iommu_enabled(d) )
> >              {
> >                  spin_unlock(&d->arch.hvm.irq_lock);
> > -                hvm_dpci_eoi(d, vioapic->base_gsi + pin);
> > +                hvm_dpci_eoi(d, gsi);
> >                  spin_lock(&d->arch.hvm.irq_lock);
> >              }
> >  
> > +            /*
> > +             * Callbacks don't expect to be executed with any lock held, so
> > +             * drop the lock that protects the vIO-APIC fields from 
> > changing.
> > +             *
> > +             * Note that the redirection entry itself cannot go away, so 
> > upon
> > +             * retaking the lock we only need to avoid making assumptions 
> > on
> > +             * redirection entry field values (ie: recheck the IRR field).
> > +             */
> > +            spin_unlock(&d->arch.hvm.irq_lock);
> > +            hvm_gsi_execute_callbacks(d, gsi);
> > +            spin_lock(&d->arch.hvm.irq_lock);
> 
> While this may be transient in the series, as said before I'm not
> happy about this double unlock/relock sequence. I didn't really
> understand what would be wrong with
> 
>             spin_unlock(&d->arch.hvm.irq_lock);
>             if ( is_iommu_enabled(d) )
>                 hvm_dpci_eoi(d, gsi);
>             hvm_gsi_execute_callbacks(d, gsi);
>             spin_lock(&d->arch.hvm.irq_lock);
> 
> This in particular wouldn't grow but even shrink the later patch
> dropping the call to hvm_dpci_eoi().

Sure.

> > --- a/xen/arch/x86/hvm/vpic.c
> > +++ b/xen/arch/x86/hvm/vpic.c
> > @@ -235,6 +235,8 @@ static void vpic_ioport_write(
> >                  unsigned int pin = __scanbit(pending, 8);
> >  
> >                  ASSERT(pin < 8);
> > +                hvm_gsi_execute_callbacks(current->domain,
> > +                        hvm_isa_irq_to_gsi((addr >> 7) ? (pin | 8) : pin));
> >                  hvm_dpci_eoi(current->domain,
> >                               hvm_isa_irq_to_gsi((addr >> 7) ? (pin | 8) : 
> > pin));
> >                  __clear_bit(pin, &pending);
> > @@ -285,6 +287,8 @@ static void vpic_ioport_write(
> >                  /* Release lock and EOI the physical interrupt (if any). */
> >                  vpic_update_int_output(vpic);
> >                  vpic_unlock(vpic);
> > +                hvm_gsi_execute_callbacks(current->domain,
> > +                        hvm_isa_irq_to_gsi((addr >> 7) ? (pin | 8) : pin));
> >                  hvm_dpci_eoi(current->domain,
> >                               hvm_isa_irq_to_gsi((addr >> 7) ? (pin | 8) : 
> > pin));
> >                  return; /* bail immediately */
> 
> Another presumably minor remark: In the IO-APIC case you insert after
> the call to hvm_dpci_eoi(). I wonder if consistency wouldn't help
> avoid questions of archeologists in a couple of years time.

Hm, sorry, I remember trying to place them in the same order, but
likely messed up the order during some rebase.

Thanks, Roger.



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.