From patchwork Wed Nov 28 11:39:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Vadim Rozenfeld X-Patchwork-Id: 1815791 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 034A5DF2ED for ; Wed, 28 Nov 2012 11:39:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754492Ab2K1Ljc (ORCPT ); Wed, 28 Nov 2012 06:39:32 -0500 Received: from mx1.redhat.com ([209.132.183.28]:7412 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754470Ab2K1Lja (ORCPT ); Wed, 28 Nov 2012 06:39:30 -0500 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qASBdTSl020348 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 28 Nov 2012 06:39:29 -0500 Received: from vadimr.dell (vpn-202-28.tlv.redhat.com [10.35.202.28]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id qASBdJ35016171 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 28 Nov 2012 06:39:26 -0500 From: Vadim Rozenfeld Organization: Red Hat To: "George-Cristian =?iso-8859-1?q?B=EErzan?=" Subject: Re: Performance issue Date: Wed, 28 Nov 2012 13:39:16 +0200 User-Agent: KMail/1.13.7 (Linux/3.3.0-rc5+; KDE/4.6.5; x86_64; ; ) Cc: Gleb Natapov , kvm@vger.kernel.org References: <201211272238.38614.vrozenfe@redhat.com> In-Reply-To: MIME-Version: 1.0 Message-Id: <201211281339.17589.vrozenfe@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org On Tuesday, November 27, 2012 11:13:12 PM George-Cristian Bîrzan wrote: > On Tue, Nov 27, 2012 at 10:38 PM, Vadim Rozenfeld wrote: > > I have some code which do both reference time and invariant TSC but it > > will not work after migration. I will send it later today. > > Do you mean migrating guests? This is not an issue for us. OK, but don't say I didn't warn you :) There are two patches, one for kvm and another one for qemu. you will probably need to rebase them. Add "hv_tsc" cpu parameter to activate this feature. you will probably need to deactivate hpet by adding "-no-hpet" parameter as well. best regards, Vadim. > > Also, it would be much appreciated! > > -- > George-Cristian Bîrzan diff --git a/target-i386/cpu.c b/target-i386/cpu.c index f3708e6..ad77b72 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -1250,6 +1250,8 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) hyperv_enable_relaxed_timing(true); } else if (!strcmp(featurestr, "hv_vapic")) { hyperv_enable_vapic_recommended(true); + } else if (!strcmp(featurestr, "hv_tsc")) { + hyperv_enable_tsc_recommended(true); } else { fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr); goto error; diff --git a/target-i386/hyperv.c b/target-i386/hyperv.c index f284e99..bd581a1 100644 --- a/target-i386/hyperv.c +++ b/target-i386/hyperv.c @@ -15,6 +15,12 @@ static bool hyperv_vapic; static bool hyperv_relaxed_timing; static int hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY; +static bool hyperv_tsc; + +void hyperv_enable_tsc_recommended(bool val) +{ + hyperv_tsc = val; +} void hyperv_enable_vapic_recommended(bool val) { @@ -42,12 +48,18 @@ bool hyperv_enabled(void) bool hyperv_hypercall_available(void) { if (hyperv_vapic || + hyperv_tsc || (hyperv_spinlock_attempts != HYPERV_SPINLOCK_NEVER_RETRY)) { return true; } return false; } +bool hyperv_tsc_recommended(void) +{ + return hyperv_tsc; +} + bool hyperv_vapic_recommended(void) { return hyperv_vapic; diff --git a/target-i386/hyperv.h b/target-i386/hyperv.h index bacb1d4..94c2d6e 100644 --- a/target-i386/hyperv.h +++ b/target-i386/hyperv.h @@ -27,10 +27,12 @@ #endif #if !defined(CONFIG_USER_ONLY) && defined(CONFIG_KVM) +void hyperv_enable_tsc_recommended(bool val); void hyperv_enable_vapic_recommended(bool val); void hyperv_enable_relaxed_timing(bool val); void hyperv_set_spinlock_retries(int val); #else +static inline void hyperv_enable_tsc_recommended(bool val) { } static inline void hyperv_enable_vapic_recommended(bool val) { } static inline void hyperv_enable_relaxed_timing(bool val) { } static inline void hyperv_set_spinlock_retries(int val) { } @@ -38,6 +40,7 @@ static inline void hyperv_set_spinlock_retries(int val) { } bool hyperv_enabled(void); bool hyperv_hypercall_available(void); +bool hyperv_tsc_recommended(void); bool hyperv_vapic_recommended(void); bool hyperv_relaxed_timing_enabled(void); int hyperv_get_spinlock_retries(void); diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 5b18383..dc7f259 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -390,13 +390,17 @@ int kvm_arch_init_vcpu(CPUX86State *env) c = &cpuid_data.entries[cpuid_i++]; memset(c, 0, sizeof(*c)); c->function = KVM_CPUID_SIGNATURE; - if (!hyperv_enabled()) { - memcpy(signature, "KVMKVMKVM\0\0\0", 12); - c->eax = 0; - } else { - memcpy(signature, "Microsoft Hv", 12); + memcpy(signature, "KVMKVMKVM\0\0\0", 12); + if (hyperv_enabled()) { c->eax = HYPERV_CPUID_MIN; } +// if (!hyperv_enabled()) { +// memcpy(signature, "KVMKVMKVM\0\0\0", 12); +// c->eax = 0; +// } else { +// memcpy(signature, "Microsoft Hv", 12); +// c->eax = HYPERV_CPUID_MIN; +// } c->ebx = signature[0]; c->ecx = signature[1]; c->edx = signature[2]; @@ -427,7 +431,11 @@ int kvm_arch_init_vcpu(CPUX86State *env) c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE; c->eax |= HV_X64_MSR_APIC_ACCESS_AVAILABLE; } - + if (hyperv_tsc_recommended()) { + c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE; + c->eax |= HV_X64_MSR_TIME_REF_COUNT_AVAILABLE; + c->eax |= 0x200; + } c = &cpuid_data.entries[cpuid_i++]; memset(c, 0, sizeof(*c)); c->function = HYPERV_CPUID_ENLIGHTMENT_INFO; @@ -445,14 +453,14 @@ int kvm_arch_init_vcpu(CPUX86State *env) c->eax = 0x40; c->ebx = 0x40; - c = &cpuid_data.entries[cpuid_i++]; - memset(c, 0, sizeof(*c)); - c->function = KVM_CPUID_SIGNATURE_NEXT; - memcpy(signature, "KVMKVMKVM\0\0\0", 12); - c->eax = 0; - c->ebx = signature[0]; - c->ecx = signature[1]; - c->edx = signature[2]; +// c = &cpuid_data.entries[cpuid_i++]; +// memset(c, 0, sizeof(*c)); +// c->function = KVM_CPUID_SIGNATURE_NEXT; +// memcpy(signature, "KVMKVMKVM\0\0\0", 12); +// c->eax = 0; +// c->ebx = signature[0]; +// c->ecx = signature[1]; +// c->edx = signature[2]; } has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);