From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752001AbbJFEG4 (ORCPT ); Tue, 6 Oct 2015 00:06:56 -0400 Received: from mga09.intel.com ([134.134.136.24]:43115 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751009AbbJFEGy (ORCPT ); Tue, 6 Oct 2015 00:06:54 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,641,1437462000"; d="scan'208";a="574871815" Date: Tue, 6 Oct 2015 12:06:47 +0800 From: Haozhong Zhang To: Radim =?utf-8?B?S3LEjW3DocWZ?= Cc: David Matlack , kvm@vger.kernel.org, Gleb Natapov , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , x86@kernel.org, Joerg Roedel , Wanpeng Li , Xiao Guangrong , Mihai =?utf-8?B?RG9uyJt1?= , Andy Lutomirski , Kai Huang , linux-kernel@vger.kernel.org Subject: Re: [PATCH 04/12] KVM: x86: Replace call-back set_tsc_khz() with a common function Message-ID: <20151006040647.GD3798@hzzhang-OptiPlex-9020.sh.intel.com> Mail-Followup-To: Radim =?utf-8?B?S3LEjW3DocWZ?= , David Matlack , kvm@vger.kernel.org, Gleb Natapov , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , x86@kernel.org, Joerg Roedel , Wanpeng Li , Xiao Guangrong , Mihai =?utf-8?B?RG9uyJt1?= , Andy Lutomirski , Kai Huang , linux-kernel@vger.kernel.org References: <1443418691-24050-1-git-send-email-haozhong.zhang@intel.com> <1443418691-24050-5-git-send-email-haozhong.zhang@intel.com> <20151005195325.GA4508@potion.brq.redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20151005195325.GA4508@potion.brq.redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Oct 05, 2015 at 09:53:26PM +0200, Radim Krčmář wrote: > 2015-09-28 13:38+0800, Haozhong Zhang: > > Both VMX and SVM propagate virtual_tsc_khz in the same way, so this > > patch removes the call-back set_tsc_khz() and replaces it with a common > > function. > > > > Signed-off-by: Haozhong Zhang > > --- > > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > > +static void set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz, bool scale) > > +{ > > + u64 ratio, khz; > | [...] > > + khz = user_tsc_khz; > > I'd use "user_tsc_khz" directly. > I'll do so. > > + /* TSC scaling required - calculate ratio */ > > + shift = (kvm_tsc_scaling_ratio_frac_bits <= 32) ? > > + kvm_tsc_scaling_ratio_frac_bits : 32; > > + ratio = khz << shift; > > + do_div(ratio, tsc_khz); > > + ratio <<= (kvm_tsc_scaling_ratio_frac_bits - shift); > > VMX is losing 16 bits by this operation; normal fixed point division > could get us a smaller drift (and an one-liner here) ... > at 4.3 GHz, 32 instead of 48 bits after decimal point translate to one > "lost" TSC tick per second, in the worst case. > > Please mention that we are truncating on purpose :) It's intentional to avoid the potential overflow in khz << kvm_tsc_scaling_ratio_frac_bits. For VMX where kvm_tsc_scaling_ratio_frac_bits == 48, the above expression is only safe to left shift a pretty small khz (< 2^16 KHz or 65.5 MHz). Thus, I decided to sacrifice the precision for safety. I chose to truncate at the boundary of 32 bits which can handle khz as large as 4294 GHz. Though this truncation results in losing TSC ticks when khz is larger than 4.3 GHz, the lost is however pretty small compared with the large khz. Alternatively, it's also possible to follow David's comment to use divq on x86_64 to keep both precision and safety. On i386, it just falls back to above truncating approach. - Haozhong