public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] kvmtrace: powerpc support and timestamps for KVM_TRACE
@ 2008-07-10 10:54 ehrhardt
  2008-07-10 10:54 ` [PATCH 1/9] kvmtrace: Remove use of bit fields in kvm trace structure v3 ehrhardt
                   ` (8 more replies)
  0 siblings, 9 replies; 11+ messages in thread
From: ehrhardt @ 2008-07-10 10:54 UTC (permalink / raw)
  To: kvm; +Cc: hollisb, avi, kvm-ppc, ehrhardt

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

Chaning kvmtrace code to use timestamp and add powerpc support.

This is the revised series including the feedback from the earlier submission
this week. I now also added the userspace changes which completes the series.

The series contains nine patches (4 generic / 5 powerpc code):

Subject: [PATCH 1/9] kvmtrace: Remove use of bit fields in kvm trace structure v3
	Introducing a endian save way to store the flags event,tcs, num_data 
Subject: [PATCH 2/9] kvmtrace: replace get_cycles with getnstimeofday
	use a cross host comparable timestamp source and make it 32/64 bit save
Subject: [PATCH 3/9] kvmtrace: rename cycles to timestamp
	it is no more tracking cycles, so rename variables and change comments
Subject: [PATCH 3/9] kvmppc: kvmtrace: enable KVM_TRACE building for powerpc
	enable KVM_TRACE for powerpc in Kconfig/Makefile
Subject: [PATCH 4/9] kvmppc: kvmtrace: adds trace points for ppc tlb activity v2
	use KVM_TRACE to track tlb/shadow tlb activity on embedded powerpc
Subject: [PATCH 5/9] kvmppc: kvmtrace: trace powerpc instruction emulation
	use KVM_TRACE to track instruction emulation overhead
Subject: [PATCH 7/9] kvm-userspace: kvmtrace_format: add ppc instruction emulation
	extension to kvmtrace_format to handle complex event types e.g. ppc
	instructon emulation
Subject: [PATCH 8/9] kvm-userspace: kvmtrace_format: add statistic section
	adding statistic creation/prsentation to the kvmtrace data processing
Subject: [PATCH 9/9] kvm-userspace: kvmtrace: rename cycles to timestamp
	it is no more tracking cycles, so rename variables and change comments

Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 arch/powerpc/kvm/emulate.c   |    2
 b/arch/powerpc/kvm/44x_tlb.c |   15 ++
 b/arch/powerpc/kvm/Kconfig   |   11 +
 b/arch/powerpc/kvm/Makefile  |    6
 b/arch/powerpc/kvm/emulate.c |    4
 b/include/linux/kvm.h        |   17 ++
 b/user/formats               |   16 --
 b/user/kvmtrace_format       |  276 ++++++++++++++++++++++++++++++++++++++++---
 b/virt/kvm/kvm_trace.c       |   19 +-
 include/linux/kvm.h          |   10 +
 user/formats                 |   50 +++----
 user/kvmtrace_format         |  114 +++++++++++++----
 virt/kvm/kvm_trace.c         |   29 ++--
 13 files changed, 461 insertions(+), 108 deletions(-)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/9] kvmtrace: Remove use of bit fields in kvm trace structure v3
  2008-07-10 10:54 [PATCH 0/5] kvmtrace: powerpc support and timestamps for KVM_TRACE ehrhardt
@ 2008-07-10 10:54 ` ehrhardt
  2008-07-10 10:54 ` [PATCH 2/9] kvmtrace: replace get_cycles with getnstimeofday ehrhardt
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: ehrhardt @ 2008-07-10 10:54 UTC (permalink / raw)
  To: kvm; +Cc: hollisb, avi, kvm-ppc, ehrhardt

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
From: Jerone Young <jyoung5@us.ibm.com>

This patch fixes kvmtrace use on big endian systems. When using bit fields the
compiler will lay data out in the wrong order expected when laid down into a
file.
This fixes it by using one variable instead of using bit fields.

Updates in v3:
	- fixed macro definition bug in v2
	- ensured in macro operator order
	- fixed whitespace/indent issues
	- removed superfluous initialization

Signed-off-by: Jerone Young <jyoung5@us.ibm.com>
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 include/linux/kvm.h  |   17 ++++++++++++++---
 virt/kvm/kvm_trace.c |   19 ++++++++++---------
 2 files changed, 24 insertions(+), 12 deletions(-)

[diff]

diff --git a/include/linux/kvm.h b/include/linux/kvm.h
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -311,9 +311,13 @@
 
 /* This structure represents a single trace buffer record. */
 struct kvm_trace_rec {
-	__u32 event:28;
-	__u32 extra_u32:3;
-	__u32 cycle_in:1;
+	/* variable rec_val
+	 * is split into:
+	 * bits 0 - 27  -> event id
+	 * bits 28 -30  -> number of extra data args of size u32
+	 * bits 31      -> binary indicator for if tsc is in record
+	 */
+	__u32 rec_val;
 	__u32 pid;
 	__u32 vcpu_id;
 	union {
@@ -326,6 +330,13 @@
 		} nocycle;
 	} u;
 } __attribute__((packed));
+
+#define TRACE_REC_EVENT_ID(val) \
+		(0x0fffffff & (val))
+#define TRACE_REC_NUM_DATA_ARGS(val) \
+		(0x70000000 & ((val) << 28))
+#define TRACE_REC_TCS(val) \
+		(0x80000000 & ((val) << 31))
 
 #define KVMIO 0xAE
 
diff --git a/virt/kvm/kvm_trace.c b/virt/kvm/kvm_trace.c
--- a/virt/kvm/kvm_trace.c
+++ b/virt/kvm/kvm_trace.c
@@ -54,12 +54,13 @@
 	struct kvm_trace *kt = kvm_trace;
 	struct kvm_trace_rec rec;
 	struct kvm_vcpu *vcpu;
-	int    i, extra, size;
+	int    i, size;
+	u32    extra;
 
 	if (unlikely(kt->trace_state != KVM_TRACE_STATE_RUNNING))
 		return;
 
-	rec.event	= va_arg(*args, u32);
+	rec.rec_val	= TRACE_REC_EVENT_ID(va_arg(*args, u32));
 	vcpu		= va_arg(*args, struct kvm_vcpu *);
 	rec.pid		= current->tgid;
 	rec.vcpu_id	= vcpu->vcpu_id;
@@ -67,21 +68,21 @@
 	extra   	= va_arg(*args, u32);
 	WARN_ON(!(extra <= KVM_TRC_EXTRA_MAX));
 	extra 		= min_t(u32, extra, KVM_TRC_EXTRA_MAX);
-	rec.extra_u32   = extra;
 
