Message ID | 20190611170336.121706-10-marc.zyngier@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: arm/arm64: vgic: ITS translation cache | expand |
Hi Marc, On 6/11/19 7:03 PM, Marc Zyngier wrote: > Now that we have a cache of MSI->LPI translations, it is pretty > easy to implement kvm_arch_set_irq_inatomic (this cache can be > parsed without sleeping). > > Hopefully, this will improve some LPI-heavy workloads. > > Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> > --- > virt/kvm/arm/vgic/vgic-irqfd.c | 36 ++++++++++++++++++++++++++++------ > 1 file changed, 30 insertions(+), 6 deletions(-) > > diff --git a/virt/kvm/arm/vgic/vgic-irqfd.c b/virt/kvm/arm/vgic/vgic-irqfd.c > index 99e026d2dade..9f203ed8c8f3 100644 > --- a/virt/kvm/arm/vgic/vgic-irqfd.c > +++ b/virt/kvm/arm/vgic/vgic-irqfd.c > @@ -77,6 +77,15 @@ int kvm_set_routing_entry(struct kvm *kvm, > return r; > } > > +static void kvm_populate_msi(struct kvm_kernel_irq_routing_entry *e, > + struct kvm_msi *msi) > +{ > + msi->address_lo = e->msi.address_lo; > + msi->address_hi = e->msi.address_hi; > + msi->data = e->msi.data; > + msi->flags = e->msi.flags; > + msi->devid = e->msi.devid; > +} > /** > * kvm_set_msi: inject the MSI corresponding to the s/:/ - > * MSI routing entry > @@ -90,21 +99,36 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, > { > struct kvm_msi msi; > > - msi.address_lo = e->msi.address_lo; > - msi.address_hi = e->msi.address_hi; > - msi.data = e->msi.data; > - msi.flags = e->msi.flags; > - msi.devid = e->msi.devid; > - > if (!vgic_has_its(kvm)) > return -ENODEV; > > if (!level) > return -1; > > + kvm_populate_msi(e, &msi); > return vgic_its_inject_msi(kvm, &msi); > } > > +/** > + * kvm_arch_set_irq_inatomic: fast-path for irqfd injection s/:/ - > + * > + * Currently only direct MSI injecton is supported. injection > + */ > +int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e, > + struct kvm *kvm, int irq_source_id, int level, > + bool line_status) > +{ > + if (e->type == KVM_IRQ_ROUTING_MSI && vgic_has_its(kvm) && level) { > + struct kvm_msi msi; > + > + kvm_populate_msi(e, &msi); > + if (!vgic_its_inject_cached_translation(kvm, &msi)) > + return 0; if this fails since its->enabled is false we will re-attempt the injection though the normal injection path but that's not a big deal. > + } > + > + return -EWOULDBLOCK; > +} > + > int kvm_vgic_setup_default_irq_routing(struct kvm *kvm) > { > struct kvm_irq_routing_entry *entries; > Reviewed-by: Eric Auger <eric.auger@redhat.com> Thanks Eric
On 23/07/2019 16:14, Auger Eric wrote: > Hi Marc, > > On 6/11/19 7:03 PM, Marc Zyngier wrote: >> Now that we have a cache of MSI->LPI translations, it is pretty >> easy to implement kvm_arch_set_irq_inatomic (this cache can be >> parsed without sleeping). >> >> Hopefully, this will improve some LPI-heavy workloads. >> >> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> >> --- >> virt/kvm/arm/vgic/vgic-irqfd.c | 36 ++++++++++++++++++++++++++++------ >> 1 file changed, 30 insertions(+), 6 deletions(-) >> >> diff --git a/virt/kvm/arm/vgic/vgic-irqfd.c b/virt/kvm/arm/vgic/vgic-irqfd.c >> index 99e026d2dade..9f203ed8c8f3 100644 >> --- a/virt/kvm/arm/vgic/vgic-irqfd.c >> +++ b/virt/kvm/arm/vgic/vgic-irqfd.c >> @@ -77,6 +77,15 @@ int kvm_set_routing_entry(struct kvm *kvm, >> return r; >> } >> >> +static void kvm_populate_msi(struct kvm_kernel_irq_routing_entry *e, >> + struct kvm_msi *msi) >> +{ >> + msi->address_lo = e->msi.address_lo; >> + msi->address_hi = e->msi.address_hi; >> + msi->data = e->msi.data; >> + msi->flags = e->msi.flags; >> + msi->devid = e->msi.devid; >> +} >> /** >> * kvm_set_msi: inject the MSI corresponding to the > s/:/ - >> * MSI routing entry >> @@ -90,21 +99,36 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, >> { >> struct kvm_msi msi; >> >> - msi.address_lo = e->msi.address_lo; >> - msi.address_hi = e->msi.address_hi; >> - msi.data = e->msi.data; >> - msi.flags = e->msi.flags; >> - msi.devid = e->msi.devid; >> - >> if (!vgic_has_its(kvm)) >> return -ENODEV; >> >> if (!level) >> return -1; >> >> + kvm_populate_msi(e, &msi); >> return vgic_its_inject_msi(kvm, &msi); >> } >> >> +/** >> + * kvm_arch_set_irq_inatomic: fast-path for irqfd injection > s/:/ - >> + * >> + * Currently only direct MSI injecton is supported. > injection >> + */ >> +int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e, >> + struct kvm *kvm, int irq_source_id, int level, >> + bool line_status) >> +{ >> + if (e->type == KVM_IRQ_ROUTING_MSI && vgic_has_its(kvm) && level) { >> + struct kvm_msi msi; >> + >> + kvm_populate_msi(e, &msi); >> + if (!vgic_its_inject_cached_translation(kvm, &msi)) >> + return 0; > if this fails since its->enabled is false we will re-attempt the > injection though the normal injection path but that's not a big deal. Yeah, I wouldn't worry about that. If there is a screaming device, so be it. The guest should know better... >> + } >> + >> + return -EWOULDBLOCK; >> +} >> + >> int kvm_vgic_setup_default_irq_routing(struct kvm *kvm) >> { >> struct kvm_irq_routing_entry *entries; >> > Reviewed-by: Eric Auger <eric.auger@redhat.com> Thanks Eric. M.
diff --git a/virt/kvm/arm/vgic/vgic-irqfd.c b/virt/kvm/arm/vgic/vgic-irqfd.c index 99e026d2dade..9f203ed8c8f3 100644 --- a/virt/kvm/arm/vgic/vgic-irqfd.c +++ b/virt/kvm/arm/vgic/vgic-irqfd.c @@ -77,6 +77,15 @@ int kvm_set_routing_entry(struct kvm *kvm, return r; } +static void kvm_populate_msi(struct kvm_kernel_irq_routing_entry *e, + struct kvm_msi *msi) +{ + msi->address_lo = e->msi.address_lo; + msi->address_hi = e->msi.address_hi; + msi->data = e->msi.data; + msi->flags = e->msi.flags; + msi->devid = e->msi.devid; +} /** * kvm_set_msi: inject the MSI corresponding to the * MSI routing entry @@ -90,21 +99,36 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, { struct kvm_msi msi; - msi.address_lo = e->msi.address_lo; - msi.address_hi = e->msi.address_hi; - msi.data = e->msi.data; - msi.flags = e->msi.flags; - msi.devid = e->msi.devid; - if (!vgic_has_its(kvm)) return -ENODEV; if (!level) return -1; + kvm_populate_msi(e, &msi); return vgic_its_inject_msi(kvm, &msi); } +/** + * kvm_arch_set_irq_inatomic: fast-path for irqfd injection + * + * Currently only direct MSI injecton is supported. + */ +int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e, + struct kvm *kvm, int irq_source_id, int level, + bool line_status) +{ + if (e->type == KVM_IRQ_ROUTING_MSI && vgic_has_its(kvm) && level) { + struct kvm_msi msi; + + kvm_populate_msi(e, &msi); + if (!vgic_its_inject_cached_translation(kvm, &msi)) + return 0; + } + + return -EWOULDBLOCK; +} + int kvm_vgic_setup_default_irq_routing(struct kvm *kvm) { struct kvm_irq_routing_entry *entries;
Now that we have a cache of MSI->LPI translations, it is pretty easy to implement kvm_arch_set_irq_inatomic (this cache can be parsed without sleeping). Hopefully, this will improve some LPI-heavy workloads. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> --- virt/kvm/arm/vgic/vgic-irqfd.c | 36 ++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-)