From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55603) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aQaJH-0005ER-2n for qemu-devel@nongnu.org; Tue, 02 Feb 2016 07:43:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aQaJC-00020e-Fp for qemu-devel@nongnu.org; Tue, 02 Feb 2016 07:43:54 -0500 Received: from mx1.redhat.com ([209.132.183.28]:32795) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aQaJC-00020W-6s for qemu-devel@nongnu.org; Tue, 02 Feb 2016 07:43:50 -0500 From: marcandre.lureau@redhat.com Date: Tue, 2 Feb 2016 13:43:35 +0100 Message-Id: <1454417016-3913-8-git-send-email-marcandre.lureau@redhat.com> In-Reply-To: <1454417016-3913-1-git-send-email-marcandre.lureau@redhat.com> References: <1454417016-3913-1-git-send-email-marcandre.lureau@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PULL 7/8] ivshmem: use a single eventfd callback, get rid of CharDriver List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: claudio.fontana@huawei.com, armbru@redhat.com, =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= From: Marc-Andr=C3=A9 Lureau Simplify the interrupt handling by having a single callback on irq&msi cases. Remove usage of CharDriver, replace it with qemu_set_fd_handler(). Use event_notifier_test_and_clear() to read the eventfd. Before this patch, ivshmem writes the first byte received to s->intrstatus. But ivshmem_device_spec.txt says "The status register is set to 1 when an interrupt occurs." Fortunately, the byte usually comes from another ivshmem device, and those always write 1. After this commit, follows the specification, set to 1 when an interrupt occurs. Signed-off-by: Marc-Andr=C3=A9 Lureau Acked-by: Markus Armbruster --- hw/misc/ivshmem.c | 55 ++++++++++++++++++-------------------------------= ------ 1 file changed, 18 insertions(+), 37 deletions(-) diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c index 5f33149..48b7a34 100644 --- a/hw/misc/ivshmem.c +++ b/hw/misc/ivshmem.c @@ -263,15 +263,6 @@ static const MemoryRegionOps ivshmem_mmio_ops =3D { }, }; =20 -static void ivshmem_receive(void *opaque, const uint8_t *buf, int size) -{ - IVShmemState *s =3D opaque; - - IVSHMEM_DPRINTF("ivshmem_receive 0x%02x size: %d\n", *buf, size); - - ivshmem_IntrStatus_write(s, *buf); -} - static int ivshmem_can_receive(void * opaque) { return sizeof(int64_t); @@ -282,15 +273,24 @@ static void ivshmem_event(void *opaque, int event) IVSHMEM_DPRINTF("ivshmem_event %d\n", event); } =20 -static void fake_irqfd(void *opaque, const uint8_t *buf, int size) { - +static void ivshmem_vector_notify(void *opaque) +{ MSIVector *entry =3D opaque; PCIDevice *pdev =3D entry->pdev; IVShmemState *s =3D IVSHMEM(pdev); int vector =3D entry - s->msi_vectors; + EventNotifier *n =3D &s->peers[s->vm_id].eventfds[vector]; + + if (!event_notifier_test_and_clear(n)) { + return; + } =20 IVSHMEM_DPRINTF("interrupt on vector %p %d\n", pdev, vector); - msix_notify(pdev, vector); + if (ivshmem_has_feature(s, IVSHMEM_MSI)) { + msix_notify(pdev, vector); + } else { + ivshmem_IntrStatus_write(s, 1); + } } =20 static int ivshmem_vector_unmask(PCIDevice *dev, unsigned vector, @@ -350,35 +350,16 @@ static void ivshmem_vector_poll(PCIDevice *dev, } } =20 -static CharDriverState* create_eventfd_chr_device(IVShmemState *s, - EventNotifier *n, - int vector) +static void watch_vector_notifier(IVShmemState *s, EventNotifier *n, + int vector) { - /* create a event character device based on the passed eventfd */ int eventfd =3D event_notifier_get_fd(n); - CharDriverState *chr; - - chr =3D qemu_chr_open_eventfd(eventfd); - - if (chr =3D=3D NULL) { - error_report("creating chardriver for eventfd %d failed", eventf= d); - return NULL; - } - qemu_chr_fe_claim_no_fail(chr); =20 /* if MSI is supported we need multiple interrupts */ - if (ivshmem_has_feature(s, IVSHMEM_MSI)) { - s->msi_vectors[vector].pdev =3D PCI_DEVICE(s); - - qemu_chr_add_handlers(chr, ivshmem_can_receive, fake_irqfd, - ivshmem_event, &s->msi_vectors[vector]); - } else { - qemu_chr_add_handlers(chr, ivshmem_can_receive, ivshmem_receive, - ivshmem_event, s); - } - - return chr; + s->msi_vectors[vector].pdev =3D PCI_DEVICE(s); =20 + qemu_set_fd_handler(eventfd, ivshmem_vector_notify, + NULL, &s->msi_vectors[vector]); } =20 static int check_shm_size(IVShmemState *s, int fd, Error **errp) @@ -588,7 +569,7 @@ static void setup_interrupt(IVShmemState *s, int vect= or) =20 if (!with_irqfd) { IVSHMEM_DPRINTF("with eventfd"); - s->eventfd_chr[vector] =3D create_eventfd_chr_device(s, n, vecto= r); + watch_vector_notifier(s, n, vector); } else if (msix_enabled(pdev)) { IVSHMEM_DPRINTF("with irqfd"); if (ivshmem_add_kvm_msi_virq(s, vector) < 0) { --=20 2.5.0