-	rec.cycle_in 	= p->cycle_in;
-
-	if (rec.cycle_in) {
+	rec.rec_val |= TRACE_REC_TCS(p->cycle_in)
+			| TRACE_REC_NUM_DATA_ARGS(extra);
+	
+	if (p->cycle_in) {
 		rec.u.cycle.cycle_u64 = get_cycles();
 
-		for (i = 0; i < rec.extra_u32; i++)
+		for (i = 0; i < extra; i++)
 			rec.u.cycle.extra_u32[i] = va_arg(*args, u32);
 	} else {
-		for (i = 0; i < rec.extra_u32; i++)
+		for (i = 0; i < extra; i++)
 			rec.u.nocycle.extra_u32[i] = va_arg(*args, u32);
 	}
 
-	size = calc_rec_size(rec.cycle_in, rec.extra_u32 * sizeof(u32));
+	size = calc_rec_size(p->cycle_in, extra * sizeof(u32));
 	relay_write(kt->rchan, &rec, size);
 }
 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 2/9] kvmtrace: replace get_cycles with getnstimeofday
  2008-07-10 10:54 [PATCH 0/5] kvmtrace: powerpc support and timestamps for KVM_TRACE ehrhardt
  2008-07-10 10:54 ` [PATCH 1/9] kvmtrace: Remove use of bit fields in kvm trace structure v3 ehrhardt
@ 2008-07-10 10:54 ` ehrhardt
  2008-07-10 15:15   ` Avi Kivity
  2008-07-10 10:54 ` [PATCH 3/9] kvmtrace: rename cycles to timestamp ehrhardt
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 11+ messages in thread
From: ehrhardt @ 2008-07-10 10:54 UTC (permalink / raw)
  To: kvm; +Cc: hollisb, avi, kvm-ppc, ehrhardt

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

The current kvmtrace code uses get_cycles() while the interpretation would be
easier using using nanoseconds. Getnstimeofday should give the same accuracy
as get_cycles on all architectures but at a better unit (e.g. comparable
between two hosts with different frequencies.

The implementation of kvmtrace uses a 64 bit cycle variable while get_cycles
only provided a unsigned long which is != 64 bit on 32 bit architectures.
Since this patch introduced getnstimeofday we can addtionally merge the
tv_sec portion of the struct timespec returned to use the full 64 bit
of the trace interface and therefor avoid some wraparounds. This merge
is done always if the two values of a struct timespec fit into the u64.

An alternative might be ktime_t instead of u64 and using as Sheng Yang
suggested and ktime_get(), I had no time to test&compare that yet.
Any comments or requirements from others what to prefer here ?

Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 kvm_trace.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

[diff]

diff --git a/virt/kvm/kvm_trace.c b/virt/kvm/kvm_trace.c
--- a/virt/kvm/kvm_trace.c
+++ b/virt/kvm/kvm_trace.c
@@ -56,6 +56,7 @@
 	struct kvm_vcpu *vcpu;
 	int    i, size;
 	u32    extra;
+	struct timespec tv;
 
 	if (unlikely(kt->trace_state != KVM_TRACE_STATE_RUNNING))
 		return;
@@ -73,7 +74,13 @@
 			| TRACE_REC_NUM_DATA_ARGS(extra);
 	
 	if (p->cycle_in) {
-		rec.u.cycle.cycle_u64 = get_cycles();
+		getnstimeofday(&tv);
+		/* compress both struct tv values into u64 on 32 bit archs */
+		if (sizeof(tv) == sizeof(u64))
+			rec.u.cycle.cycle_u64 = 
+				(((u64)tv.tv_sec) << 32) | tv.tv_nsec;
+		else
+			rec.u.cycle.cycle_u64 = tv.tv_nsec;
 
 		for (i = 0; i < extra; i++)
 			rec.u.cycle.extra_u32[i] = va_arg(*args, u32);

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/9] kvmtrace: rename cycles to timestamp
  2008-07-10 10:54 [PATCH 0/5] kvmtrace: powerpc support and timestamps for KVM_TRACE ehrhardt
  2008-07-10 10:54 ` [PATCH 1/9] kvmtrace: Remove use of bit fields in kvm trace structure v3 ehrhardt
  2008-07-10 10:54 ` [PATCH 2/9] kvmtrace: replace get_cycles with getnstimeofday ehrhardt
@ 2008-07-10 10:54 ` ehrhardt
  2008-07-10 10:54 ` [PATCH 3/9] kvmppc: kvmtrace: enable KVM_TRACE building for powerpc ehrhardt
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: ehrhardt @ 2008-07-10 10:54 UTC (permalink / raw)
  To: kvm; +Cc: hollisb, avi, kvm-ppc, ehrhardt

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

Due to the fact that the cycle counter is now completely replaced by the more
generic time based code (getnstimeofday) this patch renames all occurances of
the old cycle code to make it clear that this is now a timestamp.

Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 include/linux/kvm.h  |    6 +++---
 virt/kvm/kvm_trace.c |   20 ++++++++++----------
 2 files changed, 13 insertions(+), 13 deletions(-)

[diff]

diff --git a/include/linux/kvm.h b/include/linux/kvm.h
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -322,12 +322,12 @@
 	__u32 vcpu_id;
 	union {
 		struct {
-			__u64 cycle_u64;
+			__u64 timestamp_u64;
 			__u32 extra_u32[KVM_TRC_EXTRA_MAX];
-		} cycle;
+		} timestamp;
 		struct {
 			__u32 extra_u32[KVM_TRC_EXTRA_MAX];
-		} nocycle;
+		} notimestamp;
 	} u;
 } __attribute__((packed));
 
diff --git a/virt/kvm/kvm_trace.c b/virt/kvm/kvm_trace.c
--- a/virt/kvm/kvm_trace.c
+++ b/virt/kvm/kvm_trace.c
@@ -35,16 +35,16 @@
 struct kvm_trace_probe {
 	const char *name;
 	const char *format;
-	u32 cycle_in;
+	u32 timestamp_in;
 	marker_probe_func *probe_func;
 };
 
-static inline int calc_rec_size(int cycle, int extra)
+static inline int calc_rec_size(int timestamp, int extra)
 {
 	int rec_size = KVM_TRC_HEAD_SIZE;
 
 	rec_size += extra;
-	return cycle ? rec_size += KVM_TRC_CYCLE_SIZE : rec_size;
+	return timestamp ? rec_size += KVM_TRC_CYCLE_SIZE : rec_size;
 }
 
 static void kvm_add_trace(void *probe_private, void *call_data,
@@ -70,26 +70,26 @@
 	WARN_ON(!(extra <= KVM_TRC_EXTRA_MAX));
 	extra 		= min_t(u32, extra, KVM_TRC_EXTRA_MAX);
 
-	rec.rec_val |= TRACE_REC_TCS(p->cycle_in)
+	rec.rec_val |= TRACE_REC_TCS(p->timestamp_in)
 			| TRACE_REC_NUM_DATA_ARGS(extra);
 	
-	if (p->cycle_in) {
+	if (p->timestamp_in) {
 		getnstimeofday(&tv);
 		/* compress both struct tv values into u64 on 32 bit archs */
 		if (sizeof(tv) == sizeof(u64))
-			rec.u.cycle.cycle_u64 = 
+			rec.u.timestamp.timestamp_u64 = 
 				(((u64)tv.tv_sec) << 32) | tv.tv_nsec;
 		else
-			rec.u.cycle.cycle_u64 = tv.tv_nsec;
+			rec.u.timestamp.timestamp_u64 = tv.tv_nsec;
 
 		for (i = 0; i < extra; i++)
-			rec.u.cycle.extra_u32[i] = va_arg(*args, u32);
+			rec.u.timestamp.extra_u32[i] = va_arg(*args, u32);
 	} else {
 		for (i = 0; i < extra; i++)
-			rec.u.nocycle.extra_u32[i] = va_arg(*args, u32);
+			rec.u.notimestamp.extra_u32[i] = va_arg(*args, u32);
 	}
 
-	size = calc_rec_size(p->cycle_in, extra * sizeof(u32));
+	size = calc_rec_size(p->timestamp_in, extra * sizeof(u32));
 	relay_write(kt->rchan, &rec, size);
 }
 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/9] kvmppc: kvmtrace: enable KVM_TRACE building for powerpc
  2008-07-10 10:54 [PATCH 0/5] kvmtrace: powerpc support and timestamps for KVM_TRACE ehrhardt
                   ` (2 preceding siblings ...)
  2008-07-10 10:54 ` [PATCH 3/9] kvmtrace: rename cycles to timestamp ehrhardt
