From nobody Thu Apr 18 12:40:57 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1531216616253120.61489294155024; Tue, 10 Jul 2018 02:56:56 -0700 (PDT) Received: from localhost ([::1]:46822 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fcpNy-0002MO-VO for importer@patchew.org; Tue, 10 Jul 2018 05:56:43 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33016) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fcpN5-00023g-B7 for qemu-devel@nongnu.org; Tue, 10 Jul 2018 05:55:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fcpN2-0002p6-67 for qemu-devel@nongnu.org; Tue, 10 Jul 2018 05:55:47 -0400 Received: from mail-pg1-x543.google.com ([2607:f8b0:4864:20::543]:33455) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fcpN1-0002oU-PJ for qemu-devel@nongnu.org; Tue, 10 Jul 2018 05:55:44 -0400 Received: by mail-pg1-x543.google.com with SMTP id r5-v6so1863380pgv.0 for ; Tue, 10 Jul 2018 02:55:43 -0700 (PDT) Received: from localhost.localdomain ([203.205.141.123]) by smtp.googlemail.com with ESMTPSA id w13-v6sm1032598pgt.84.2018.07.10.02.55.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 10 Jul 2018 02:55:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=kZrLklCqdWSBCL/UWGW97Wi+paFlFSN4aKCmZq/45hY=; b=emq2qKAt1A4XUzTfma72sXIGPNNZxP1FQwmClr1sD51GmXsrjR30OvxOgDfdl9X4M/ 0dt40P8KBcSSw3y6nJBoJompoKzBSvtsu0px9diR02vxyjC7bZRUI9iToT2c1p4fefRu QujWLoSXjA+woL4m/7AEBpD5IVn6VVhl41w2jEuCI9LWQYMjrQMEBCjuWS/lA/Z6LZio 7ohRWJiZMXH9SanqbLu/CLe5uTHUfBsddbMuIEImTnIjFde+kAJicJDXilFncWbe8mbB mXaWmRXkquKkf1c/FswJSBV5B6+NLxqiT89XK/HZMHBch95ESXCi51SsbAbk8OChiUrO 8Vfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=kZrLklCqdWSBCL/UWGW97Wi+paFlFSN4aKCmZq/45hY=; b=iR5mJ8LRYr37CFaqfRUeqXLQoMt/5uAnAa2QFivfcG0NJmyiMV9q/BsU1voP4ikjmJ XnYgxifkMO6nTWVycdsDgHknyN4YCqOg63xkBKWxndH/yNnmTdGHj6MsdaoRst9mDbg+ ZgA1xrwdnlDSBDtA8umpQFLentiDQOBhvHdq2BlO+BwHC6uF439Ipq2k/gwQitTzKb4Q XF9BKjsTFDtRVyjgPCtElmQ9OUGkp8CwaA3/CjoYcMgKIqYWDnAU9qFKErm1tX4qQhZ6 2DvGQmzWOTiXrvVlelLDoag8TFoO0A/hYTSyLOW+61XOCaZQjLeSwz7wB2rqYIp85H6z hhEw== X-Gm-Message-State: APt69E2B4d0m6IepeQ/eeVplQABjZ6jbFsZQL7ZoeGEKmpMIlhgnK/TH WYkL0VFF4C6ifpmShIOxMysU0Q== X-Google-Smtp-Source: AAOMgpc7kAiQC7kKvnolFgvmELH32DdchFDZ3sozoAlYoIxbCb+VDjW42vleA33pjI2aRglwxO8w5Q== X-Received: by 2002:a63:8b44:: with SMTP id j65-v6mr16017935pge.248.1531216542341; Tue, 10 Jul 2018 02:55:42 -0700 (PDT) From: Wanpeng Li X-Google-Original-From: Wanpeng Li To: qemu-devel@nongnu.org, kvm@vger.kernel.org Date: Tue, 10 Jul 2018 17:55:38 +0800 Message-Id: <1531216538-19674-1-git-send-email-wanpengli@tencent.com> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::543 Subject: [Qemu-devel] [PATCH] target-i386: coalesced PIO support for RTC X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paolo Bonzini , Eduardo Habkost , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Windows I/O, such as the real-time clock. The address register (port 0x70 in the RTC case) can use coalesced I/O, cutting the number of userspace exits by half when reading or writing the RTC. Guest access rtc like this: write register index to 0x70, then write or=20 read data from 0x71. writing 0x70 port is just as index and do nothing=20 else. So we can use coalesced mmio to handle this scene to reduce VM-EXIT=20 time. In our environment, 12 windows guest running on a Skylake server: Before patch: IO Port Access Samples Samples% Time% Avg time 0x70:POUT 20675 46.04% 92.72% 67.15us ( +- 7.93% ) After patch: IO Port Access Samples Samples% Time% Avg time 0x70:POUT 17509 45.42% 42.08% 6.37us ( +- 20.37% ) Thanks to Peng Hao's initial patch. Cc: Paolo Bonzini Cc: Radim Kr=C4=8Dm=C3=A1=C5=99 Cc: Eduardo Habkost Signed-off-by: Wanpeng Li --- accel/kvm/kvm-all.c | 56 +++++++++++++++++++++++++++++++++++++++++++= ---- hw/timer/mc146818rtc.c | 8 +++++++ include/exec/memattrs.h | 1 + include/exec/memory.h | 5 +++++ include/sysemu/kvm.h | 8 +++++++ linux-headers/linux/kvm.h | 5 +++-- memory.c | 5 +++++ 7 files changed, 82 insertions(+), 6 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index eb7db92..7a12341 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -128,6 +128,7 @@ bool kvm_direct_msi_allowed; bool kvm_ioeventfd_any_length_allowed; bool kvm_msi_use_devid; static bool kvm_immediate_exit; +bool kvm_coalesced_pio_allowed; =20 static const KVMCapabilityInfo kvm_required_capabilites[] =3D { KVM_CAP_INFO(USER_MEMORY), @@ -536,7 +537,7 @@ static void kvm_coalesce_mmio_region(MemoryListener *li= stener, =20 zone.addr =3D start; zone.size =3D size; - zone.pad =3D 0; + zone.pio =3D 0; =20 (void)kvm_vm_ioctl(s, KVM_REGISTER_COALESCED_MMIO, &zone); } @@ -553,7 +554,7 @@ static void kvm_uncoalesce_mmio_region(MemoryListener *= listener, =20 zone.addr =3D start; zone.size =3D size; - zone.pad =3D 0; + zone.pio =3D 0; =20 (void)kvm_vm_ioctl(s, KVM_UNREGISTER_COALESCED_MMIO, &zone); } @@ -877,6 +878,45 @@ static void kvm_io_ioeventfd_del(MemoryListener *liste= ner, } } =20 +static void kvm_coalesce_io_add(MemoryListener *listener, + MemoryRegionSection *section, + hwaddr start, hwaddr size) +{ + KVMState *s =3D kvm_state; + + if (kvm_coalesced_pio_allowed) { + struct kvm_coalesced_mmio_zone zone; + + zone.addr =3D start; + zone.size =3D size; + zone.pio =3D 1; + + (void)kvm_vm_ioctl(s, KVM_REGISTER_COALESCED_MMIO, &zone); + } +} + +static void kvm_coalesce_io_del(MemoryListener *listener, + MemoryRegionSection *section, + hwaddr start, hwaddr size) +{ + KVMState *s =3D kvm_state; + + if (kvm_coalesced_pio_allowed) { + struct kvm_coalesced_mmio_zone zone; + + zone.addr =3D start; + zone.size =3D size; + zone.pio =3D 1; + + (void)kvm_vm_ioctl(s, KVM_UNREGISTER_COALESCED_MMIO, &zone); + } +} + +static MemoryListener kvm_coalesced_io_listener =3D { + .coalesced_mmio_add =3D kvm_coalesce_io_add, + .coalesced_mmio_del =3D kvm_coalesce_io_del, + .priority =3D 10, +}; void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml, AddressSpace *as, int as_id) { @@ -1615,6 +1655,8 @@ static int kvm_init(MachineState *ms) } =20 s->coalesced_mmio =3D kvm_check_extension(s, KVM_CAP_COALESCED_MMIO); + kvm_coalesced_pio_allowed =3D s->coalesced_mmio && + kvm_check_extension(s, KVM_CAP_COALESCED_PIO); =20 #ifdef KVM_CAP_VCPU_EVENTS s->vcpu_events =3D kvm_check_extension(s, KVM_CAP_VCPU_EVENTS); @@ -1694,6 +1736,8 @@ static int kvm_init(MachineState *ms) &address_space_memory, 0); memory_listener_register(&kvm_io_listener, &address_space_io); + memory_listener_register(&kvm_coalesced_io_listener, + &address_space_io); =20 s->many_ioeventfds =3D kvm_check_many_ioeventfds(); =20 @@ -1775,8 +1819,12 @@ void kvm_flush_coalesced_mmio_buffer(void) struct kvm_coalesced_mmio *ent; =20 ent =3D &ring->coalesced_mmio[ring->first]; - - cpu_physical_memory_write(ent->phys_addr, ent->data, ent->len); + if (ent->pio) { + address_space_rw(&address_space_io, ent->phys_addr, + MEMTXATTRS_NONE, ent->data, ent->len, tru= e); + } else { + cpu_physical_memory_write(ent->phys_addr, ent->data, ent->= len); + } smp_wmb(); ring->first =3D (ring->first + 1) % KVM_COALESCED_MMIO_MAX; } diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index 6f1f723..8bd8682 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -70,6 +70,7 @@ typedef struct RTCState { ISADevice parent_obj; =20 MemoryRegion io; + MemoryRegion coalesced_io; uint8_t cmos_data[128]; uint8_t cmos_index; int32_t base_year; @@ -990,6 +991,13 @@ static void rtc_realizefn(DeviceState *dev, Error **er= rp) memory_region_init_io(&s->io, OBJECT(s), &cmos_ops, s, "rtc", 2); isa_register_ioport(isadev, &s->io, base); =20 + if (memory_allow_coalesced_pio()) { + memory_region_set_flush_coalesced(&s->io); + memory_region_init_io(&s->coalesced_io, OBJECT(s), &cmos_ops, + s, "rtc1", 1); + isa_register_ioport(isadev, &s->coalesced_io, base); + memory_region_add_coalescing(&s->coalesced_io, 0, 1); + } qdev_set_legacy_instance_id(dev, base, 3); qemu_register_reset(rtc_reset, s); =20 diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h index d4a1642..97884d8 100644 --- a/include/exec/memattrs.h +++ b/include/exec/memattrs.h @@ -45,6 +45,7 @@ typedef struct MemTxAttrs { * from "didn't specify" if necessary). */ #define MEMTXATTRS_UNSPECIFIED ((MemTxAttrs) { .unspecified =3D 1 }) +#define MEMTXATTRS_NONE ((MemTxAttrs) { 0 }) =20 /* New-style MMIO accessors can indicate that the transaction failed. * A zero (MEMTX_OK) response means success; anything else is a failure diff --git a/include/exec/memory.h b/include/exec/memory.h index 448d41a..2854907 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1405,6 +1405,11 @@ void memory_region_set_flush_coalesced(MemoryRegion = *mr); void memory_region_clear_flush_coalesced(MemoryRegion *mr); =20 /** + * memory_allow_coalesced_pio: Check whether coalesced pio allowed. + */ +bool memory_allow_coalesced_pio(void); + +/** * memory_region_clear_global_locking: Declares that access processing does * not depend on the QEMU global lock. * diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 0b64b8e..08366b2 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -45,6 +45,7 @@ extern bool kvm_readonly_mem_allowed; extern bool kvm_direct_msi_allowed; extern bool kvm_ioeventfd_any_length_allowed; extern bool kvm_msi_use_devid; +extern bool kvm_coalesced_pio_allowed; =20 #define kvm_enabled() (kvm_allowed) /** @@ -167,6 +168,12 @@ extern bool kvm_msi_use_devid; */ #define kvm_msi_devid_required() (kvm_msi_use_devid) =20 +/** + * kvm_coalesced_pio_enabled: + * Returns: true if KVM allow coalesced pio + */ +#define kvm_coalesced_pio_enabled() (kvm_coalesced_pio_allowed) + #else =20 #define kvm_enabled() (0) @@ -184,6 +191,7 @@ extern bool kvm_msi_use_devid; #define kvm_direct_msi_enabled() (false) #define kvm_ioeventfd_any_length_enabled() (false) #define kvm_msi_devid_required() (false) +#define kvm_coalesced_pio_enabled() (false) =20 #endif /* CONFIG_KVM_IS_POSSIBLE */ =20 diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 98f389a..747b473 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -420,13 +420,13 @@ struct kvm_run { struct kvm_coalesced_mmio_zone { __u64 addr; __u32 size; - __u32 pad; + __u32 pio; }; =20 struct kvm_coalesced_mmio { __u64 phys_addr; __u32 len; - __u32 pad; + __u32 pio; __u8 data[8]; }; =20 @@ -949,6 +949,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_GET_MSR_FEATURES 153 #define KVM_CAP_HYPERV_EVENTFD 154 #define KVM_CAP_HYPERV_TLBFLUSH 155 +#define KVM_CAP_COALESCED_PIO 156 =20 #ifdef KVM_CAP_IRQ_ROUTING =20 diff --git a/memory.c b/memory.c index e9cd446..4a32817 100644 --- a/memory.c +++ b/memory.c @@ -2211,6 +2211,11 @@ void memory_region_clear_global_locking(MemoryRegion= *mr) mr->global_locking =3D false; } =20 +bool memory_allow_coalesced_pio(void) +{ + return kvm_enabled() && kvm_coalesced_pio_enabled(); +} + static bool userspace_eventfd_warning; =20 void memory_region_add_eventfd(MemoryRegion *mr, --=20 2.7.4