From: "Jan Beulich" <JBeulich@suse.com>
To: xen-devel <xen-devel@lists.xenproject.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>, Keir Fraser <keir@xen.org>
Subject: [PATCH] x86/HVM: also separate kernel/user vTSC statistics
Date: Tue, 10 Feb 2015 11:32:14 +0000 [thread overview]
Message-ID: <54D9FA4E020000780005E8FF@mail.emea.novell.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 3769 bytes --]
It is unclear why this got done for PV only originally.
While at it, limit this statistics collection to debug or performance
counter enabled builds.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -319,7 +319,6 @@ u64 hvm_get_guest_tsc_fixed(struct vcpu
{
tsc = hvm_get_guest_time_fixed(v, at_tsc);
tsc = gtime_to_gtsc(v->domain, tsc);
- v->domain->arch.vtsc_kerncount++;
}
else if ( at_tsc )
{
@@ -4368,12 +4367,41 @@ void hvm_cpuid(unsigned int input, unsig
}
}
+static uint64_t _hvm_rdtsc_intercept(void)
+{
+ struct vcpu *curr = current;
+#if !defined(NDEBUG) || defined(PERF_COUNTERS)
+ struct domain *currd = curr->domain;
+
+ if ( currd->arch.vtsc )
+ switch ( hvm_guest_x86_mode(curr) )
+ {
+ struct segment_register sreg;
+
+ case 8:
+ case 4:
+ case 2:
+ hvm_get_segment_register(curr, x86_seg_ss, &sreg);
+ if ( unlikely(sreg.attr.fields.dpl) )
+ {
+ case 1:
+ currd->arch.vtsc_usercount++;
+ break;
+ }
+ /* fall through */
+ case 0:
+ currd->arch.vtsc_kerncount++;
+ break;
+ }
+#endif
+
+ return hvm_get_guest_tsc(curr);
+}
+
void hvm_rdtsc_intercept(struct cpu_user_regs *regs)
{
- uint64_t tsc;
- struct vcpu *v = current;
+ uint64_t tsc = _hvm_rdtsc_intercept();
- tsc = hvm_get_guest_tsc(v);
regs->eax = (uint32_t)tsc;
regs->edx = (uint32_t)(tsc >> 32);
@@ -4401,7 +4429,7 @@ int hvm_msr_read_intercept(unsigned int
break;
case MSR_IA32_TSC:
- *msr_content = hvm_get_guest_tsc(v);
+ *msr_content = _hvm_rdtsc_intercept();
break;
case MSR_IA32_TSC_ADJUST:
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -1777,10 +1777,12 @@ void pv_soft_rdtsc(struct vcpu *v, struc
spin_lock(&d->arch.vtsc_lock);
+#if !defined(NDEBUG) || defined(PERF_COUNTERS)
if ( guest_kernel_mode(v, regs) )
d->arch.vtsc_kerncount++;
else
d->arch.vtsc_usercount++;
+#endif
if ( (int64_t)(now - d->arch.vtsc_last) > 0 )
d->arch.vtsc_last = now;
@@ -2033,17 +2035,13 @@ static void dump_softtsc(unsigned char k
printk(",khz=%"PRIu32, d->arch.tsc_khz);
if ( d->arch.incarnation )
printk(",inc=%"PRIu32, d->arch.incarnation);
+#if !defined(NDEBUG) || defined(PERF_COUNTERS)
if ( !(d->arch.vtsc_kerncount | d->arch.vtsc_usercount) )
- {
printk("\n");
- continue;
- }
- if ( is_hvm_domain(d) )
- printk(",vtsc count: %"PRIu64" total\n",
- d->arch.vtsc_kerncount);
else
printk(",vtsc count: %"PRIu64" kernel, %"PRIu64" user\n",
d->arch.vtsc_kerncount, d->arch.vtsc_usercount);
+#endif
domcnt++;
}
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -319,8 +319,10 @@ struct arch_domain
struct time_scale ns_to_vtsc; /* scaling for certain emulated cases */
uint32_t incarnation; /* incremented every restore or live migrate
(possibly other cases in the future */
- uint64_t vtsc_kerncount; /* for hvm, counts all vtsc */
- uint64_t vtsc_usercount; /* not used for hvm */
+#if !defined(NDEBUG) || defined(PERF_COUNTERS)
+ uint64_t vtsc_kerncount;
+ uint64_t vtsc_usercount;
+#endif
/* Pseudophysical e820 map (XENMEM_memory_map). */
spinlock_t e820_lock;
[-- Attachment #2: x86-HVM-vTSC-counts.patch --]
[-- Type: text/plain, Size: 3817 bytes --]
x86/HVM: also separate kernel/user vTSC statistics
It is unclear why this got done for PV only originally.
While at it, limit this statistics collection to debug or performance
counter enabled builds.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -319,7 +319,6 @@ u64 hvm_get_guest_tsc_fixed(struct vcpu
{
tsc = hvm_get_guest_time_fixed(v, at_tsc);
tsc = gtime_to_gtsc(v->domain, tsc);
- v->domain->arch.vtsc_kerncount++;
}
else if ( at_tsc )
{
@@ -4368,12 +4367,41 @@ void hvm_cpuid(unsigned int input, unsig
}
}
+static uint64_t _hvm_rdtsc_intercept(void)
+{
+ struct vcpu *curr = current;
+#if !defined(NDEBUG) || defined(PERF_COUNTERS)
+ struct domain *currd = curr->domain;
+
+ if ( currd->arch.vtsc )
+ switch ( hvm_guest_x86_mode(curr) )
+ {
+ struct segment_register sreg;
+
+ case 8:
+ case 4:
+ case 2:
+ hvm_get_segment_register(curr, x86_seg_ss, &sreg);
+ if ( unlikely(sreg.attr.fields.dpl) )
+ {
+ case 1:
+ currd->arch.vtsc_usercount++;
+ break;
+ }
+ /* fall through */
+ case 0:
+ currd->arch.vtsc_kerncount++;
+ break;
+ }
+#endif
+
+ return hvm_get_guest_tsc(curr);
+}
+
void hvm_rdtsc_intercept(struct cpu_user_regs *regs)
{
- uint64_t tsc;
- struct vcpu *v = current;
+ uint64_t tsc = _hvm_rdtsc_intercept();
- tsc = hvm_get_guest_tsc(v);
regs->eax = (uint32_t)tsc;
regs->edx = (uint32_t)(tsc >> 32);
@@ -4401,7 +4429,7 @@ int hvm_msr_read_intercept(unsigned int
break;
case MSR_IA32_TSC:
- *msr_content = hvm_get_guest_tsc(v);
+ *msr_content = _hvm_rdtsc_intercept();
break;
case MSR_IA32_TSC_ADJUST:
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -1777,10 +1777,12 @@ void pv_soft_rdtsc(struct vcpu *v, struc
spin_lock(&d->arch.vtsc_lock);
+#if !defined(NDEBUG) || defined(PERF_COUNTERS)
if ( guest_kernel_mode(v, regs) )
d->arch.vtsc_kerncount++;
else
d->arch.vtsc_usercount++;
+#endif
if ( (int64_t)(now - d->arch.vtsc_last) > 0 )
d->arch.vtsc_last = now;
@@ -2033,17 +2035,13 @@ static void dump_softtsc(unsigned char k
printk(",khz=%"PRIu32, d->arch.tsc_khz);
if ( d->arch.incarnation )
printk(",inc=%"PRIu32, d->arch.incarnation);
+#if !defined(NDEBUG) || defined(PERF_COUNTERS)
if ( !(d->arch.vtsc_kerncount | d->arch.vtsc_usercount) )
- {
printk("\n");
- continue;
- }
- if ( is_hvm_domain(d) )
- printk(",vtsc count: %"PRIu64" total\n",
- d->arch.vtsc_kerncount);
else
printk(",vtsc count: %"PRIu64" kernel, %"PRIu64" user\n",
d->arch.vtsc_kerncount, d->arch.vtsc_usercount);
+#endif
domcnt++;
}
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -319,8 +319,10 @@ struct arch_domain
struct time_scale ns_to_vtsc; /* scaling for certain emulated cases */
uint32_t incarnation; /* incremented every restore or live migrate
(possibly other cases in the future */
- uint64_t vtsc_kerncount; /* for hvm, counts all vtsc */
- uint64_t vtsc_usercount; /* not used for hvm */
+#if !defined(NDEBUG) || defined(PERF_COUNTERS)
+ uint64_t vtsc_kerncount;
+ uint64_t vtsc_usercount;
+#endif
/* Pseudophysical e820 map (XENMEM_memory_map). */
spinlock_t e820_lock;
[-- Attachment #3: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
next reply other threads:[~2015-02-10 11:32 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-10 11:32 Jan Beulich [this message]
2015-02-10 11:51 ` [PATCH] x86/HVM: also separate kernel/user vTSC statistics Andrew Cooper
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=54D9FA4E020000780005E8FF@mail.emea.novell.com \
--to=jbeulich@suse.com \
--cc=andrew.cooper3@citrix.com \
--cc=keir@xen.org \
--cc=xen-devel@lists.xenproject.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.