@ 2008-07-10 10:54 ` ehrhardt
  2008-07-10 10:54 ` [PATCH 4/9] kvmppc: kvmtrace: adds trace points for ppc tlb activity v2 ehrhardt
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: ehrhardt @ 2008-07-10 10:54 UTC (permalink / raw)
  To: kvm; +Cc: hollisb, avi, kvm-ppc, ehrhardt

From: Jerone Young <jyoung5@us.ibm.com>

This patch enables KVM_TRACE to build for PowerPC arch. This means just
adding sections to Kconfig and Makefile.

Signed-off-by: Jerone Young <jyoung5@us.ibm.com>
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 Kconfig  |   11 +++++++++++
 Makefile |    6 ++++--
 2 files changed, 15 insertions(+), 2 deletions(-)

[diff]
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -37,6 +37,17 @@ config KVM_BOOKE_HOST
 	  Provides host support for KVM on Book E PowerPC processors. Currently
 	  this works on 440 processors only.
 
+config KVM_TRACE
+	bool "KVM trace support"
+	depends on KVM && MARKERS && SYSFS
+	select RELAY
+	select DEBUG_FS
+	default n
+	---help---
+	  This option allows reading a trace of kvm-related events through
+	  relayfs.  Note the ABI is not considered stable and will be
+	  modified in future updates.
+
 source drivers/virtio/Kconfig
 
 endif # VIRTUALIZATION
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -4,9 +4,11 @@
 
 EXTRA_CFLAGS += -Ivirt/kvm -Iarch/powerpc/kvm
 
-common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o)
+common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o)
 
-kvm-objs := $(common-objs) powerpc.o emulate.o booke_guest.o
+common-objs-$(CONFIG_KVM_TRACE)  += $(addprefix ../../../virt/kvm/, kvm_trace.o)
+
+kvm-objs := $(common-objs-y) powerpc.o emulate.o booke_guest.o
 obj-$(CONFIG_KVM) += kvm.o
 
 AFLAGS_booke_interrupts.o := -I$(obj)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 4/9] kvmppc: kvmtrace: adds trace points for ppc tlb activity v2
  2008-07-10 10:54 [PATCH 0/5] kvmtrace: powerpc support and timestamps for KVM_TRACE ehrhardt
                   ` (3 preceding siblings ...)
  2008-07-10 10:54 ` [PATCH 3/9] kvmppc: kvmtrace: enable KVM_TRACE building for powerpc ehrhardt
@ 2008-07-10 10:54 ` ehrhardt
  2008-07-10 10:54 ` [PATCH 5/9] kvmppc: kvmtrace: trace powerpc instruction emulation ehrhardt
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: ehrhardt @ 2008-07-10 10:54 UTC (permalink / raw)
  To: kvm; +Cc: hollisb, avi, kvm-ppc, ehrhardt

From: Jerone Young <jyoung5@us.ibm.com>
From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

This patch adds trace points to track powerpc TLB activities using the
KVM_TRACE infrastructure.
Update to v1:
	- fixed wrong indents reported by checkpatch

Signed-off-by: Jerone Young <jyoung5@us.ibm.com>
Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 arch/powerpc/kvm/44x_tlb.c |   15 ++++++++++++++-
 arch/powerpc/kvm/emulate.c |    4 ++++
 include/linux/kvm.h        |    3 +++
 3 files changed, 21 insertions(+), 1 deletion(-)

[diff]

diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c
--- a/arch/powerpc/kvm/44x_tlb.c
+++ b/arch/powerpc/kvm/44x_tlb.c
@@ -19,6 +19,7 @@
 
 #include <linux/types.h>
 #include <linux/string.h>
+#include <linux/kvm.h>
 #include <linux/kvm_host.h>
 #include <linux/highmem.h>
 #include <asm/mmu-44x.h>
@@ -175,6 +176,10 @@
 	stlbe->word1 = (hpaddr & 0xfffffc00) | ((hpaddr >> 32) & 0xf);
 	stlbe->word2 = kvmppc_44x_tlb_shadow_attrib(flags,
 	                                            vcpu->arch.msr & MSR_PR);
+
+	KVMTRACE_5D(STLB_WRITE, vcpu, victim,
+			stlbe->tid, stlbe->word0, stlbe->word1, stlbe->word2,
+			handler);
 }
 
 void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, u64 eaddr, u64 asid)
@@ -203,6 +208,9 @@
 
 		kvmppc_44x_shadow_release(vcpu, i);
 		stlbe->word0 = 0;
+		KVMTRACE_5D(STLB_INVAL, vcpu, i,
+				stlbe->tid, stlbe->word0, stlbe->word1,
+				stlbe->word2, handler);
 	}
 	up_write(&current->mm->mmap_sem);
 }
@@ -216,8 +224,13 @@
 	/* XXX Replace loop with fancy data structures. */
 	down_write(&current->mm->mmap_sem);
 	for (i = 0; i <= tlb_44x_hwater; i++) {
+		struct tlbe *stlbe = &vcpu->arch.shadow_tlb[i];
+
 		kvmppc_44x_shadow_release(vcpu, i);
-		vcpu->arch.shadow_tlb[i].word0 = 0;
+		stlbe->word0 = 0;
+		KVMTRACE_5D(STLB_INVAL, vcpu, i,
+				stlbe->tid, stlbe->word0, stlbe->word1,
+				stlbe->word2, handler);
 	}
 	up_write(&current->mm->mmap_sem);
 }
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -169,6 +169,10 @@
 		 * are mapped on the fly. */
 		kvmppc_mmu_map(vcpu, eaddr, raddr >> PAGE_SHIFT, asid, flags);
 	}
+
+	KVMTRACE_5D(GTLB_WRITE, vcpu, index,
+			tlbe->tid, tlbe->word0, tlbe->word1, tlbe->word2,
+			handler);
 
 	return EMULATE_DONE;
 }
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -470,5 +470,8 @@
 #define KVM_TRC_LMSW             (KVM_TRC_HANDLER + 0x13)
 #define KVM_TRC_APIC_ACCESS      (KVM_TRC_HANDLER + 0x14)
 #define KVM_TRC_TDP_FAULT        (KVM_TRC_HANDLER + 0x15)
+#define KVM_TRC_GTLB_WRITE       (KVM_TRC_HANDLER + 0x16)
+#define KVM_TRC_STLB_WRITE       (KVM_TRC_HANDLER + 0x17)
+#define KVM_TRC_STLB_INVAL       (KVM_TRC_HANDLER + 0x18)
 
 #endif

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 5/9] kvmppc: kvmtrace: trace powerpc instruction emulation
  2008-07-10 10:54 [PATCH 0/5] kvmtrace: powerpc support and timestamps for KVM_TRACE ehrhardt
                   ` (4 preceding siblings ...)
  2008-07-10 10:54 ` [PATCH 4/9] kvmppc: kvmtrace: adds trace points for ppc tlb activity v2 ehrhardt
@ 2008-07-10 10:54 ` ehrhardt
  2008-07-10 10:54 ` [PATCH 7/9] kvm-userspace: kvmtrace_format: add ppc " ehrhardt
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: ehrhardt @ 2008-07-10 10:54 UTC (permalink / raw)
  To: kvm; +Cc: hollisb, avi, kvm-ppc, ehrhardt

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

