All of lore.kernel.org
 help / color / mirror / Atom feed
From: Avi Kivity <avi@redhat.com>
To: Cam Macdonell <cam@cs.ualberta.ca>
Cc: kvm@vger.kernel.org, qemu-devel@nongnu.org
Subject: Re: [PATCH v4 3/3] Inter-VM shared memory PCI device
Date: Mon, 12 Apr 2010 23:56:15 +0300	[thread overview]
Message-ID: <4BC388EF.8000706@redhat.com> (raw)
In-Reply-To: <1270680720-8457-4-git-send-email-cam@cs.ualberta.ca>

On 04/08/2010 01:52 AM, Cam Macdonell wrote:
> Support an inter-vm shared memory device that maps a shared-memory object as a
> PCI device in the guest.  This patch also supports interrupts between guest by
> communicating over a unix domain socket.  This patch applies to the qemu-kvm
> repository.
>
>      -device ivshmem,size=<size in MB>[,shm=<shm name>]
>    

Can that be <size in format accepted by -m> (2M, 4G, 19T, ...).

> Interrupts are supported between multiple VMs by using a shared memory server
> by using a chardev socket.
>
>      -device ivshmem,size=<size in MB>[,shm=<shm name>][,chardev=<id>][,msi=on]
>              [,irqfd=on][,vectors=n]
>      -chardev socket,path=<path>,id=<id>
>    

Do we need the irqfd parameter?  Should be on by default.

On the other hand, it may fail with older kernels with limited irqfd 
slots, so better keep it there.

> Sample programs, init scripts and the shared memory server are available in a
> git repo here:
>
>      www.gitorious.org/nahanni
>    

Please consider qemu.git/contrib.

> ---
>   Makefile.target |    3 +
>   hw/ivshmem.c    |  700 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   qemu-char.c     |    6 +
>   qemu-char.h     |    3 +
>    

qemu-doc.texi | 45 +++++++++++++

>   4 files changed, 712 insertions(+), 0 deletions(-)
>   create mode 100644 hw/ivshmem.c
>
> diff --git a/Makefile.target b/Makefile.target
> index 1ffd802..bc9a681 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -199,6 +199,9 @@ obj-$(CONFIG_USB_OHCI) += usb-ohci.o
>   obj-y += rtl8139.o
>   obj-y += e1000.o
>
> +# Inter-VM PCI shared memory
> +obj-y += ivshmem.o
> +
>    

depends on CONFIG_PCI

>   # Hardware support
> +
> +#define PCI_COMMAND_IOACCESS                0x0001
> +#define PCI_COMMAND_MEMACCESS               0x0002
>    

Should be in pci.h?

> +
> +#define DEBUG_IVSHMEM
>    

Disable for production.

> +
> +#define IVSHMEM_IRQFD   0
> +#define IVSHMEM_MSI     1
> +#define IVSHMEM_MAX_EVENTFDS  16
>    

Too low?  why limit?
> +
> +struct eventfd_entry {
> +    PCIDevice *pdev;
> +    int vector;
> +};
>    

Coding style:  EventfdEntry, and a typedef.

