From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.1 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6420DC04AAC for ; Thu, 23 May 2019 04:18:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 18BEC20881 for ; Thu, 23 May 2019 04:18:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KUCtlCKQ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726443AbfEWES6 (ORCPT ); Thu, 23 May 2019 00:18:58 -0400 Received: from mail-pg1-f194.google.com ([209.85.215.194]:33278 "EHLO mail-pg1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725792AbfEWES6 (ORCPT ); Thu, 23 May 2019 00:18:58 -0400 Received: by mail-pg1-f194.google.com with SMTP id h17so2425680pgv.0; Wed, 22 May 2019 21:18:57 -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=HbqtOQevQsp/ok74pQVOtTO4LnYP1GQdx8YeHeJwjdA=; b=KUCtlCKQiEsmI4qGb5+5ls2Urv7EPflFrlNcayB80Hbzpnm6l2sig4DOkKVjy2L3/Y DCuGlFQkA1XdKFHo2pCJG/dXO7KAKTGHKRxVsBfCP91+DA8Q/qgRB51tMJBFbZBU5s9U LzOu3T2leyByV7HSD7nvZj42azIGalpu/X5vyigVydotYCMrLt+Gr9JqnRqWhopHeMK7 apETmcWQ003JlQhS7NyO99/odcD8T44nUYxxa6v4q935IrFKgMdb2Wd+MMzmwocjQRM3 /H8t6M3pszMEAyn7Y0gmU23w16DOMrRB1UTyLgVqe76seahwAUDIRvSytbfYJw25Ar1t 8K/g== 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=HbqtOQevQsp/ok74pQVOtTO4LnYP1GQdx8YeHeJwjdA=; b=JN9PyhAW6JP4LMFPJO/wBsiOyMZ8K//Vv9fb4JlBiuu1Ynu5f+KHAZ4k3ERK0/DUi4 a0tmWzl7TNV975gOlFi+0v8dM+wnK9D3+FIrGB9EPgngSo9oFB1zLuF3y6RAbQXJOEup Dh464HAyQ9pbPg1rdUwvOovUDND5h9aemLEo5YjHC3yUAVyGBB5AWlhWxp7cx/64PC/0 g/y6S0f/graEcyX8d2BnUwCojte2uSR9zoi90WRRxX2MU/L5VRoLWlgdRc0Z++rYyfcc x/eFWIoX7neNqGstFhKRGZkVibYeUUte64j1G9ONvYrTDWSk4dhQj0EFIhu08Pnv0TJm AcMQ== X-Gm-Message-State: APjAAAVTBTOB6iIY8RlxBsW6AI3NvQMs9iMk+Buir4k4bleBVGLlvynA ajOuQOBLSVqAR3CvKJqBQ87/vHee X-Google-Smtp-Source: APXvYqzM2AE7xEJVcugB0F0nxfevORP435QvjJsvCkkKHUxCnEXIJdTnxTMM9RMQIN+QtEuNrlAuPg== X-Received: by 2002:aa7:8b57:: with SMTP id i23mr19083581pfd.54.1558585136738; Wed, 22 May 2019 21:18:56 -0700 (PDT) Received: from localhost.localdomain ([203.205.141.123]) by smtp.googlemail.com with ESMTPSA id m12sm22991427pgi.56.2019.05.22.21.18.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 22 May 2019 21:18:56 -0700 (PDT) From: Wanpeng Li X-Google-Original-From: Wanpeng Li To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Sean Christopherson Subject: [PATCH 1/2] KVM: LAPIC: Optimize timer latency consider world switch time Date: Thu, 23 May 2019 12:18:50 +0800 Message-Id: <1558585131-1321-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: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Wanpeng Li Advance lapic timer tries to hidden the hypervisor overhead between the host emulated timer fires and the guest awares the timer is fired. However, even though after more sustaining optimizations, kvm-unit-tests/tscdeadline_latency still awares ~1000 cycles latency since we lost the time between the end of wait_lapic_expire and the guest awares the timer is fired. There are codes between the end of wait_lapic_expire and the world switch, futhermore, the world switch itself also has overhead. Actually the guest_tsc is equal to the target deadline time in wait_lapic_expire is too late, guest will aware the latency between the end of wait_lapic_expire() and after vmentry to the guest. This patch takes this time into consideration. The vmentry_lapic_timer_advance_ns module parameter should be well tuned by host admin, it can reduce average cyclictest latency from 3us to 2us on Skylake server. (guest w/ nohz=off, idle=poll, host w/ preemption_timer=N, the cyclictest latency is not too sensitive when preemption_timer=Y for this optimization in my testing), kvm-unit-tests/tscdeadline_latency can reach 0. Cc: Paolo Bonzini Cc: Radim Krčmář Cc: Sean Christopherson Signed-off-by: Wanpeng Li --- arch/x86/kvm/lapic.c | 17 +++++++++++++++-- arch/x86/kvm/lapic.h | 1 + arch/x86/kvm/vmx/vmx.c | 2 +- arch/x86/kvm/x86.c | 3 +++ arch/x86/kvm/x86.h | 2 ++ 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index fcf42a3..6f85221 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1531,6 +1531,19 @@ static inline void adjust_lapic_timer_advance(struct kvm_vcpu *vcpu, apic->lapic_timer.timer_advance_ns = timer_advance_ns; } +u64 get_vmentry_advance_delta(struct kvm_vcpu *vcpu) +{ + u64 vmentry_lapic_timer_advance_cycles = 0; + + if (vmentry_lapic_timer_advance_ns) { + vmentry_lapic_timer_advance_cycles = vmentry_lapic_timer_advance_ns * + vcpu->arch.virtual_tsc_khz; + do_div(vmentry_lapic_timer_advance_cycles, 1000000); + } + return vmentry_lapic_timer_advance_cycles; +} +EXPORT_SYMBOL_GPL(get_vmentry_advance_delta); + void kvm_wait_lapic_expire(struct kvm_vcpu *vcpu) { struct kvm_lapic *apic = vcpu->arch.apic; @@ -1544,7 +1557,7 @@ void kvm_wait_lapic_expire(struct kvm_vcpu *vcpu) tsc_deadline = apic->lapic_timer.expired_tscdeadline; apic->lapic_timer.expired_tscdeadline = 0; - guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc()); + guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc()) + get_vmentry_advance_delta(vcpu); apic->lapic_timer.advance_expire_delta = guest_tsc - tsc_deadline; if (guest_tsc < tsc_deadline) @@ -1572,7 +1585,7 @@ static void start_sw_tscdeadline(struct kvm_lapic *apic) local_irq_save(flags); now = ktime_get(); - guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc()); + guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc()) + get_vmentry_advance_delta(vcpu); ns = (tscdeadline - guest_tsc) * 1000000ULL; do_div(ns, this_tsc_khz); diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index f974a3d..df2fe17 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -221,6 +221,7 @@ static inline int kvm_lapic_latched_init(struct kvm_vcpu *vcpu) bool kvm_apic_pending_eoi(struct kvm_vcpu *vcpu, int vector); void kvm_wait_lapic_expire(struct kvm_vcpu *vcpu); +u64 get_vmentry_advance_delta(struct kvm_vcpu *vcpu); bool kvm_intr_is_single_vcpu_fast(struct kvm *kvm, struct kvm_lapic_irq *irq, struct kvm_vcpu **dest_vcpu); diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index da24f18..0199ac3 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7047,7 +7047,7 @@ static int vmx_set_hv_timer(struct kvm_vcpu *vcpu, u64 guest_deadline_tsc, vmx = to_vmx(vcpu); tscl = rdtsc(); - guest_tscl = kvm_read_l1_tsc(vcpu, tscl); + guest_tscl = kvm_read_l1_tsc(vcpu, tscl) + get_vmentry_advance_delta(vcpu); delta_tsc = max(guest_deadline_tsc, guest_tscl) - guest_tscl; lapic_timer_advance_cycles = nsec_to_cycles(vcpu, ktimer->timer_advance_ns); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index a4eb711..a02e2c3 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -145,6 +145,9 @@ module_param(tsc_tolerance_ppm, uint, S_IRUGO | S_IWUSR); static int __read_mostly lapic_timer_advance_ns = -1; module_param(lapic_timer_advance_ns, int, S_IRUGO | S_IWUSR); +u32 __read_mostly vmentry_lapic_timer_advance_ns = 0; +module_param(vmentry_lapic_timer_advance_ns, uint, S_IRUGO | S_IWUSR); + static bool __read_mostly vector_hashing = true; module_param(vector_hashing, bool, S_IRUGO); diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 275b3b6..b0a3b84 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -294,6 +294,8 @@ extern u64 kvm_supported_xcr0(void); extern unsigned int min_timer_period_us; +extern unsigned int vmentry_lapic_timer_advance_ns; + extern bool enable_vmware_backdoor; extern struct static_key kvm_no_apic_vcpu; -- 2.7.4