This patch adds a trace point for the instruction emulation on embedded powerpc
utilizing the KVM_TRACE interface.

Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 arch/powerpc/kvm/emulate.c |    2 ++
 include/linux/kvm.h        |    1 +
 2 files changed, 3 insertions(+)

[diff]

diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -769,6 +769,8 @@
 		break;
 	}
 
+	KVMTRACE_3D(PPC_INSTR, vcpu, inst, vcpu->arch.pc, emulated, entryexit);
+
 	if (advance)
 		vcpu->arch.pc += 4; /* Advance past emulated instruction. */
 
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -473,5 +473,6 @@
 #define KVM_TRC_GTLB_WRITE       (KVM_TRC_HANDLER + 0x16)
 #define KVM_TRC_STLB_WRITE       (KVM_TRC_HANDLER + 0x17)
 #define KVM_TRC_STLB_INVAL       (KVM_TRC_HANDLER + 0x18)
+#define KVM_TRC_PPC_INSTR        (KVM_TRC_HANDLER + 0x19)
 
 #endif

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 7/9] kvm-userspace: kvmtrace_format: add ppc instruction emulation
  2008-07-10 10:54 [PATCH 0/5] kvmtrace: powerpc support and timestamps for KVM_TRACE ehrhardt
                   ` (5 preceding siblings ...)
  2008-07-10 10:54 ` [PATCH 5/9] kvmppc: kvmtrace: trace powerpc instruction emulation ehrhardt