> +
> +typedef struct IVShmemState {
> +    PCIDevice dev;
> +    uint32_t intrmask;
> +    uint32_t intrstatus;
> +    uint32_t doorbell;
> +
> +    CharDriverState * chr;
> +    CharDriverState ** eventfd_chr;
> +    int ivshmem_mmio_io_addr;
> +
> +    pcibus_t mmio_addr;
> +    uint8_t *ivshmem_ptr;
> +    unsigned long ivshmem_offset;
>    

off_t

> +    unsigned int ivshmem_size;
>    

ram_addr_t

> +
> +/* accessing registers - based on rtl8139 */
> +static void ivshmem_update_irq(IVShmemState *s, int val)
> +{
> +    int isr;
> +    isr = (s->intrstatus&  s->intrmask)&  0xffffffff;
>    

This is highly undocumented, but fits my suggested 'status is bitmap'.  
'isr' needs to be uint32_t if you mask it like that.

> +
> +    /* don't print ISR resets */
> +    if (isr) {
> +        IVSHMEM_DPRINTF("Set IRQ to %d (%04x %04x)\n",
> +           isr ? 1 : 0, s->intrstatus, s->intrmask);
> +    }
> +
> +    qemu_set_irq(s->dev.irq[0], (isr != 0));
> +}
> +
> +
>
>
> +
> +static void create_shared_memory_BAR(IVShmemState *s, int fd) {
> +
> +    s->shm_fd = fd;
> +
> +    s->ivshmem_offset = qemu_ram_mmap(s->shm_fd, s->ivshmem_size,
> +             MAP_SHARED, 0);
>    

Where did the offset go?

> +
> +    s->ivshmem_ptr = qemu_get_ram_ptr(s->ivshmem_offset);
>    

Never used, please drop.

> +
> +    /* region for shared memory */
> +    pci_register_bar(&s->dev, 2, s->ivshmem_size,
> +                       PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map);
>    

Might be worthwhile to mark it as a 64-bit BAR.  Please test with 
ridiculous shared memory sizes.

> +}
> +
> +static int ivshmem_irqfd(PCIDevice* pdev, uint16_t vector, int fd)
> +{
> +    struct kvm_irqfd call = { };
> +    int r;
> +
> +    IVSHMEM_DPRINTF("inside irqfd\n");
> +    if (vector>= pdev->msix_entries_nr)
> +        return -EINVAL;
> +    call.fd = fd;
> +    call.gsi = pdev->msix_irq_entries[vector].gsi;
> +    r = kvm_vm_ioctl(kvm_state, KVM_IRQFD,&call);
> +    if (r<  0) {
> +        IVSHMEM_DPRINTF("allocating irqfd failed %d\n", r);
> +        return r;
> +    }
> +    return 0;
> +}
>    

should be in kvm.c for reuse.

> +
> +static int ivshmem_ioeventfd(IVShmemState* s, int posn, int fd, int vector)
> +{
> +
> +    int ret;
> +    struct kvm_ioeventfd iofd;
> +
> +    iofd.datamatch = (posn<<  16) | vector;
> +    iofd.addr = s->mmio_addr + Doorbell;
> +    iofd.len = 4;
> +    iofd.flags = KVM_IOEVENTFD_FLAG_DATAMATCH;
> +    iofd.fd = fd;
> +
> +    ret = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD,&iofd);
>    

Ditto.

> +
> +    if (ret<  0) {
> +        fprintf(stderr, "error assigning ioeventfd (%d)\n", ret);
> +        perror(strerror(ret));
> +    } else {
> +        IVSHMEM_DPRINTF("success assigning ioeventfd (%d:%d)\n", posn, vector);
> +    }
> +
> +    return ret;
> +}
>    

blank line here.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


WARNING: multiple messages have this Message-ID (diff)
From: Avi Kivity <avi@redhat.com>
To: Cam Macdonell <cam@cs.ualberta.ca>
Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org
Subject: [Qemu-devel] Re: [PATCH v4 3/3] Inter-VM shared memory PCI device
Date: Mon, 12 Apr 2010 23:56:15 +0300	[thread overview]
Message-ID: <4BC388EF.8000706@redhat.com> (raw)
In-Reply-To: <1270680720-8457-4-git-send-email-cam@cs.ualberta.ca>

On 04/08/2010 01:52 AM, Cam Macdonell wrote:
> Support an inter-vm shared memory device that maps a shared-memory object as a
> PCI device in the guest.  This patch also supports interrupts between guest by
> communicating over a unix domain socket.  This patch applies to the qemu-kvm
> repository.
>
>      -device ivshmem,size=<size in MB>[,shm=<shm name>]
>    

Can that be <size in format accepted by -m> (2M, 4G, 19T, ...).

> Interrupts are supported between multiple VMs by using a shared memory server
> by using a chardev socket.
>
>      -device ivshmem,size=<size in MB>[,shm=<shm name>][,chardev=<id>][,msi=on]
>              [,irqfd=on][,vectors=n]
>      -chardev socket,path=<path>,id=<id>
>    

Do we need the irqfd parameter?  Should be on by default.

