From: Vadim Rozenfeld <vrozenfe@redhat.com>
To: "George-Cristian Bîrzan" <gc@birzan.org>
Cc: Gleb Natapov <gleb@redhat.com>, kvm@vger.kernel.org
Subject: Re: Performance issue
Date: Wed, 28 Nov 2012 13:39:16 +0200 [thread overview]
Message-ID: <201211281339.17589.vrozenfe@redhat.com> (raw)
In-Reply-To: <CAMxNYaY1WQOw-D_3fc9AQgqnpyLFd6EM4TqXGH5tXa6EPvqc5w@mail.gmail.com>
[-- Attachment #1: Type: Text/Plain, Size: 751 bytes --]
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 <vrozenfe@redhat.com>
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
[-- Attachment #2: hv_time_kvm.diff --]
[-- Type: text/x-patch, Size: 4028 bytes --]
diff --git a/arch/x86/include/asm/hyperv.h b/arch/x86/include/asm/hyperv.h
index b80420b..9c5ffef 100644
--- a/arch/x86/include/asm/hyperv.h
+++ b/arch/x86/include/asm/hyperv.h
@@ -136,6 +136,9 @@
/* MSR used to read the per-partition time reference counter */
#define HV_X64_MSR_TIME_REF_COUNT 0x40000020
+/* A partition's reference time stamp counter (TSC) page */
+#define HV_X64_MSR_REFERENCE_TSC 0x40000021
+
/* Define the virtual APIC registers */
#define HV_X64_MSR_EOI 0x40000070
#define HV_X64_MSR_ICR 0x40000071
@@ -179,6 +182,10 @@
#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_MASK \
(~((1ull << HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT) - 1))
+#define HV_X64_MSR_TSC_REFERENCE_ENABLE 0x00000001
+#define HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT 12
+
+
#define HV_PROCESSOR_POWER_STATE_C0 0
#define HV_PROCESSOR_POWER_STATE_C1 1
#define HV_PROCESSOR_POWER_STATE_C2 2
@@ -191,4 +198,11 @@
#define HV_STATUS_INVALID_ALIGNMENT 4
#define HV_STATUS_INSUFFICIENT_BUFFERS 19
+typedef struct _HV_REFERENCE_TSC_PAGE {
+ uint32_t TscSequence;
+ uint32_t Rserved1;
+ uint64_t TscScale;
+ int64_t TscOffset;
+} HV_REFERENCE_TSC_PAGE, * PHV_REFERENCE_TSC_PAGE;
+
#endif
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index b2e11f4..63ee09e 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -565,6 +565,8 @@ struct kvm_arch {
/* fields used by HYPER-V emulation */
u64 hv_guest_os_id;
u64 hv_hypercall;
+ u64 hv_ref_count;
+ u64 hv_tsc_page;
#ifdef CONFIG_KVM_MMU_AUDIT
int audit_point;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 4f76417..4538295 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -813,7 +813,7 @@ EXPORT_SYMBOL_GPL(kvm_rdpmc);
static u32 msrs_to_save[] = {
MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW,
- HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL,
+ HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL, HV_X64_MSR_REFERENCE_TSC,
HV_X64_MSR_APIC_ASSIST_PAGE, MSR_KVM_ASYNC_PF_EN, MSR_KVM_STEAL_TIME,
MSR_KVM_PV_EOI_EN,
MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
@@ -1428,6 +1428,8 @@ static bool kvm_hv_msr_partition_wide(u32 msr)
switch (msr) {
case HV_X64_MSR_GUEST_OS_ID:
case HV_X64_MSR_HYPERCALL:
+ case HV_X64_MSR_TIME_REF_COUNT:
+ case HV_X64_MSR_REFERENCE_TSC:
r = true;
break;
}
@@ -1438,6 +1440,7 @@ static bool kvm_hv_msr_partition_wide(u32 msr)
static int set_msr_hyperv_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
{
struct kvm *kvm = vcpu->kvm;
+ unsigned long addr;
switch (msr) {
case HV_X64_MSR_GUEST_OS_ID:
@@ -1467,6 +1470,27 @@ static int set_msr_hyperv_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
if (__copy_to_user((void __user *)addr, instructions, 4))
return 1;
kvm->arch.hv_hypercall = data;
+ kvm->arch.hv_ref_count = get_kernel_ns();
+ break;
+ }
+ case HV_X64_MSR_REFERENCE_TSC: {
+ HV_REFERENCE_TSC_PAGE tsc_ref;
+ tsc_ref.TscSequence =
+ boot_cpu_has(X86_FEATURE_CONSTANT_TSC) ? 1 : 0;
+ tsc_ref.TscScale =
+ ((10000LL << 32) /vcpu->arch.virtual_tsc_khz) << 32;
+ tsc_ref.TscOffset = 0;
+ if (!(data & HV_X64_MSR_TSC_REFERENCE_ENABLE)) {
+ kvm->arch.hv_tsc_page = data;
+ break;
+ }
+ addr = gfn_to_hva(vcpu->kvm, data >>
+ HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT);
+ if (kvm_is_error_hva(addr))
+ return 1;
+ if(__copy_to_user((void __user *)addr, &tsc_ref, sizeof(tsc_ref)))
+ return 1;
+ kvm->arch.hv_tsc_page = data;
break;
}
default:
@@ -1881,6 +1905,13 @@ static int get_msr_hyperv_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case HV_X64_MSR_HYPERCALL:
data = kvm->arch.hv_hypercall;
break;
+ case HV_X64_MSR_TIME_REF_COUNT:
+ data = get_kernel_ns() - kvm->arch.hv_ref_count;
+ do_div(data, 100);
+ break;
+ case HV_X64_MSR_REFERENCE_TSC:
+ data = kvm->arch.hv_tsc_page;
+ break;
default:
vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
return 1;
[-- Attachment #3: hv_time_qemu.diff --]
[-- Type: text/x-patch, Size: 4666 bytes --]
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);
next prev parent reply other threads:[~2012-11-28 11:39 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-22 19:17 Performance issue George-Cristian Bîrzan
2012-11-23 7:26 ` Stefan Hajnoczi
[not found] ` <CAMxNYabWpHqmNN7mCY9mwVJjoTj4jwS_js+cZcxQVnJsTdwfBg@mail.gmail.com>
2012-11-23 14:02 ` Fwd: " George-Cristian Bîrzan
2012-11-25 15:19 ` Gleb Natapov
2012-11-25 16:17 ` George-Cristian Bîrzan
2012-11-26 19:31 ` George-Cristian Bîrzan
2012-11-27 12:20 ` Gleb Natapov
2012-11-27 12:29 ` George-Cristian Bîrzan
2012-11-27 14:54 ` Gleb Natapov
2012-11-27 20:38 ` Vadim Rozenfeld
2012-11-27 21:13 ` George-Cristian Bîrzan
2012-11-28 11:39 ` Vadim Rozenfeld [this message]
2012-11-28 19:09 ` George-Cristian Bîrzan
2012-11-29 11:56 ` Vadim Rozenfeld
2012-11-29 13:45 ` George-Cristian Bîrzan
2012-11-29 13:56 ` Gleb Natapov
2012-11-29 20:34 ` Vadim Rozenfeld
2012-11-28 19:18 ` George-Cristian Bîrzan
2012-11-28 19:56 ` Gleb Natapov
2012-11-28 20:01 ` George-Cristian Bîrzan
2012-11-28 20:12 ` Gleb Natapov
-- strict thread matches above, loose matches on Subject: below --
2015-10-15 13:38 kernel: BUG: soft lockup - CPU#1 stuck for 60s! [md0_raid5:1614] Rainer Fügenstein
2015-10-16 1:15 ` Neil Brown
2015-10-24 16:15 ` performance issue (was: Re: kernel: BUG: soft lockup - CPU#1 stuck for 60s!) Rainer Fügenstein
2015-10-24 16:31 ` Roman Mamedov
2015-10-25 19:23 ` Rainer Fügenstein
2015-10-25 20:08 ` Neil Brown
2015-11-02 22:55 ` performance issue Rainer Fügenstein
2015-11-03 1:34 ` Neil Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201211281339.17589.vrozenfe@redhat.com \
--to=vrozenfe@redhat.com \
--cc=gc@birzan.org \
--cc=gleb@redhat.com \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.