@ 2008-07-10 10:54 ` ehrhardt
  2008-07-10 10:54 ` [PATCH 8/9] kvm-userspace: kvmtrace_format: add statistic section ehrhardt
  2008-07-10 10:54 ` [PATCH 9/9] kvm-userspace: kvmtrace: rename cycles to timestamp ehrhardt
  8 siblings, 0 replies; 11+ messages in thread
From: ehrhardt @ 2008-07-10 10:54 UTC (permalink / raw)
  To: kvm; +Cc: hollisb, avi, kvm-ppc, ehrhardt

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

This patch adds the handling of the ppc instruction emulation trace records.
Due to the fact that those are more complex than the classic "formats" file
way this patch adds a check of the event id and maps to the internal handler
function if needed (other complex trace records that might appear in future
can hook up there too).
Additionally this fixes the ppc tlb trace record definitions in the formats
file now that the revised kernel patch series is submitted.

Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 formats         |   16 +--
 kvmtrace_format |  276 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 268 insertions(+), 24 deletions(-)

[diff]

diff --git a/user/formats b/user/formats
--- a/user/formats
+++ b/user/formats
@@ -23,13 +23,9 @@
 0x00020013  %(tsc)d (+%(reltsc)8d)  LMSW          vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ value = 0x%(1)08x ]
 0x00020014  %(tsc)d (+%(reltsc)8d)  APIC_ACCESS   vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ offset = 0x%(1)08x ]
 0x00020015  %(tsc)d (+%(reltsc)8d)  TDP_FAULT     vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ errorcode = 0x%(1)08x, virt = 0x%(3)08x %(2)08x ]
-# ppc: context switch
-0x00020016  %(tsc)d (+%(reltsc)8d)  CONT_SWITCH   vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x
-# ppc: tlb write
-0x00020017  %(tsc)d (+%(reltsc)8d)  TLB_WRITE    vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
-# ppc: tlb invalidate
-0x00020018  %(tsc)d (+%(reltsc)8d)  TLB_INVAL     vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
-# ppc: guest TLB write
-0x00020019  %(tsc)d (+%(reltsc)8d)  GTLB_WRITE    vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
-# ppc: shadow TLB write
-0x00020020  %(tsc)d (+%(reltsc)8d)  STLB_WRITE   vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
+# ppc: tlb traces
+0x00020016  GTLB_WRITE    vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
+0x00020017  STLB_WRITE    vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
+0x00020018  STLB_INVAL    vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
+# ppc: instruction emulation - this type is handled more complex in kvmtrace_format, but listed to show the eventid and transported data
+#0x00020019  %(tsc)d (+%(reltsc)8d)  PPC_INSTR     vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ instr = 0x%(1)08x, pc = 0x%(2)08x, emul = 0x%(3)08x, nsec = %(4)08d ]
diff --git a/user/kvmtrace_format b/user/kvmtrace_format
--- a/user/kvmtrace_format
+++ b/user/kvmtrace_format
@@ -58,6 +58,250 @@
 def sighand(x,y):
     global interrupted
     interrupted = 1
+
+# ppc instruction decoding for event type 0x00020019 (PPC_INSTR)
+def get_op(instr):
+        return (instr >> 26);
+
+def get_xop(instr):
+        return (instr >> 1) & 0x3ff;
+
+def get_sprn(instr):
+	return ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0)
+
+def get_dcrn(instr):
+	return ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0);
+
+def get_tlbwe_type(instr):
+	ws = (instr >> 11) & 0x1f;
+	if ws == 0:
+		return "PAGEID"
+	elif ws == 1:
+		return "XLAT"
+	elif ws == 2:
+		return "ATTRIB"
+	else:
+		return "UNKNOWN"
+
+def get_name(instr):
+	if get_op(instr)==3:
+		return "trap"
+	elif get_op(instr)==19:
+		if get_xop(instr) == 50:
+			return "rfi"
+		else:
+			return "unknown"
+	elif get_op(instr)==31:
+		if get_xop(instr) == 83:
+			return "mfmsr"
+
+		elif get_xop(instr) == 87:
+			return "lbzx"
+
+		elif get_xop(instr) == 131:
+			return "wrtee"
+
+		elif get_xop(instr) == 146:
+			return "mtmsr"
+
+		elif get_xop(instr) == 163:
+			return "wrteei"
+
+		elif get_xop(instr) == 215:
+			return "stbx"
+
+		elif get_xop(instr) == 247:
+			return "stbux"
+
+		elif get_xop(instr) == 279:
+			return "lhzx"
+
+		elif get_xop(instr) == 311:
+			return "lhzux"
+
+		elif get_xop(instr) == 323:
+			return "mfdcr"
+
+		elif get_xop(instr) == 339:
+			return "mfspr"
+
+		elif get_xop(instr) == 407:
+			return "sthx"
+
+		elif get_xop(instr) == 439:
+			return "sthux"
+
+		elif get_xop(instr) == 451:
+			return "mtdcr"
+
+		elif get_xop(instr) == 467:
+			return "mtspr"
+
+		elif get_xop(instr) == 470:
+			return "dcbi"
+
+		elif get_xop(instr) == 534:
+			return "lwbrx"
+
+		elif get_xop(instr) == 566:
+			return "tlbsync"
+
+		elif get_xop(instr) == 662:
+			return "stwbrx"
+
+		elif get_xop(instr) == 978:
+			return "tlbwe"
+
+		elif get_xop(instr) == 914:
+			return "tlbsx"
+
+		elif get_xop(instr) == 790:
+			return "lhbrx"
+
+		elif get_xop(instr) == 918:
+			return "sthbrx"
+
+		elif get_xop(instr) == 966:
+			return "iccci"
+
+		else:
+			return "unknown"
+
+	elif get_op(instr) == 32:
+		return "lwz"
+
+	elif get_op(instr) == 33:
+		return "lwzu"
+
+	elif get_op(instr) == 34:
+		return "lbz"
+
+	elif get_op(instr) == 35:
+		return "lbzu"
+
+	elif get_op(instr) == 36:
+		return "stw"
+
+	elif get_op(instr) == 37:
+		return "stwu"
+
+	elif get_op(instr) == 38:
+		return "stb"
+
+	elif get_op(instr) == 39:
+		return "stbu"
+
+	elif get_op(instr) == 40:
+		return "lhz"
+
+	elif get_op(instr) == 41:
+		return "lhzu"
+
+	elif get_op(instr) == 44:
+		return "sth"
+
+	elif get_op(instr) == 45:
+		return "sthu"
+
+	else:
+		return "unknown"
+
+def get_sprn_name(sprn):
+		if sprn == 0x01a:
+			return "SRR0"
+		elif sprn == 0x01b:
+			return "SRR1"
+		elif sprn == 0x3b2:
+			return "MMUCR"
+		elif sprn == 0x030:
+			return "PID"
+		elif sprn == 0x03f:
+			return "IVPR"
+		elif sprn == 0x3b3:
+			return "CCR0"
+		elif sprn == 0x378:
+			return "CCR1"
+		elif sprn == 0x11f:
+			return "PVR"
+		elif sprn == 0x03d:
+			return "DEAR"
+		elif sprn == 0x03e:
+			return "ESR"
+		elif sprn == 0x134:
+			return "DBCR0"
+		elif sprn == 0x135:
+			return "DBCR1"
+		elif sprn == 0x11c:
+			return "TBWL"
+		elif sprn == 0x11d:
+			return "TBWU"
+		elif sprn == 0x016:
+			return "DEC"
+		elif sprn == 0x150:
+			return "TSR"
+		elif sprn == 0x154:
+			return "TCR"
+		elif sprn == 0x110:
+			return "SPRG0"
+		elif sprn == 0x111:
+			return "SPRG1"
+		elif sprn == 0x112:
+			return "SPRG2"
+		elif sprn == 0x113:
+			return "SPRG3"
+		elif sprn == 0x114:
+			return "SPRG4"
+		elif sprn == 0x115:
+			return "SPRG5"
+		elif sprn == 0x116:
+			return "SPRG6"
+		elif sprn == 0x117:
+			return "SPRG7"
+		elif sprn == 0x190:
+			return "IVOR0"
+		elif sprn == 0x191:
+			return "IVOR1"
+		elif sprn == 0x192:
+			return "IVOR2"
+		elif sprn == 0x193:
+			return "IVOR3"
+		elif sprn == 0x194:
+			return "IVOR4"
+		elif sprn == 0x195:
+			return "IVOR5"
+		elif sprn == 0x196:
+			return "IVOR6"
+		elif sprn == 0x197:
+			return "IVOR7"
+		elif sprn == 0x198:
+			return "IVOR8"
+		elif sprn == 0x199:
+			return "IVOR9"
+		elif sprn == 0x19a:
+			return "IVOR10"
+		elif sprn == 0x19b:
+			return "IVOR11"
+		elif sprn == 0x19c:
+			return "IVOR12"
+		elif sprn == 0x19d:
+			return "IVOR13"
+		elif sprn == 0x19e:
+			return "IVOR14"
+		elif sprn == 0x19f:
+			return "IVOR15"
+		else:
+			return "UNKNOWN"
+
+def get_special(instr):
+	if get_op(instr) == 31:
+		if (get_xop(instr) == 339) or (get_xop(instr) == 467):
+			sprn = get_sprn(instr);
+			return ("- sprn 0x%03x %8s" % (sprn, get_sprn_name(sprn)))
+		elif (get_xop(instr) == 323 ) or (get_xop(instr) == 451):
+			return ("- dcrn 0x%03x" % get_dcrn(instr))
+		elif (get_xop(instr) == 978 ) or (get_xop(instr) == 451):
+			return ("- ws -> %8s" % get_tlbwe_type(instr))
+	return ""
 
 ##### Main code
 
@@ -206,20 +450,24 @@
                 '4'     : d4,
                 '5'     : d5    }
 
-        try:
-
-            if defs.has_key(str(event)):
-                print defs[str(event)] % args
-            else:
-                if defs.has_key(str(0)): print defs[str(0)] % args
-        except TypeError:
-            if defs.has_key(str(event)):
-                print defs[str(event)]
-                print args
-            else:
-                if defs.has_key(str(0)):
-                    print defs[str(0)]
+        # some event types need more than just formats mapping they are if/elif
+        # chained here and the last default else is the mapping via formats
+        if event == 0x00020019:
+            pdata = (tsc, reltsc, vcpu_id, pid, d1, d2, d3, get_name(d1), get_special(d1))
+            print "%d (+%12d)  PPC_INSTR vcpu = 0x%08x  pid = 0x%08x [ instr = 0x%08x, pc = 0x%08x, emul = %01d, mnemonic = %8s %s" % pdata
+        else:
+            try:
+                if defs.has_key(str(event)):
+                    print defs[str(event)] % args
+                else:
+                    if defs.has_key(str(0)): print defs[str(0)] % args
+            except TypeError:
+                if defs.has_key(str(event)):
+                    print defs[str(event)]
                     print args
-
+                else:
+                    if defs.has_key(str(0)):
+                        print defs[str(0)]
+                        print args
 
     except IOError, struct.error: sys.exit()

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 8/9] kvm-userspace: kvmtrace_format: add statistic section
  2008-07-10 10:54 [PATCH 0/5] kvmtrace: powerpc support and timestamps for KVM_TRACE ehrhardt
                   ` (6 preceding siblings ...)
  2008-07-10 10:54 ` [PATCH 7/9] kvm-userspace: kvmtrace_format: add ppc " ehrhardt
@ 2008-07-10 10:54 ` ehrhardt
  2008-07-10 10:54 ` [PATCH 9/9] kvm-userspace: kvmtrace: rename cycles to timestamp ehrhardt
  8 siblings, 0 replies; 11+ messages in thread
From: ehrhardt @ 2008-07-10 10:54 UTC (permalink / raw)
  To: kvm; +Cc: hollisb, avi, kvm-ppc, ehrhardt

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

Usually people don't want to read thousands of trace log lines to interpret
the data, a condensed statistic about the traced events is usually better
to read.
This patch adds a new command line switch -s that tells kvmtrace_format to
generate statistics while processing the trace records. Those statistics are
then printed at the end of the output.
This patch contains a statistic function for the ppc instruction emulation.
An example output might look like that:

      mnemonic +      count
---------------+-----------
        wrteei |       1260
         mfmsr |        977
         mtspr |        895
         wrtee |        742
         mfspr |        534
           rfi |        179
         mtmsr |         90
           lbz |         53
           stb |         28
           sum =       4758
[...] more detailed statistics about spr, dcr and tlb usage

Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 kvmtrace_format |   73 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 67 insertions(+), 6 deletions(-)

[diff]
diff --git a/user/kvmtrace_format b/user/kvmtrace_format
--- a/user/kvmtrace_format
+++ b/user/kvmtrace_format
@@ -4,7 +4,7 @@
 
 # Program for reformatting trace buffer output according to user-supplied rules
 
-import re, sys, string, signal, struct, os, getopt
+import re, sys, string, signal, struct, os, getopt, operator
 
 def usage():
     print >> sys.stderr, \
@@ -29,6 +29,12 @@
           this script may not be able to keep up with the output of kvmtrace
           if it is piped directly.  In these circumstances you should have
           kvmtrace output to a file for processing off-line.
+
+          kvmtrace_format has the following additional switches
+          -c mhz - specifies the mhz of the traced machine used to convert
+                   cycle data in trace records into time
+          -s     - if this switch is set additional trace statistics are
+                   created and printed at the end of the output
           """
     sys.exit(1)
 
@@ -60,6 +66,33 @@
     interrupted = 1
 
 # ppc instruction decoding for event type 0x00020019 (PPC_INSTR)
+# some globals for statistic summaries
+stat_ppc_instr_mnemonic = {};
+stat_ppc_instr_spr = {};
+stat_ppc_instr_dcr = {};
+stat_ppc_instr_tlb = {};
+
+def ppc_instr_print_summary(sortedlist, colname):
+	print "\n\n%14s + %10s" % (colname, "count")
+	print "%s" % (15*"-"+"+"+11*"-")
+	sum = 0
+	for value, key in sortedlist:
+		sum += key
+		print "%14s | %10d" % (value, key)
+	print "%14s = %10d" % ("sum", sum)
+
+
+def ppc_instr_summary():
+	# don't print empty statistics
+        if stat_ppc_instr_mnemonic:
+		ppc_instr_print_summary(sorted(stat_ppc_instr_mnemonic.iteritems(), key=operator.itemgetter(1), reverse=True), "mnemonic")
+        if stat_ppc_instr_spr:
+		ppc_instr_print_summary(sorted(stat_ppc_instr_spr.iteritems(), key=operator.itemgetter(1), reverse=True), "mnemonic-spr")
+        if stat_ppc_instr_dcr:
+		ppc_instr_print_summary(sorted(stat_ppc_instr_dcr.iteritems(), key=operator.itemgetter(1), reverse=True), "mnemonic-dcr")
+        if stat_ppc_instr_tlb:
+		ppc_instr_print_summary(sorted(stat_ppc_instr_tlb.iteritems(), key=operator.itemgetter(1), reverse=True), "mnemonic-tlb")
+
 def get_op(instr):
         return (instr >> 26);
 
@@ -293,28 +326,53 @@
 			return "UNKNOWN"
 
 def get_special(instr):
+	name = get_name(instr);
+	if stat_ppc_instr_mnemonic.has_key(name):
+		stat_ppc_instr_mnemonic[name] += 1
+	else:
+		stat_ppc_instr_mnemonic[name] = 1
+
 	if get_op(instr) == 31:
 		if (get_xop(instr) == 339) or (get_xop(instr) == 467):
 			sprn = get_sprn(instr);
-			return ("- sprn 0x%03x %8s" % (sprn, get_sprn_name(sprn)))
+			sprn_name = get_sprn_name(sprn);
+			stat_idx = name+"-"+sprn_name
+			if stat_ppc_instr_spr.has_key(stat_idx):
+				stat_ppc_instr_spr[stat_idx] += 1
+			else:
+				stat_ppc_instr_spr[stat_idx] = 1
+			return ("- sprn 0x%03x %8s" % (sprn, sprn_name))
 		elif (get_xop(instr) == 323 ) or (get_xop(instr) == 451):
-			return ("- dcrn 0x%03x" % get_dcrn(instr))
+			dcrn = get_dcrn(instr);
+			stat_idx = name+"-"+("%04X"%dcrn)
+			if stat_ppc_instr_dcr.has_key(stat_idx):
+				stat_ppc_instr_dcr[stat_idx] += 1
+			else:
+				stat_ppc_instr_dcr[stat_idx] = 1
+			return ("- dcrn 0x%03x" % dcrn)
 		elif (get_xop(instr) == 978 ) or (get_xop(instr) == 451):
-			return ("- ws -> %8s" % get_tlbwe_type(instr))
+			tlbwe_type = get_tlbwe_type(instr)
+			stat_idx = name+"-"+tlbwe_type
+			if stat_ppc_instr_tlb.has_key(stat_idx):
+				stat_ppc_instr_tlb[stat_idx] += 1
+			else:
+				stat_ppc_instr_tlb[stat_idx] = 1
+			return ("- ws -> %8s" % tlbwe_type)
 	return ""
 
 ##### Main code
 
 mhz = 0
+summary = False
 
 if len(sys.argv) < 2:
     usage()
 
 try:
-    opts, arg = getopt.getopt(sys.argv[1:], "c:" )
-
+    opts, arg = getopt.getopt(sys.argv[1:], "sc:" )
     for opt in opts:
         if opt[0] == '-c' : mhz = int(opt[1])
+        if opt[0] == '-s' : summary = True
 
 except getopt.GetoptError:
     usage()
@@ -471,3 +529,6 @@
                         print args
 
     except IOError, struct.error: sys.exit()
+
+if summary:
+	ppc_instr_summary()

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 9/9] kvm-userspace: kvmtrace: rename cycles to timestamp
  2008-07-10 10:54 [PATCH 0/5] kvmtrace: powerpc support and timestamps for KVM_TRACE ehrhardt
                   ` (7 preceding siblings ...)
  2008-07-10 10:54 ` [PATCH 8/9] kvm-userspace: kvmtrace_format: add statistic section ehrhardt
@ 2008-07-10 10:54 ` ehrhardt
  8 siblings, 0 replies; 11+ messages in thread
