From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52942) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bIaWl-0001zz-1V for qemu-devel@nongnu.org; Thu, 30 Jun 2016 07:53:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bIaWg-0006RO-15 for qemu-devel@nongnu.org; Thu, 30 Jun 2016 07:53:02 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:43508 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bIaWf-0006Pz-Sc for qemu-devel@nongnu.org; Thu, 30 Jun 2016 07:52:57 -0400 Received: from pps.filterd (m0098414.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.11/8.16.0.11) with SMTP id u5UBnSw7059445 for ; Thu, 30 Jun 2016 07:52:55 -0400 Received: from e06smtp14.uk.ibm.com (e06smtp14.uk.ibm.com [195.75.94.110]) by mx0b-001b2d01.pphosted.com with ESMTP id 23utca9j8g-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Thu, 30 Jun 2016 07:52:55 -0400 Received: from localhost by e06smtp14.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 30 Jun 2016 12:52:53 +0100 Received: from b06cxnps4076.portsmouth.uk.ibm.com (d06relay13.portsmouth.uk.ibm.com [9.149.109.198]) by d06dlp01.portsmouth.uk.ibm.com (Postfix) with ESMTP id 71EDA17D8056 for ; Thu, 30 Jun 2016 12:54:12 +0100 (BST) Received: from d06av09.portsmouth.uk.ibm.com (d06av09.portsmouth.uk.ibm.com [9.149.37.250]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u5UBqpTo5505304 for ; Thu, 30 Jun 2016 11:52:51 GMT Received: from d06av09.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av09.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u5UBqpOE009438 for ; Thu, 30 Jun 2016 05:52:51 -0600 From: Cornelia Huck Date: Thu, 30 Jun 2016 13:52:47 +0200 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Message-Id: <1467287567-2632-1-git-send-email-cornelia.huck@de.ibm.com> Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH v2] virtio: Fix setting up host notifiers for vhost List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: mst@redhat.com, famz@redhat.com, stefanha@redhat.com, jasowang@redhat.com, pl@kamp.de, marcandre.lureau@gmail.com, pbonzini@redhat.com, Cornelia Huck When setting up host notifiers, virtio_bus_set_host_notifier() simply switches the handler. This will only work, however, if the ioeventfd has already been setup; this is true for dataplane, but not for vhost, and will completely break things if the ioeventfd is disabled for the device. Fix this by starting the ioeventfd on assign if that has not happened before, and only switch the handler if the ioeventfd has really been started. While we're at it, also fixup the unsetting path of set_host_notifier_internal(). Fixes: 6798e245a3 ("virtio-bus: common ioeventfd infrastructure") Reported-by: Jason Wang Reported-by: Marc-Andr=C3=A9 Lureau Signed-off-by: Cornelia Huck --- Changes v1->v2: - don't switch the handler if the eventfd has not been setup - this fixes the failure of vhost-user-test for me - add more comments --- hw/virtio/virtio-bus.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c index 1313760..dfe24fc 100644 --- a/hw/virtio/virtio-bus.c +++ b/hw/virtio/virtio-bus.c @@ -176,8 +176,8 @@ static int set_host_notifier_internal(DeviceState *pr= oxy, VirtioBusState *bus, return r; } } else { - virtio_queue_set_host_notifier_fd_handler(vq, false, false); k->ioeventfd_assign(proxy, notifier, n, assign); + virtio_queue_set_host_notifier_fd_handler(vq, false, false); event_notifier_cleanup(notifier); } return r; @@ -246,6 +246,9 @@ void virtio_bus_stop_ioeventfd(VirtioBusState *bus) /* * This function switches from/to the generic ioeventfd handler. * assign=3D=3Dfalse means 'use generic ioeventfd handler'. + * It is only considered an error if the binding does not support + * host notifiers at all, not when they are not available for the + * individual device. */ int virtio_bus_set_host_notifier(VirtioBusState *bus, int n, bool assign= ) { @@ -259,6 +262,13 @@ int virtio_bus_set_host_notifier(VirtioBusState *bus= , int n, bool assign) } if (assign) { /* + * Not yet started? assign=3D=3Dtrue implies we want to use an + * eventfd, so let's do the requisite setup. + */ + if (!k->ioeventfd_started(proxy)) { + virtio_bus_start_ioeventfd(bus); + } + /* * Stop using the generic ioeventfd, we are doing eventfd handli= ng * ourselves below */ @@ -269,8 +279,13 @@ int virtio_bus_set_host_notifier(VirtioBusState *bus= , int n, bool assign) * Otherwise, there's a window where we don't have an * ioeventfd and we may end up with a notification where * we don't expect one. + * + * Also note that we should only do something with the eventfd + * handler if the eventfd has actually been setup. */ - virtio_queue_set_host_notifier_fd_handler(vq, assign, !assign); + if (k->ioeventfd_started(proxy)) { + virtio_queue_set_host_notifier_fd_handler(vq, assign, !assign); + } if (!assign) { /* Use generic ioeventfd handler again. */ k->ioeventfd_set_disabled(proxy, false); --=20 2.6.6