From patchwork Sun Dec 12 15:02:07 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 75252 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 971BEB7082 for ; Mon, 13 Dec 2010 02:09:49 +1100 (EST) Received: from localhost ([127.0.0.1]:36288 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PRnYX-0001Oe-JP for incoming@patchwork.ozlabs.org; Sun, 12 Dec 2010 10:09:45 -0500 Received: from [140.186.70.92] (port=36219 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PRnRT-0005z7-Bz for qemu-devel@nongnu.org; Sun, 12 Dec 2010 10:02:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PRnRR-0004TJ-5G for qemu-devel@nongnu.org; Sun, 12 Dec 2010 10:02:26 -0500 Received: from mail-ww0-f53.google.com ([74.125.82.53]:52318) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PRnRQ-0004T6-Q1 for qemu-devel@nongnu.org; Sun, 12 Dec 2010 10:02:25 -0500 Received: by wwi18 with SMTP id 18so5160099wwi.10 for ; Sun, 12 Dec 2010 07:02:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer:in-reply-to:references; bh=E918rnmjmcrRu5gNnDv6oGVZ0GLYdkTwVwmC/61Lqy4=; b=hkBCK7sPOwfh2d/dnbOYIrKHDAuQdThWf0v3+GSdF7VE4AUR4QlL1gUNs3RMmfzsnU cLo84iA0V5zEoIfuj8T7eSiG2PObrzV7KGDWsWR0QlyTiFNUd7ZHIoyvhT9tLb+z8HAj qOPXfYdbi3b/sQygwiYmbsrTszDqINKRVxnwI= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=RBILOd04RBI4gOepHXVftR8U2folnRn5M6X/zLD5VTDKRUIrlcMfe4LY/xfgfz5KKG pn51CKzsdtFde8LRyFT1Z1xMMUUEWfLkdQha61WKiP8C2yBoFxpfA7MFVDubG5wUODIM yd0f3vOaWudkV6StKxTssEOuHw9ed/VLVAtD8= Received: by 10.216.181.80 with SMTP id k58mr3312592wem.65.1292166143788; Sun, 12 Dec 2010 07:02:23 -0800 (PST) Received: from localhost.localdomain ([109.224.133.37]) by mx.google.com with ESMTPS id m7sm2556987wer.42.2010.12.12.07.02.22 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sun, 12 Dec 2010 07:02:23 -0800 (PST) From: Stefan Hajnoczi To: Date: Sun, 12 Dec 2010 15:02:07 +0000 Message-Id: <1292166128-10874-4-git-send-email-stefanha@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1292166128-10874-1-git-send-email-stefanha@linux.vnet.ibm.com> References: <1292166128-10874-1-git-send-email-stefanha@linux.vnet.ibm.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Cc: Stefan Hajnoczi , "Michael S. Tsirkin" Subject: [Qemu-devel] [PATCH v5 3/4] virtio-pci: Don't use ioeventfd on old kernels X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org There used to be a limit of 6 KVM io bus devices inside the kernel. On such a kernel, don't use ioeventfd for virtqueue host notification since the limit is reached too easily. This ensures that existing vhost-net setups (which always use ioeventfd) have ioeventfds available so they can continue to work. Signed-off-by: Stefan Hajnoczi --- hw/virtio-pci.c | 4 ++++ kvm-all.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ kvm-stub.c | 5 +++++ kvm.h | 1 + 4 files changed, 59 insertions(+), 0 deletions(-) diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index f57c45a..db0df67 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -690,6 +690,10 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, pci_register_bar(&proxy->pci_dev, 0, size, PCI_BASE_ADDRESS_SPACE_IO, virtio_map); + if (!kvm_has_many_ioeventfds()) { + proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD; + } + virtio_bind_device(vdev, &virtio_pci_bindings, proxy); proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY; proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE; diff --git a/kvm-all.c b/kvm-all.c index cae24bb..255b6fa 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -28,6 +28,11 @@ #include "kvm.h" #include "bswap.h" +/* This check must be after config-host.h is included */ +#ifdef CONFIG_EVENTFD +#include +#endif + /* KVM uses PAGE_SIZE in it's definition of COALESCED_MMIO_MAX */ #define PAGE_SIZE TARGET_PAGE_SIZE @@ -72,6 +77,7 @@ struct KVMState int irqchip_in_kernel; int pit_in_kernel; int xsave, xcrs; + int many_ioeventfds; }; static KVMState *kvm_state; @@ -441,6 +447,39 @@ int kvm_check_extension(KVMState *s, unsigned int extension) return ret; } +static int kvm_check_many_ioeventfds(void) +{ + /* Older kernels have a 6 device limit on the KVM io bus. Find out so we + * can avoid creating too many ioeventfds. + */ +#ifdef CONFIG_EVENTFD + int ioeventfds[7]; + int i, ret = 0; + for (i = 0; i < ARRAY_SIZE(ioeventfds); i++) { + ioeventfds[i] = eventfd(0, EFD_CLOEXEC); + if (ioeventfds[i] < 0) { + break; + } + ret = kvm_set_ioeventfd_pio_word(ioeventfds[i], 0, i, true); + if (ret < 0) { + close(ioeventfds[i]); + break; + } + } + + /* Decide whether many devices are supported or not */ + ret = i == ARRAY_SIZE(ioeventfds); + + while (i-- > 0) { + kvm_set_ioeventfd_pio_word(ioeventfds[i], 0, i, false); + close(ioeventfds[i]); + } + return ret; +#else + return 0; +#endif +} + static void kvm_set_phys_mem(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset) @@ -717,6 +756,8 @@ int kvm_init(int smp_cpus) kvm_state = s; cpu_register_phys_memory_client(&kvm_cpu_phys_memory_client); + s->many_ioeventfds = kvm_check_many_ioeventfds(); + return 0; err: @@ -1046,6 +1087,14 @@ int kvm_has_xcrs(void) return kvm_state->xcrs; } +int kvm_has_many_ioeventfds(void) +{ + if (!kvm_enabled()) { + return 0; + } + return kvm_state->many_ioeventfds; +} + void kvm_setup_guest_memory(void *start, size_t size) { if (!kvm_has_sync_mmu()) { diff --git a/kvm-stub.c b/kvm-stub.c index 5384a4b..33d4476 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -99,6 +99,11 @@ int kvm_has_robust_singlestep(void) return 0; } +int kvm_has_many_ioeventfds(void) +{ + return 0; +} + void kvm_setup_guest_memory(void *start, size_t size) { } diff --git a/kvm.h b/kvm.h index 60a9b42..ce08d42 100644 --- a/kvm.h +++ b/kvm.h @@ -42,6 +42,7 @@ int kvm_has_robust_singlestep(void); int kvm_has_debugregs(void); int kvm_has_xsave(void); int kvm_has_xcrs(void); +int kvm_has_many_ioeventfds(void); #ifdef NEED_CPU_H int kvm_init_vcpu(CPUState *env);