From: ehrhardt @ 2008-07-10 10:54 UTC (permalink / raw)
  To: kvm; +Cc: hollisb, avi, kvm-ppc, ehrhardt

From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>

Due to the fact that the cycle counter is now completely replaced by the more
generic time based code (getnstimeofday) this patch renames all occurances of
the old cycle code to make it clear that this is now a timestamp.
Due to some values now growing a big larger (relts) the patch also
increases the print width of those values.

Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
---

[diffstat]
 formats         |   50 +++++++++++++++++++++++++-------------------------
 kvmtrace_format |   41 +++++++++++++++++------------------------
 2 files changed, 42 insertions(+), 49 deletions(-)

[diff]

diff --git a/user/formats b/user/formats
--- a/user/formats
+++ b/user/formats
@@ -1,31 +1,31 @@
-0x00000000  %(tsc)d (+%(reltsc)8d)  unknown (0x%(event)016x) vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ 0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x ]
+0x00000000  %(ts)d (+%(relts)12d)  unknown (0x%(event)016x) vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ 0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x ]
 
-0x00010001  %(tsc)d (+%(reltsc)8d)  VMENTRY       vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x
-0x00010002  %(tsc)d (+%(reltsc)8d)  VMEXIT        vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ exitcode = 0x%(1)08x, rip = 0x%(3)08x %(2)08x ]
-0x00020001  %(tsc)d (+%(reltsc)8d)  PAGE_FAULT    vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ errorcode = 0x%(1)08x, virt = 0x%(3)08x %(2)08x ]
-0x00020002  %(tsc)d (+%(reltsc)8d)  INJ_VIRQ      vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
-0x00020003  %(tsc)d (+%(reltsc)8d)  REDELIVER_EVT vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
-0x00020004  %(tsc)d (+%(reltsc)8d)  PEND_INTR     vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
-0x00020005  %(tsc)d (+%(reltsc)8d)  IO_READ       vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ port = 0x%(1)04x, size = %(2)d ]
-0x00020006  %(tsc)d (+%(reltsc)8d)  IO_WRITE      vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ port = 0x%(1)04x, size = %(2)d ]
-0x00020007  %(tsc)d (+%(reltsc)8d)  CR_READ       vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ CR# = %(1)d, value = 0x%(3)08x %(2)08x ]
-0x00020008  %(tsc)d (+%(reltsc)8d)  CR_WRITE      vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ CR# = %(1)d, value = 0x%(3)08x %(2)08x ]
-0x00020009  %(tsc)d (+%(reltsc)8d)  DR_READ       vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ DR# = %(1)d, value = 0x%(2)08x ]
-0x0002000A  %(tsc)d (+%(reltsc)8d)  DR_WRITE      vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ DR# = %(1)d, value = 0x%(2)08x ]
-0x0002000B  %(tsc)d (+%(reltsc)8d)  MSR_READ      vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ MSR# = 0x%(1)08x, data = 0x%(3)08x %(2)08x ]
-0x0002000C  %(tsc)d (+%(reltsc)8d)  MSR_WRITE     vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ MSR# = 0x%(1)08x, data = 0x%(3)08x %(2)08x ]
-0x0002000D  %(tsc)d (+%(reltsc)8d)  CPUID         vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ func = 0x%(1)08x, eax = 0x%(2)08x, ebx = 0x%(3)08x, ecx = 0x%(4)08x edx = 0x%(5)08x]
-0x0002000E  %(tsc)d (+%(reltsc)8d)  INTR          vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
-0x0002000F  %(tsc)d (+%(reltsc)8d)  NMI           vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x
-0x00020010  %(tsc)d (+%(reltsc)8d)  VMMCALL       vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ func = 0x%(1)08x ]
-0x00020011  %(tsc)d (+%(reltsc)8d)  HLT           vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x
-0x00020012  %(tsc)d (+%(reltsc)8d)  CLTS          vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x
-0x00020013  %(tsc)d (+%(reltsc)8d)  LMSW          vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ value = 0x%(1)08x ]
-0x00020014  %(tsc)d (+%(reltsc)8d)  APIC_ACCESS   vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ offset = 0x%(1)08x ]
-0x00020015  %(tsc)d (+%(reltsc)8d)  TDP_FAULT     vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ errorcode = 0x%(1)08x, virt = 0x%(3)08x %(2)08x ]
+0x00010001  %(ts)d (+%(relts)12d)  VMENTRY       vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x
+0x00010002  %(ts)d (+%(relts)12d)  VMEXIT        vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ exitcode = 0x%(1)08x, rip = 0x%(3)08x %(2)08x ]
+0x00020001  %(ts)d (+%(relts)12d)  PAGE_FAULT    vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ errorcode = 0x%(1)08x, virt = 0x%(3)08x %(2)08x ]
+0x00020002  %(ts)d (+%(relts)12d)  INJ_VIRQ      vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
+0x00020003  %(ts)d (+%(relts)12d)  REDELIVER_EVT vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
+0x00020004  %(ts)d (+%(relts)12d)  PEND_INTR     vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
+0x00020005  %(ts)d (+%(relts)12d)  IO_READ       vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ port = 0x%(1)04x, size = %(2)d ]
+0x00020006  %(ts)d (+%(relts)12d)  IO_WRITE      vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ port = 0x%(1)04x, size = %(2)d ]
+0x00020007  %(ts)d (+%(relts)12d)  CR_READ       vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ CR# = %(1)d, value = 0x%(3)08x %(2)08x ]
+0x00020008  %(ts)d (+%(relts)12d)  CR_WRITE      vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ CR# = %(1)d, value = 0x%(3)08x %(2)08x ]
+0x00020009  %(ts)d (+%(relts)12d)  DR_READ       vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ DR# = %(1)d, value = 0x%(2)08x ]
+0x0002000A  %(ts)d (+%(relts)12d)  DR_WRITE      vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ DR# = %(1)d, value = 0x%(2)08x ]
+0x0002000B  %(ts)d (+%(relts)12d)  MSR_READ      vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ MSR# = 0x%(1)08x, data = 0x%(3)08x %(2)08x ]
+0x0002000C  %(ts)d (+%(relts)12d)  MSR_WRITE     vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ MSR# = 0x%(1)08x, data = 0x%(3)08x %(2)08x ]
+0x0002000D  %(ts)d (+%(relts)12d)  CPUID         vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ func = 0x%(1)08x, eax = 0x%(2)08x, ebx = 0x%(3)08x, ecx = 0x%(4)08x edx = 0x%(5)08x]
+0x0002000E  %(ts)d (+%(relts)12d)  INTR          vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ vector = 0x%(1)02x ]
+0x0002000F  %(ts)d (+%(relts)12d)  NMI           vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x
+0x00020010  %(ts)d (+%(relts)12d)  VMMCALL       vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ func = 0x%(1)08x ]
+0x00020011  %(ts)d (+%(relts)12d)  HLT           vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x
+0x00020012  %(ts)d (+%(relts)12d)  CLTS          vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x
+0x00020013  %(ts)d (+%(relts)12d)  LMSW          vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ value = 0x%(1)08x ]
+0x00020014  %(ts)d (+%(relts)12d)  APIC_ACCESS   vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ offset = 0x%(1)08x ]
+0x00020015  %(ts)d (+%(relts)12d)  TDP_FAULT     vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ errorcode = 0x%(1)08x, virt = 0x%(3)08x %(2)08x ]
 # ppc: tlb traces
 0x00020016  GTLB_WRITE    vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
 0x00020017  STLB_WRITE    vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
 0x00020018  STLB_INVAL    vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ index = 0x%(1)08x, tid = 0x%(2)08x, word1=0x%(3)08x, word2=0x%(4)08x, word3=0x%(5)08x ]
 # ppc: instruction emulation - this type is handled more complex in kvmtrace_format, but listed to show the eventid and transported data
