All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@siemens.com>
To: Liu Ping Fan <qemulist@gmail.com>
Cc: Cam Macdonell <cam@cs.ualberta.ca>,
	"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>
Subject: Re: [Qemu-devel] [PATCH] ivshmem: use irqfd to interrupt among VMs
Date: Wed, 21 Nov 2012 13:43:06 +0100	[thread overview]
Message-ID: <50ACCC5A.80204@siemens.com> (raw)
In-Reply-To: <1353477751-9846-1-git-send-email-qemulist@gmail.com>

On 2012-11-21 07:02, Liu Ping Fan wrote:
> From: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> 
> Using irqfd, so we can avoid switch between kernel and user when
> VMs interrupts each other.
> 
> Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
> ---
>  hw/ivshmem.c |   48 +++++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 47 insertions(+), 1 deletions(-)
> 
> diff --git a/hw/ivshmem.c b/hw/ivshmem.c
> index f6dbb21..81c7354 100644
> --- a/hw/ivshmem.c
> +++ b/hw/ivshmem.c
> @@ -19,6 +19,7 @@
>  #include "hw.h"
>  #include "pc.h"
>  #include "pci.h"
> +#include "msi.h"
>  #include "msix.h"
>  #include "kvm.h"
>  #include "migration.h"
> @@ -54,6 +55,11 @@ typedef struct EventfdEntry {
>      int vector;
>  } EventfdEntry;
>  
> +typedef struct IrqfdEntry {
> +    int virq;
> +    bool used;

used = (virq != -1), so it should be redundant, and you can reduce
IrqfdEntry to a plain int holding the virq.

> +} IrqfdEntry;
> +
>  typedef struct IVShmemState {
>      PCIDevice dev;
>      uint32_t intrmask;
> @@ -83,6 +89,8 @@ typedef struct IVShmemState {
>      uint32_t vectors;
>      uint32_t features;
>      EventfdEntry *eventfd_table;
> +    IrqfdEntry *vector_irqfd;
> +    bool irqfd_enable;
>  
>      Error *migration_blocker;
>  
> @@ -632,6 +640,38 @@ static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address,
>      msix_write_config(pci_dev, address, val, len);
>  }
>  
> +static int ivshmem_vector_use(PCIDevice *dev, unsigned vector,
> +                                     MSIMessage msg)
> +{
> +    IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
> +    int virq;
> +    EventNotifier *n = &s->peers[s->vm_id].eventfds[vector];
> +
> +    virq = kvm_irqchip_add_msi_route(kvm_state, msg);
> +    if (virq >= 0 && kvm_irqchip_add_irqfd_notifier(kvm_state, n, virq) >= 0) {
> +        s->vector_irqfd[vector].virq = virq;
> +        s->vector_irqfd[vector].used = true;
> +        qemu_chr_add_handlers(s->eventfd_chr[vector], NULL, NULL, NULL, NULL);
> +    } else if (virq >= 0) {
> +        kvm_irqchip_release_virq(kvm_state, virq);
> +    }
> +    return 0;

You drop the errors here. Better refactor the code to a scheme like this:

err = service();
if (err) {
    roll_back();
    return err;
    /* or: goto roll_back_... */
}

> +}
> +
> +static void ivshmem_vector_release(PCIDevice *dev, unsigned vector)
> +{
> +    IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
> +    EventNotifier *n = &s->peers[s->vm_id].eventfds[vector];
> +    int virq = s->vector_irqfd[vector].virq;
> +
> +    if (s->vector_irqfd[vector].used) {
> +        kvm_irqchip_remove_irqfd_notifier(kvm_state, n, virq);
> +        kvm_irqchip_release_virq(kvm_state, virq);
> +        s->vector_irqfd[vector].virq = -1;
> +        s->vector_irqfd[vector].used = false;
> +    }
> +}
> +
>  static int pci_ivshmem_init(PCIDevice *dev)
>  {
>      IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
> @@ -759,7 +799,13 @@ static int pci_ivshmem_init(PCIDevice *dev)
>      }
>  
>      s->dev.config_write = ivshmem_write_config;
> -
> +    if (kvm_gsi_routing_enabled()) {
> +        s->irqfd_enable = msix_set_vector_notifiers(dev, ivshmem_vector_use,
> +                    ivshmem_vector_release) >= 0 ? true : false;
> +        if (s->irqfd_enable) {
> +            s->vector_irqfd = g_new0(IrqfdEntry, s->vectors);

Conceptually, msix_set_vector_notifiers can already call
ivshmem_vector_use, so this initialization would come too late. Doesn't
happen here as MSI-X is still off during device init. However, just
perform vector_irqfd allocation unconditionally before the registration.

And where do you free it again...?

> +        }
> +    }
>      return 0;
>  }
>  
> 

Jan

-- 
Siemens AG, Corporate Technology, CT RTC ITP SDP-DE
Corporate Competence Center Embedded Linux

  reply	other threads:[~2012-11-21 12:43 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-21  6:02 [Qemu-devel] [PATCH] ivshmem: use irqfd to interrupt among VMs Liu Ping Fan
2012-11-21 12:43 ` Jan Kiszka [this message]
2012-11-22  2:48   ` liu ping fan
2012-11-22 11:40     ` Jan Kiszka
2012-11-23  2:20       ` liu ping fan

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=50ACCC5A.80204@siemens.com \
    --to=jan.kiszka@siemens.com \
    --cc=cam@cs.ualberta.ca \
    --cc=qemu-devel@nongnu.org \
    --cc=qemulist@gmail.com \
    /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.