From patchwork Fri Nov 18 05:50:04 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: zanghongyong@huawei.com X-Patchwork-Id: 126349 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 966E9B7256 for ; Fri, 18 Nov 2011 17:46:12 +1100 (EST) Received: from localhost ([::1]:37190 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RRID6-0008U4-GH for incoming@patchwork.ozlabs.org; Fri, 18 Nov 2011 01:46:04 -0500 Received: from eggs.gnu.org ([140.186.70.92]:55334) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RRICz-0008Tz-Nw for qemu-devel@nongnu.org; Fri, 18 Nov 2011 01:45:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RRICy-0000oA-28 for qemu-devel@nongnu.org; Fri, 18 Nov 2011 01:45:57 -0500 Received: from szxga01-in.huawei.com ([119.145.14.64]:35967) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RRICw-0000mc-Fw for qemu-devel@nongnu.org; Fri, 18 Nov 2011 01:45:56 -0500 Received: from huawei.com (szxga05-in [172.24.2.49]) by szxga05-in.huawei.com (iPlanet Messaging Server 5.2 HotFix 2.14 (built Aug 8 2006)) with ESMTP id <0LUU00AS1G3YHD@szxga05-in.huawei.com> for qemu-devel@nongnu.org; Fri, 18 Nov 2011 14:45:35 +0800 (CST) Received: from szxrg02-dlp.huawei.com ([172.24.2.119]) by szxga05-in.huawei.com (iPlanet Messaging Server 5.2 HotFix 2.14 (built Aug 8 2006)) with ESMTP id <0LUU003CBG3WO8@szxga05-in.huawei.com> for qemu-devel@nongnu.org; Fri, 18 Nov 2011 14:45:34 +0800 (CST) Received: from szxeml205-edg.china.huawei.com ([172.24.2.119]) by szxrg02-dlp.huawei.com (MOS 4.1.9-GA) with ESMTP id AFB69491; Fri, 18 Nov 2011 14:44:39 +0800 Received: from SZXEML401-HUB.china.huawei.com (10.82.67.31) by szxeml205-edg.china.huawei.com (172.24.2.57) with Microsoft SMTP Server (TLS) id 14.1.323.3; Fri, 18 Nov 2011 14:44:32 +0800 Received: from localhost.localdomain (10.166.29.43) by szxeml401-hub.china.huawei.com (10.82.67.31) with Microsoft SMTP Server id 14.1.323.3; Fri, 18 Nov 2011 14:44:31 +0800 Date: Fri, 18 Nov 2011 13:50:04 +0800 From: zanghongyong@huawei.com X-Originating-IP: [10.166.29.43] To: avi@redhat.com, qemu-devel@nongnu.org, kvm@vger.kernel.org Message-id: <1321595404-2127-1-git-send-email-zanghongyong@huawei.com> MIME-version: 1.0 X-Mailer: git-send-email 1.7.0.4 Content-type: text/plain Content-transfer-encoding: 7BIT X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: Solaris 9 X-Received-From: 119.145.14.64 Cc: wusongwei@huawei.com, hanweidong@huawei.com, wuchangyi@huawei.com, louzhengwei@huawei.com, xiaowei.yang@huawei.com, james.chenjiabo@huawei.com, zanghongyong@huawei.com, cam@cs.ualberta.ca Subject: [Qemu-devel] [PATCH v2] ivshmem: add a new PIO BAR3(Doorbell) besides MMIO BAR0 to reduce notification time X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Hongyong Zang This patch, adds a PIO BAR3 for guest notifying qemu. And we find the new notification way of PIO BAR3 reduces 30% time in comparison with the original MMIO BAR0 way. Signed-off-by: Hongyong Zang --- hw/ivshmem.c | 24 ++++++++++++++++++++++-- kvm-all.c | 23 +++++++++++++++++++++++ kvm.h | 1 + 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/hw/ivshmem.c b/hw/ivshmem.c index 242fbea..031cdd8 100644 --- a/hw/ivshmem.c +++ b/hw/ivshmem.c @@ -29,6 +29,7 @@ #define IVSHMEM_MASTER 1 #define IVSHMEM_REG_BAR_SIZE 0x100 +#define IVSHIO_REG_BAR_SIZE 0x10 //#define DEBUG_IVSHMEM #ifdef DEBUG_IVSHMEM @@ -57,8 +58,10 @@ typedef struct IVShmemState { CharDriverState **eventfd_chr; CharDriverState *server_chr; MemoryRegion ivshmem_mmio; + MemoryRegion ivshmem_pio; pcibus_t mmio_addr; + pcibus_t pio_addr; /* We might need to register the BAR before we actually have the memory. * So prepare a container MemoryRegion for the BAR immediately and * add a subregion when we have the memory. @@ -234,7 +237,7 @@ static uint64_t ivshmem_io_read(void *opaque, target_phys_addr_t addr, return ret; } -static const MemoryRegionOps ivshmem_mmio_ops = { +static const MemoryRegionOps ivshmem_io_ops = { .read = ivshmem_io_read, .write = ivshmem_io_write, .endianness = DEVICE_NATIVE_ENDIAN, @@ -348,6 +351,8 @@ static void close_guest_eventfds(IVShmemState *s, int posn) for (i = 0; i < guest_curr_max; i++) { kvm_set_ioeventfd_mmio_long(s->peers[posn].eventfds[i], s->mmio_addr + DOORBELL, (posn << 16) | i, 0); + kvm_set_ioeventfd_pio_long(s->peers[posn].eventfds[i], + s->pio_addr + DOORBELL, (posn << 16) | i, 0); close(s->peers[posn].eventfds[i]); } @@ -367,6 +372,12 @@ static void setup_ioeventfds(IVShmemState *s) { true, (i << 16) | j, s->peers[i].eventfds[j]); + memory_region_add_eventfd(&s->ivshmem_pio, + DOORBELL, + 4, + true, + (i << 16) | j, + s->peers[i].eventfds[j]); } } } @@ -495,6 +506,10 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags) (incoming_posn << 16) | guest_max_eventfd, 1) < 0) { fprintf(stderr, "ivshmem: ioeventfd not available\n"); } + if (kvm_set_ioeventfd_pio_long(incoming_fd, s->pio_addr + DOORBELL, + (incoming_posn << 16) | guest_max_eventfd, 1) < 0) { + fprintf(stderr, "ivshmem: ioeventfd not available\n"); + } } return; @@ -656,8 +671,10 @@ static int pci_ivshmem_init(PCIDevice *dev) s->shm_fd = 0; - memory_region_init_io(&s->ivshmem_mmio, &ivshmem_mmio_ops, s, + memory_region_init_io(&s->ivshmem_mmio, &ivshmem_io_ops, s, "ivshmem-mmio", IVSHMEM_REG_BAR_SIZE); + memory_region_init_io(&s->ivshmem_pio, &ivshmem_io_ops, s, + "ivshmem-pio", IVSHIO_REG_BAR_SIZE); if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) { setup_ioeventfds(s); @@ -666,6 +683,8 @@ static int pci_ivshmem_init(PCIDevice *dev) /* region for registers*/ pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ivshmem_mmio); + pci_register_bar(&s->dev, 3, PCI_BASE_ADDRESS_SPACE_IO, + &s->ivshmem_pio); memory_region_init(&s->bar, "ivshmem-bar2-container", s->ivshmem_size); @@ -742,6 +761,7 @@ static int pci_ivshmem_uninit(PCIDevice *dev) IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev); memory_region_destroy(&s->ivshmem_mmio); + memory_region_destroy(&s->ivshmem_pio); memory_region_del_subregion(&s->bar, &s->ivshmem); memory_region_destroy(&s->ivshmem); memory_region_destroy(&s->bar); diff --git a/kvm-all.c b/kvm-all.c index 5d500e1..737c2e2 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1396,6 +1396,29 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t addr, uint32_t val, bool assign return 0; } +int kvm_set_ioeventfd_pio_long(int fd, uint32_t addr, uint32_t val, bool assign) +{ + struct kvm_ioeventfd kick = { + .datamatch = val, + .addr = addr, + .len = 4, + .flags = KVM_IOEVENTFD_FLAG_DATAMATCH | KVM_IOEVENTFD_FLAG_PIO, + .fd = fd, + }; + int r; + if (!kvm_enabled()) { + return -ENOSYS; + } + if (!assign) { + kick.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN; + } + r = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick); + if (r < 0) { + return r; + } + return 0; +} + int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign) { struct kvm_ioeventfd kick = { diff --git a/kvm.h b/kvm.h index b15e1dd..c2373c9 100644 --- a/kvm.h +++ b/kvm.h @@ -198,6 +198,7 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign) int kvm_set_irqfd(int gsi, int fd, bool assigned); +int kvm_set_ioeventfd_pio_long(int fd, uint32_t adr, uint32_t val, bool assign); int kvm_set_ioeventfd_pio_word(int fd, uint16_t adr, uint16_t val, bool assign); typedef struct KVMMsiMessage {