On the other hand, it may fail with older kernels with limited irqfd 
slots, so better keep it there.

> Sample programs, init scripts and the shared memory server are available in a
> git repo here:
>
>      www.gitorious.org/nahanni
>    

Please consider qemu.git/contrib.

> ---
>   Makefile.target |    3 +
>   hw/ivshmem.c    |  700 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   qemu-char.c     |    6 +
>   qemu-char.h     |    3 +
>    

qemu-doc.texi | 45 +++++++++++++

>   4 files changed, 712 insertions(+), 0 deletions(-)
>   create mode 100644 hw/ivshmem.c
>
> diff --git a/Makefile.target b/Makefile.target
> index 1ffd802..bc9a681 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -199,6 +199,9 @@ obj-$(CONFIG_USB_OHCI) += usb-ohci.o
>   obj-y += rtl8139.o
>   obj-y += e1000.o
>
> +# Inter-VM PCI shared memory
> +obj-y += ivshmem.o
> +
>    

depends on CONFIG_PCI

>   # Hardware support
> +
> +#define PCI_COMMAND_IOACCESS                0x0001
> +#define PCI_COMMAND_MEMACCESS               0x0002
>    

Should be in pci.h?

> +
> +#define DEBUG_IVSHMEM
>    

Disable for production.

> +
> +#define IVSHMEM_IRQFD   0
> +#define IVSHMEM_MSI     1
> +#define IVSHMEM_MAX_EVENTFDS  16
>    

Too low?  why limit?
> +
> +struct eventfd_entry {
> +    PCIDevice *pdev;
> +    int vector;
> +};
>    

Coding style:  EventfdEntry, and a typedef.

> +
> +typedef struct IVShmemState {
> +    PCIDevice dev;
> +    uint32_t intrmask;
> +    uint32_t intrstatus;
> +    uint32_t doorbell;
> +
> +    CharDriverState * chr;
> +    CharDriverState ** eventfd_chr;
> +    int ivshmem_mmio_io_addr;
> +
> +    pcibus_t mmio_addr;
> +    uint8_t *ivshmem_ptr;
> +    unsigned long ivshmem_offset;
>    

off_t

> +    unsigned int ivshmem_size;
>    

ram_addr_t

> +
> +/* accessing registers - based on rtl8139 */
> +static void ivshmem_update_irq(IVShmemState *s, int val)
> +{
> +    int isr;
> +    isr = (s->intrstatus&  s->intrmask)&  0xffffffff;
>    

This is highly undocumented, but fits my suggested 'status is bitmap'.  
'isr' needs to be uint32_t if you mask it like that.

> +
> +    /* don't print ISR resets */
> +    if (isr) {
> +        IVSHMEM_DPRINTF("Set IRQ to %d (%04x %04x)\n",
> +           isr ? 1 : 0, s->intrstatus, s->intrmask);
> +    }
> +
> +    qemu_set_irq(s->dev.irq[0], (isr != 0));
> +}
> +
> +
>
>
> +
> +static void create_shared_memory_BAR(IVShmemState *s, int fd) {
> +
> +    s->shm_fd = fd;
> +
> +    s->ivshmem_offset = qemu_ram_mmap(s->shm_fd, s->ivshmem_size,
> +             MAP_SHARED, 0);
>    

Where did the offset go?

> +
> +    s->ivshmem_ptr = qemu_get_ram_ptr(s->ivshmem_offset);
>    

Never used, please drop.

> +
> +    /* region for shared memory */
> +    pci_register_bar(&s->dev, 2, s->ivshmem_size,
> +                       PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map);
>    

Might be worthwhile to mark it as a 64-bit BAR.  Please test with 
ridiculous shared memory sizes.

> +}
> +
> +static int ivshmem_irqfd(PCIDevice* pdev, uint16_t vector, int fd)
> +{
> +    struct kvm_irqfd call = { };
> +    int r;
> +
> +    IVSHMEM_DPRINTF("inside irqfd\n");
> +    if (vector>= pdev->msix_entries_nr)
> +        return -EINVAL;
> +    call.fd = fd;
> +    call.gsi = pdev->msix_irq_entries[vector].gsi;
> +    r = kvm_vm_ioctl(kvm_state, KVM_IRQFD,&call);
> +    if (r<  0) {
> +        IVSHMEM_DPRINTF("allocating irqfd failed %d\n", r);
> +        return r;
> +    }
> +    return 0;
> +}
>    

should be in kvm.c for reuse.

> +
> +static int ivshmem_ioeventfd(IVShmemState* s, int posn, int fd, int vector)
> +{
> +
> +    int ret;
> +    struct kvm_ioeventfd iofd;
> +
> +    iofd.datamatch = (posn<<  16) | vector;
> +    iofd.addr = s->mmio_addr + Doorbell;
> +    iofd.len = 4;
> +    iofd.flags = KVM_IOEVENTFD_FLAG_DATAMATCH;
> +    iofd.fd = fd;
> +
> +    ret = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD,&iofd);
>    

Ditto.

> +
> +    if (ret<  0) {
> +        fprintf(stderr, "error assigning ioeventfd (%d)\n", ret);
> +        perror(strerror(ret));
> +    } else {
> +        IVSHMEM_DPRINTF("success assigning ioeventfd (%d:%d)\n", posn, vector);
> +    }
> +
> +    return ret;
> +}
>    