-#0x00020019  %(tsc)d (+%(reltsc)8d)  PPC_INSTR     vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ instr = 0x%(1)08x, pc = 0x%(2)08x, emul = 0x%(3)08x, nsec = %(4)08d ]
+#0x00020019  %(ts)d (+%(relts)12d)  PPC_INSTR     vcpu = 0x%(vcpu)08x  pid = 0x%(pid)08x [ instr = 0x%(1)08x, pc = 0x%(2)08x, emul = 0x%(3)08x, nsec = %(4)08d ]
diff --git a/user/kvmtrace_format b/user/kvmtrace_format
--- a/user/kvmtrace_format
+++ b/user/kvmtrace_format
@@ -17,7 +17,7 @@
           {event_id}{whitespace}{text format string}
 
           The textual format string may include format specifiers, such as:
-            %(tsc)d, %(event)d, %(pid)d %(vcpu)d %(1)d, %(2)d,
+            %(ts)d, %(event)d, %(pid)d %(vcpu)d %(1)d, %(2)d,
 	    %(3)d, %(4)d, %(5)d
           [ the 'd' format specifier outputs in decimal, alternatively 'x'
             will output in hexadecimal and 'o' will output in octal ]
@@ -31,8 +31,6 @@
           kvmtrace output to a file for processing off-line.
 
           kvmtrace_format has the following additional switches
