From patchwork Wed Dec 10 16:23:19 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Tosatti X-Patchwork-Id: 419769 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id C243B1400B7 for ; Thu, 11 Dec 2014 03:59:55 +1100 (AEDT) Received: from localhost ([::1]:46720 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XykcE-00008o-24 for incoming@patchwork.ozlabs.org; Wed, 10 Dec 2014 11:59:54 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38853) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XykbZ-0007hH-49 for qemu-devel@nongnu.org; Wed, 10 Dec 2014 11:59:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XykbO-00029m-U2 for qemu-devel@nongnu.org; Wed, 10 Dec 2014 11:59:13 -0500 Received: from mx1.redhat.com ([209.132.183.28]:46079) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XykbO-00029a-Lp for qemu-devel@nongnu.org; Wed, 10 Dec 2014 11:59:02 -0500 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id sBAGx17E026567 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 10 Dec 2014 11:59:01 -0500 Received: from amt.cnet (vpn1-5-156.gru2.redhat.com [10.97.5.156]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id sBAGx0b2030897; Wed, 10 Dec 2014 11:59:01 -0500 Received: from amt.cnet (localhost [127.0.0.1]) by amt.cnet (Postfix) with ESMTP id 88CD310092D; Wed, 10 Dec 2014 14:58:48 -0200 (BRST) Received: (from marcelo@localhost) by amt.cnet (8.14.7/8.14.7/Submit) id sBAGwmcN019553; Wed, 10 Dec 2014 14:58:48 -0200 Message-Id: <20141210162420.218207164@amt.cnet> User-Agent: quilt/0.60-1 Date: Wed, 10 Dec 2014 14:23:19 -0200 From: Marcelo Tosatti To: kvm@vger.kernel.org, qemu-devel@nongnu.org References: <20141210162317.370733848@amt.cnet> Content-Disposition: inline; filename=set-lapic-tscdeadline X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Paolo Bonzini , Marcelo Tosatti , Luiz Capitulino Subject: [Qemu-devel] [QEMU patch 2/2] kvm: allow configuration of tsc deadline timer advancement 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 Add machine option and QMP commands to configure TSC deadline timer advancement. Signed-off-by: Marcelo Tosatti --- monitor.c | 15 ++++++++++ qapi-schema.json | 29 +++++++++++++++++++ qmp-commands.hx | 48 ++++++++++++++++++++++++++++++++ target-i386/kvm.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ vl.c | 4 ++ 5 files changed, 176 insertions(+) Index: qemu.tscdeadline/qapi-schema.json =================================================================== --- qemu.tscdeadline.orig/qapi-schema.json +++ qemu.tscdeadline/qapi-schema.json @@ -3515,3 +3515,32 @@ # Since: 2.1 ## { 'command': 'rtc-reset-reinjection' } + +## +# @set-lapic-tscdeadline-advance +# +# This command sets the TSC deadline timer advancement. +# This value will be subtracted from the expiration time +# of the high resolution timer which emulates +# TSC deadline timer. +# +# Useful to achieve low timer latencies. +# +# Only supported by KVM acceleration. +# +# Since: 2.3 +## +{ 'command': 'set-lapic-tscdeadline-advance', + 'data': { 'advance':'int' } +} + +## +# @get-lapic-tscdeadline-advance +# +# This command gets the TSC deadline timer advancement. +# +# Only supported by KVM acceleration. +# +# Since: 2.3 +## +{ 'command': 'get-lapic-tscdeadline-advance', 'returns': 'int' } Index: qemu.tscdeadline/qmp-commands.hx =================================================================== --- qemu.tscdeadline.orig/qmp-commands.hx +++ qemu.tscdeadline/qmp-commands.hx @@ -3854,3 +3854,51 @@ Move mouse pointer to absolute coordinat <- { "return": {} } EQMP + + { + .name = "set-lapic-tscdeadline-advance", + .args_type = "advance:i", + .mhandler.cmd_new = qmp_marshal_input_set_lapic_tscdeadline_advance, + }, + +SQMP +set-lapic-tscdeadline-advance +----------------------------- + +Set LAPIC tscdeadline timer advancement, in nanoseconds. + +Arguments: + +- "advance": LAPIC tscdeadline timer advancement (json-int) + +Example: + +-> { "execute": "set-lapic-tscdeadline-advance 1000" } +<- { "return": {} } + +EQMP + + { + .name = "get-lapic-tscdeadline-advance", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_get_lapic_tscdeadline_advance, + }, + +SQMP +get-lapic-tscdeadline-advance +----------------------------- + +Get LAPIC tscdeadline timer advancement, in nanoseconds. + +Arguments: None. + +returns a json-object with the following information: +- "value" : json-int + +Example: + +-> { "execute": "get-lapic-tscdeadline-advance" } +<- { "return": {1000} } + +EQMP + Index: qemu.tscdeadline/vl.c =================================================================== --- qemu.tscdeadline.orig/vl.c +++ qemu.tscdeadline/vl.c @@ -387,6 +387,10 @@ static QemuOptsList qemu_machine_opts = .name = "iommu", .type = QEMU_OPT_BOOL, .help = "Set on/off to enable/disable Intel IOMMU (VT-d)", + },{ + .name = "lapic-tscdeadline-advance", + .type = QEMU_OPT_NUMBER, + .help = "Set lapic tscdeadline timer advance", }, { /* End of list */ } }, Index: qemu.tscdeadline/target-i386/kvm.c =================================================================== --- qemu.tscdeadline.orig/target-i386/kvm.c +++ qemu.tscdeadline/target-i386/kvm.c @@ -37,6 +37,7 @@ #include "hw/pci/pci.h" #include "migration/migration.h" #include "qapi/qmp/qerror.h" +#include "qmp-commands.h" //#define DEBUG_KVM @@ -84,6 +85,10 @@ static bool has_msr_mtrr; static bool has_msr_architectural_pmu; static uint32_t num_architectural_pmu_counters; +static struct lapic_tscdeadline_advance { + unsigned int advance_ns; +} lapic_tscdeadline_advance; + bool kvm_allows_irq0_override(void) { return !kvm_irqchip_in_kernel() || kvm_has_gsi_routing(); @@ -835,12 +840,32 @@ static int kvm_get_supported_msrs(KVMSta return ret; } +static int kvm_set_lapic_tscdeadline(KVMState *s, uint32_t advance) +{ + struct kvm_tscdeadline_advance adv; + int ret = 0; + + memset(&adv, 0, sizeof(adv)); + + adv.timer_advance = advance; + + ret = kvm_vm_ioctl(s, KVM_SET_TSCDEADLINE_ADVANCE, &adv); + if (ret < 0) { + return ret; + } + + lapic_tscdeadline_advance.advance_ns = advance; + + return ret; +} + int kvm_arch_init(KVMState *s) { uint64_t identity_base = 0xfffbc000; uint64_t shadow_mem; int ret; struct utsname utsname; + uint32_t lapic_advance_ns; ret = kvm_get_supported_msrs(s); if (ret < 0) { @@ -894,9 +919,40 @@ int kvm_arch_init(KVMState *s) return ret; } } + + lapic_advance_ns = qemu_opt_get_number(qemu_get_machine_opts(), + "lapic-tscdeadline-advance", + 0); + if (lapic_advance_ns) { + ret = kvm_set_lapic_tscdeadline(s, lapic_advance_ns); + if (ret) { + fprintf(stderr, "Set tscdeadline advance failed: %s\n", + strerror(-ret)); + return ret; + } + } + + return 0; } +int64_t qmp_get_lapic_tscdeadline_advance(Error **errp) +{ + return lapic_tscdeadline_advance.advance_ns; +} + +void qmp_set_lapic_tscdeadline_advance(int64_t advance, Error **errp) +{ + KVMState *s = kvm_state; + int ret; + + ret = kvm_set_lapic_tscdeadline(s, advance); + if (ret) { + error_setg_errno(errp, ret, "set lapic tscdeadline failed"); + return; + } +} + static void set_v8086_seg(struct kvm_segment *lhs, const SegmentCache *rhs) { lhs->selector = rhs->selector; Index: qemu.tscdeadline/monitor.c =================================================================== --- qemu.tscdeadline.orig/monitor.c +++ qemu.tscdeadline/monitor.c @@ -5447,3 +5447,18 @@ void qmp_rtc_reset_reinjection(Error **e error_set(errp, QERR_FEATURE_DISABLED, "rtc-reset-reinjection"); } #endif + +#if !defined (TARGET_I386) || !defined (CONFIG_KVM) +int64_t qmp_get_lapic_tscdeadline_advance(Error **errp) +{ + error_set(errp, QERR_FEATURE_DISABLED, "get-lapic-tscdeadline-advance"); + + return 0; +} + +void qmp_set_lapic_tscdeadline_advance(int64_t advance, Error **errp) +{ + error_set(errp, QERR_FEATURE_DISABLED, "set-lapic-tscdeadline-advance"); +} +#endif + Index: qemu.tscdeadline/include/hw/boards.h =================================================================== --- qemu.tscdeadline.orig/include/hw/boards.h +++ qemu.tscdeadline/include/hw/boards.h @@ -133,6 +133,7 @@ struct MachineState { bool usb; char *firmware; bool iommu; + int lapi_tscdeadline_advance; ram_addr_t ram_size; ram_addr_t maxram_size; Index: qemu.tscdeadline/qemu-options.hx =================================================================== --- qemu.tscdeadline.orig/qemu-options.hx +++ qemu.tscdeadline/qemu-options.hx @@ -37,7 +37,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_mach " kvm_shadow_mem=size of KVM shadow MMU\n" " dump-guest-core=on|off include guest memory in a core dump (default=on)\n" " mem-merge=on|off controls memory merge support (default: on)\n" - " iommu=on|off controls emulated Intel IOMMU (VT-d) support (default=off)\n", + " iommu=on|off controls emulated Intel IOMMU (VT-d) support (default=off)\n" + " lapic-tscdeadline-advance=value controls LAPIC tscdeadline timer advancement (default=0)\n", QEMU_ARCH_ALL) STEXI @item -machine [type=]@var{name}[,prop=@var{value}[,...]] @@ -66,6 +67,8 @@ the host, de-duplicates identical memory (enabled by default). @item iommu=on|off Enables or disables emulated Intel IOMMU (VT-d) support. The default is off. +@item lapic-tscdeadline-advance=value +Defines the advancement of LAPIC TSC deadline timer, in nanoseconds. @end table ETEXI Index: qemu.tscdeadline/hw/core/machine.c =================================================================== --- qemu.tscdeadline.orig/hw/core/machine.c +++ qemu.tscdeadline/hw/core/machine.c @@ -72,6 +72,35 @@ static void machine_set_kvm_shadow_mem(O ms->kvm_shadow_mem = value; } +static void machine_get_lapic_tscdeadline_advance(Object *obj, Visitor *v, + void *opaque, + const char *name, + Error **errp) +{ + MachineState *ms = MACHINE(obj); + int64_t value = ms->kvm_shadow_mem; + + visit_type_int(v, &value, name, errp); +} + +static void machine_set_lapic_tscdeadline_advance(Object *obj, Visitor *v, + void *opaque, + const char *name, + Error **errp) +{ + MachineState *ms = MACHINE(obj); + Error *error = NULL; + int64_t value; + + visit_type_int(v, &value, name, &error); + if (error) { + error_propagate(errp, error); + return; + } + + ms->lapi_tscdeadline_advance = value; +} + static char *machine_get_kernel(Object *obj, Error **errp) { MachineState *ms = MACHINE(obj); @@ -299,6 +328,10 @@ static void machine_initfn(Object *obj) machine_get_kvm_shadow_mem, machine_set_kvm_shadow_mem, NULL, NULL, NULL); + object_property_add(obj, "lapic-tscdeadline-advance", "int", + machine_get_lapic_tscdeadline_advance, + machine_set_lapic_tscdeadline_advance, + NULL, NULL, NULL); object_property_add_str(obj, "kernel", machine_get_kernel, machine_set_kernel, NULL); object_property_add_str(obj, "initrd",