From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Michael S. Tsirkin" Subject: Re: [PATCHv3 RFC 1/2] kvm: implement kvm_set_msi_inatomic Date: Wed, 13 Jun 2012 18:59:50 +0300 Message-ID: <20120613155950.GB21603@redhat.com> References: <20120613130124.GU580@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: kvm@vger.kernel.org, Jan Kiszka To: Gleb Natapov Return-path: Received: from mx1.redhat.com ([209.132.183.28]:7213 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752875Ab2FMP7T (ORCPT ); Wed, 13 Jun 2012 11:59:19 -0400 Content-Disposition: inline In-Reply-To: <20120613130124.GU580@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: On Wed, Jun 13, 2012 at 04:01:24PM +0300, Gleb Natapov wrote: > On Mon, Jun 11, 2012 at 02:19:22PM +0300, Michael S. Tsirkin wrote: > > We do not want a potential broadcast to all VCPUs to run in > > a host IRQ handler. Implement an API that sends an MSI > > interrupt but only if it's safe from interrupt context, > > that is if it is a unicast. > > > We will still iterate over all vcpus, we may as well deliver to them. Or > you want to avoid a lot of vcpu kicks? This is an intermediate stage (thus RFC) for adding a cache: we can't cache if it's a broadcast. > > Signed-off-by: Michael S. Tsirkin > > --- > > include/linux/kvm_host.h | 2 ++ > > virt/kvm/irq_comm.c | 37 ++++++++++++++++++++++++++++++++----- > > 2 files changed, 34 insertions(+), 5 deletions(-) > > > > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h > > index c446435..ddb476a 100644 > > --- a/include/linux/kvm_host.h > > +++ b/include/linux/kvm_host.h > > @@ -618,6 +618,8 @@ void kvm_get_intr_delivery_bitmask(struct kvm_ioapic *ioapic, > > int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level); > > int kvm_set_msi(struct kvm_kernel_irq_routing_entry *irq_entry, struct kvm *kvm, > > int irq_source_id, int level); > > +int kvm_set_msi_inatomic(struct kvm_kernel_irq_routing_entry *irq_entry, > > + struct kvm *kvm); > > void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin); > > void kvm_register_irq_ack_notifier(struct kvm *kvm, > > struct kvm_irq_ack_notifier *kian); > > diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c > > index 5afb431..3395e03 100644 > > --- a/virt/kvm/irq_comm.c > > +++ b/virt/kvm/irq_comm.c > > @@ -114,13 +114,20 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, > > return r; > > } > > > > -int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, > > - struct kvm *kvm, int irq_source_id, int level) > > +static bool kvm_msi_is_multicast(unsigned dest, int dest_mode) > > { > > - struct kvm_lapic_irq irq; > > + if (dest_mode == 0) > > + /* Physical mode. */ > > + return dest == 0xff; > > + else > > + /* Logical mode. */ > > + return dest & (dest - 1); > > +} > > > > - if (!level) > > - return -1; > > +static int __kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, > > + struct kvm *kvm, bool noblock) > > +{ > > + struct kvm_lapic_irq irq; > > > > trace_kvm_msi_set_irq(e->msi.address_lo, e->msi.data); > > > > @@ -134,10 +141,30 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, > > irq.level = 1; > > irq.shorthand = 0; > > > > + /* Multicast MSI doesn't really block but might take a long time. */ > > + if (unlikely(noblock && kvm_msi_is_multicast(irq.dest_id, > > + irq.delivery_mode))) > delivery_mode? Should be dest_mode. But you probably need to check that > delivery_mode is not ExtINT either. > > > + return -EWOULDBLOCK; > > + > > /* TODO Deal with RH bit of MSI message address */ > > return kvm_irq_delivery_to_apic(kvm, NULL, &irq); > > } > > > > +int kvm_set_msi_inatomic(struct kvm_kernel_irq_routing_entry *e, > > + struct kvm *kvm) > > +{ > > + return __kvm_set_msi(e, kvm, true); > > +} > > + > > +int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, > > + struct kvm *kvm, int irq_source_id, int level) > > +{ > > + if (unlikely(!level)) > > + return -1; > > + > > + return __kvm_set_msi(e, kvm, false); > > +} > > + > > int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi) > > { > > struct kvm_kernel_irq_routing_entry route; > > -- > > MST > > > > -- > > To unsubscribe from this list: send the line "unsubscribe kvm" in > > the body of a message to majordomo@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- > Gleb.