blank line here.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.

  reply	other threads:[~2010-04-12 20:56 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-07 22:51 [PATCH v4 0/3] PCI Shared memory device Cam Macdonell
2010-04-07 22:51 ` [Qemu-devel] " Cam Macdonell
2010-04-07 22:51 ` [PATCH v4 1/3] Device specification for shared memory PCI device Cam Macdonell
2010-04-07 22:51   ` [Qemu-devel] " Cam Macdonell
2010-04-07 22:51   ` [PATCH v4 2/3] Support adding a file to qemu's ram allocation Cam Macdonell
2010-04-07 22:51     ` [Qemu-devel] " Cam Macdonell
2010-04-07 22:52     ` [PATCH v4 3/3] Inter-VM shared memory PCI device Cam Macdonell
2010-04-07 22:52       ` [Qemu-devel] " Cam Macdonell
2010-04-12 20:56       ` Avi Kivity [this message]
2010-04-12 20:56         ` [Qemu-devel] " Avi Kivity
2010-04-14 23:30         ` Cam Macdonell
2010-04-14 23:30           ` [Qemu-devel] " Cam Macdonell
2010-04-15  8:33           ` Avi Kivity
2010-04-15  8:33             ` [Qemu-devel] " Avi Kivity
2010-04-12 20:38     ` [PATCH v4 2/3] Support adding a file to qemu's ram allocation Avi Kivity
2010-04-12 20:38       ` [Qemu-devel] " Avi Kivity
2010-04-07 23:00   ` [PATCH v4] Shared memory uio_pci driver Cam Macdonell
2010-04-07 23:00     ` [Qemu-devel] " Cam Macdonell
2010-04-12 20:57     ` Avi Kivity
2010-04-12 20:57       ` [Qemu-devel] " Avi Kivity
2010-04-23 17:45       ` Cam Macdonell
2010-04-23 17:45         ` [Qemu-devel] " Cam Macdonell
2010-04-24  9:28         ` Avi Kivity
2010-04-24  9:28           ` [Qemu-devel] " Avi Kivity
2010-04-12 20:34   ` [PATCH v4 1/3] Device specification for shared memory PCI device Avi Kivity
2010-04-12 20:34     ` [Qemu-devel] " Avi Kivity
2010-04-12 21:11     ` Cam Macdonell
2010-04-12 21:11       ` [Qemu-devel] " Cam Macdonell
2010-04-12 21:17 ` [PATCH v4 0/3] PCI Shared memory device Michael S. Tsirkin
2010-04-12 21:17   ` [Qemu-devel] " Michael S. Tsirkin

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=4BC388EF.8000706@redhat.com \
    --to=avi@redhat.com \
    --cc=cam@cs.ualberta.ca \
    --cc=kvm@vger.kernel.org \
    --cc=qemu-devel@nongnu.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.