-          -c mhz - specifies the mhz of the traced machine used to convert
-                   cycle data in trace records into time
           -s     - if this switch is set additional trace statistics are
                    created and printed at the end of the output
           """
@@ -362,7 +360,6 @@
 
 ##### Main code
 
-mhz = 0
 summary = False
 
 if len(sys.argv) < 2:
@@ -371,7 +368,6 @@
 try:
     opts, arg = getopt.getopt(sys.argv[1:], "sc:" )
     for opt in opts:
-        if opt[0] == '-c' : mhz = int(opt[1])
         if opt[0] == '-s' : summary = True
 
 except getopt.GetoptError:
@@ -388,12 +384,12 @@
 # structure of trace record (as output by kvmtrace):
 # HDR(I) {TSC(Q)} D1(I) D2(I) D3(I) D4(I) D5(I)
 #
-# HDR consists of EVENT:28:, n_data:3:, tsc_in:1:
+# HDR consists of EVENT:28:, n_data:3:, ts_in:1:
 # pid:32, vcpu_id:32
 # EVENT means Event ID
 # n_data means number of data (like D1, D2, ...)
-# tsc_in means TSC data exists(1) or not(0).
-# if tsc_in == 0, TSC(Q) does not exists.
+# ts_in means Timestamp data exists(1) or not(0).
+# if ts_in == 0, TSC(Q) does not exists.
 #
 HDRREC = "<III"
 TSCREC = "<Q"
@@ -404,7 +400,7 @@
 D5REC  = "<IIIII"
 KMAGIC  = "<I"
 
-last_tsc = 0
+last_ts = 0
 
 i=0
 
@@ -441,7 +437,7 @@
 	(event, pid, vcpu_id) = struct.unpack(HDRREC, line)
 
         n_data = event >> 28 & 0x7
-        tsc_in = event >> 31
+        ts_in = event >> 31
 
         d1 = 0
         d2 = 0
@@ -449,13 +445,13 @@
         d4 = 0
         d5 = 0
 
-        tsc = 0
+        ts = 0
 
-        if tsc_in == 1:
+        if ts_in == 1:
             line = sys.stdin.read(struct.calcsize(TSCREC))
             if not line:
                 break
-            tsc = struct.unpack(TSCREC, line)[0]
+            ts = struct.unpack(TSCREC, line)[0]
         if n_data == 1:
             line = sys.stdin.read(struct.calcsize(D1REC))
             if not line:
@@ -486,20 +482,17 @@
 
         # provide relative TSC
 
-        if last_tsc > 0 and tsc_in == 1:
-            reltsc = tsc - last_tsc
+        if last_ts > 0 and ts_in == 1:
+            relts = ts - last_ts
         else:
-            reltsc = 0
+            relts = 0
 
-        if tsc_in == 1:
-            last_tsc = tsc
+        if ts_in == 1:
+            last_ts = ts
 
-        if mhz:
-            tsc = tsc / (mhz*1000000.0)
-
-        args = {'tsc'   : tsc,
+        args = {'ts'   : ts,
                 'event' : event,
-                'reltsc': reltsc,
+                'relts': relts,
 		'pid'   : pid,
 		'vcpu'  : vcpu_id,
                 '1'     : d1,
@@ -511,7 +504,7 @@
         # some event types need more than just formats mapping they are if/elif
         # chained here and the last default else is the mapping via formats
         if event == 0x00020019:
-            pdata = (tsc, reltsc, vcpu_id, pid, d1, d2, d3, get_name(d1), get_special(d1))
+            pdata = (ts, relts, vcpu_id, pid, d1, d2, d3, get_name(d1), get_special(d1))
             print "%d (+%12d)  PPC_INSTR vcpu = 0x%08x  pid = 0x%08x [ instr = 0x%08x, pc = 0x%08x, emul = %01d, mnemonic = %8s %s" % pdata
         else:
             try:

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/9] kvmtrace: replace get_cycles with getnstimeofday
  2008-07-10 10:54 ` [PATCH 2/9] kvmtrace: replace get_cycles with getnstimeofday ehrhardt
@ 2008-07-10 15:15   ` Avi Kivity
  0 siblings, 0 replies; 11+ messages in thread
From: Avi Kivity @ 2008-07-10 15:15 UTC (permalink / raw)
  To: ehrhardt; +Cc: kvm, hollisb, kvm-ppc

ehrhardt@linux.vnet.ibm.com wrote:
> From: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
>
> The current kvmtrace code uses get_cycles() while the interpretation would be
> easier using using nanoseconds. Getnstimeofday should give the same accuracy
> as get_cycles on all architectures but at a better unit (e.g. comparable
> between two hosts with different frequencies.
>
> The implementation of kvmtrace uses a 64 bit cycle variable while get_cycles
> only provided a unsigned long which is != 64 bit on 32 bit architectures.
> Since this patch introduced getnstimeofday we can addtionally merge the
> tv_sec portion of the struct timespec returned to use the full 64 bit
> of the trace interface and therefor avoid some wraparounds. This merge
> is done always if the two values of a struct timespec fit into the u64.
>
> An alternative might be ktime_t instead of u64 and using as Sheng Yang
> suggested and ktime_get(), I had no time to test&compare that yet.
> Any comments or requirements from others what to prefer here ?
>
> Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
> ---
>
> [diffstat]
>  kvm_trace.c |    9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
>
> [diff]
>
> diff --git a/virt/kvm/kvm_trace.c b/virt/kvm/kvm_trace.c
> --- a/virt/kvm/kvm_trace.c
> +++ b/virt/kvm/kvm_trace.c
> @@ -56,6 +56,7 @@
>  	struct kvm_vcpu *vcpu;
>  	int    i, size;
>  	u32    extra;
> +	struct timespec tv;
>  
>  	if (unlikely(kt->trace_state != KVM_TRACE_STATE_RUNNING))
>  		return;
> @@ -73,7 +74,13 @@
>  			| TRACE_REC_NUM_DATA_ARGS(extra);
>  	
>  	if (p->cycle_in) {
> -		rec.u.cycle.cycle_u64 = get_cycles();
> +		getnstimeofday(&tv);
> +		/* compress both struct tv values into u64 on 32 bit archs */
> +		if (sizeof(tv) == sizeof(u64))
> +			rec.u.cycle.cycle_u64 = 
> +				(((u64)tv.tv_sec) << 32) | tv.tv_nsec;
> +		else
> +			rec.u.cycle.cycle_u64 = tv.tv_nsec;
>  (*args, u32);
>   

Surely, different results on 32-bit and 64-bit aren't what's wanted.  I 
guess ktime_get() is better.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2008-07-10 15:15 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-10 10:54 [PATCH 0/5] kvmtrace: powerpc support and timestamps for KVM_TRACE ehrhardt
2008-07-10 10:54 ` [PATCH 1/9] kvmtrace: Remove use of bit fields in kvm trace structure v3 ehrhardt
2008-07-10 10:54 ` [PATCH 2/9] kvmtrace: replace get_cycles with getnstimeofday ehrhardt
2008-07-10 15:15   ` Avi Kivity
2008-07-10 10:54 ` [PATCH 3/9] kvmtrace: rename cycles to timestamp ehrhardt
2008-07-10 10:54 ` [PATCH 3/9] kvmppc: kvmtrace: enable KVM_TRACE building for powerpc ehrhardt
2008-07-10 10:54 ` [PATCH 4/9] kvmppc: kvmtrace: adds trace points for ppc tlb activity v2 ehrhardt
2008-07-10 10:54 ` [PATCH 5/9] kvmppc: kvmtrace: trace powerpc instruction emulation ehrhardt
2008-07-10 10:54 ` [PATCH 7/9] kvm-userspace: kvmtrace_format: add ppc " ehrhardt
2008-07-10 10:54 ` [PATCH 8/9] kvm-userspace: kvmtrace_format: add statistic section ehrhardt
2008-07-10 10:54 ` [PATCH 9/9] kvm-userspace: kvmtrace: rename cycles to timestamp ehrhardt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox