From patchwork Thu Jul 5 15:16:29 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1161271 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id D663D3FE4F for ; Thu, 5 Jul 2012 15:17:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933241Ab2GEPR2 (ORCPT ); Thu, 5 Jul 2012 11:17:28 -0400 Received: from mail-pb0-f46.google.com ([209.85.160.46]:52063 "EHLO mail-pb0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933155Ab2GEPR1 (ORCPT ); Thu, 5 Jul 2012 11:17:27 -0400 Received: by mail-pb0-f46.google.com with SMTP id rp8so12925038pbb.19 for ; Thu, 05 Jul 2012 08:17:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=lA187Y932tELJC/7NIS9+lDq3A7kmoL254GaKR14U7c=; b=fPiqUtj6IfJaoWgAeWFMo4eIdCCYQIAhZ1K266xNnLGDXUGFyJxidZgH39Je/v4xf1 iAMIwWxV3L3Bu0t/YC98DAoNVgfZs0EnOje2VqjejifuqUkHh+rbjBm1fPt/oJTDyiDt leir9O8tqb/IfmzdJWMw1cvSGcIHcbaa3Nvv4SSmXIr7Yk6pxY7bUwWPRPGOfgKFoG86 Y79yzvmwb8Ti7vggrKgabPae4NXnAt3LBSIKvIm/LrrGGZKrFpSlAFHsesx4+juet4Lf kOwqOREoT/ygcGxbl1lDb+gFEPgLHXy71yEg63nVFgWh5xmMovQX5opksaTcqU8LWouH 6a3Q== Received: by 10.68.241.228 with SMTP id wl4mr28520724pbc.51.1341501446971; Thu, 05 Jul 2012 08:17:26 -0700 (PDT) Received: from yakj.usersys.redhat.com (93-34-189-113.ip51.fastwebnet.it. [93.34.189.113]) by mx.google.com with ESMTPS id jv6sm19931888pbc.40.2012.07.05.08.17.22 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 05 Jul 2012 08:17:25 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: avi@redhat.com, mtosatti@redhat.com, kvm@vger.kernel.org, anthony.perard@citrix.com, jan.kiszka@siemens.com, mst@redhat.com, stefano.stabellini@eu.citrix.com Subject: [PATCH uq/master 8/9] virtio: move common ioeventfd handling out of virtio-pci Date: Thu, 5 Jul 2012 17:16:29 +0200 Message-Id: <1341501390-797-9-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.10.2 In-Reply-To: <1341501390-797-1-git-send-email-pbonzini@redhat.com> References: <1341501390-797-1-git-send-email-pbonzini@redhat.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org All transports can use the same event handler for the ioeventfd, though the exact setup (address/memory region) will be specific. This lets virtio use event_notifier_set_handler. Signed-off-by: Paolo Bonzini --- hw/virtio-pci.c | 36 ++---------------------------------- hw/virtio.c | 22 ++++++++++++++++++++++ hw/virtio.h | 1 + 3 files changed, 25 insertions(+), 34 deletions(-) diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index a555728..36770fd 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -173,46 +173,18 @@ static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy, __func__, r); return r; } + virtio_queue_set_host_notifier_fd_handler(vq, true); memory_region_add_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2, true, n, notifier); } else { memory_region_del_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2, true, n, notifier); - /* Handle the race condition where the guest kicked and we deassigned - * before we got around to handling the kick. - */ - if (event_notifier_test_and_clear(notifier)) { - virtio_queue_notify_vq(vq); - } - + virtio_queue_set_host_notifier_fd_handler(vq, false); event_notifier_cleanup(notifier); } return r; } -static void virtio_pci_host_notifier_read(void *opaque) -{ - VirtQueue *vq = opaque; - EventNotifier *n = virtio_queue_get_host_notifier(vq); - if (event_notifier_test_and_clear(n)) { - virtio_queue_notify_vq(vq); - } -} - -static void virtio_pci_set_host_notifier_fd_handler(VirtIOPCIProxy *proxy, - int n, bool assign) -{ - VirtQueue *vq = virtio_get_queue(proxy->vdev, n); - EventNotifier *notifier = virtio_queue_get_host_notifier(vq); - if (assign) { - qemu_set_fd_handler(event_notifier_get_fd(notifier), - virtio_pci_host_notifier_read, NULL, vq); - } else { - qemu_set_fd_handler(event_notifier_get_fd(notifier), - NULL, NULL, NULL); - } -} - static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy) { int n, r; @@ -232,8 +204,6 @@ static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy) if (r < 0) { goto assign_error; } - - virtio_pci_set_host_notifier_fd_handler(proxy, n, true); } proxy->ioeventfd_started = true; return; @@ -244,7 +214,6 @@ assign_error: continue; } - virtio_pci_set_host_notifier_fd_handler(proxy, n, false); r = virtio_pci_set_host_notifier_internal(proxy, n, false); assert(r >= 0); } @@ -266,7 +235,6 @@ static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy) continue; } - virtio_pci_set_host_notifier_fd_handler(proxy, n, false); r = virtio_pci_set_host_notifier_internal(proxy, n, false); assert(r >= 0); } diff --git a/hw/virtio.c b/hw/virtio.c index 168abe4..197edf0 100644 --- a/hw/virtio.c +++ b/hw/virtio.c @@ -988,6 +988,28 @@ EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq) { return &vq->guest_notifier; } + +static void virtio_queue_host_notifier_read(EventNotifier *n) +{ + VirtQueue *vq = container_of(n, VirtQueue, host_notifier); + if (event_notifier_test_and_clear(n)) { + virtio_queue_notify_vq(vq); + } +} + +void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign) +{ + if (assign) { + event_notifier_set_handler(&vq->host_notifier, + virtio_queue_host_notifier_read); + } else { + event_notifier_set_handler(&vq->host_notifier, NULL); + /* Test and clear notifier before after disabling event, + * in case poll callback didn't have time to run. */ + virtio_queue_host_notifier_read(&vq->host_notifier); + } +} + EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq) { return &vq->host_notifier; diff --git a/hw/virtio.h b/hw/virtio.h index 85aabe5..2949485 100644 --- a/hw/virtio.h +++ b/hw/virtio.h @@ -232,6 +232,7 @@ VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n); int virtio_queue_get_id(VirtQueue *vq); EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq); EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq); +void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign); void virtio_queue_notify_vq(VirtQueue *vq); void virtio_irq(VirtQueue *vq); #endif