linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/4] x86: Don't include asm/processor.h into asm/atomic.h
@ 2015-12-02  1:00 Andi Kleen
  2015-12-02  1:00 ` [PATCH 2/4] tracepoints: Move struct tracepoint to new tracepoint-defs.h header Andi Kleen
                   ` (4 more replies)
  0 siblings, 5 replies; 25+ messages in thread
From: Andi Kleen @ 2015-12-02  1:00 UTC (permalink / raw)
  To: x86; +Cc: rostedt, peterz, linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

asm/atomic.h doesn't really need asm/processor.h anymore. Everything
it uses has moved to other header files. So remove that include.

processor.h is a nasty header that includes lots of
other headers and makes it prone to include loops. Removing the
include here makes asm/atomic.h a "leaf" header that can
be safely included in most other headers.

The only fallout is in the lib/atomic tester which relied on
this implicit include. Give it an explicit include.
(the include is in ifdef because the user is also in ifdef)

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/include/asm/atomic.h      | 1 -
 arch/x86/include/asm/atomic64_32.h | 1 -
 lib/atomic64_test.c                | 4 ++++
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h
index ae5fb83..3e86742 100644
--- a/arch/x86/include/asm/atomic.h
+++ b/arch/x86/include/asm/atomic.h
@@ -3,7 +3,6 @@
 
 #include <linux/compiler.h>
 #include <linux/types.h>
-#include <asm/processor.h>
 #include <asm/alternative.h>
 #include <asm/cmpxchg.h>
 #include <asm/rmwcc.h>
diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h
index a11c30b..a984111 100644
--- a/arch/x86/include/asm/atomic64_32.h
+++ b/arch/x86/include/asm/atomic64_32.h
@@ -3,7 +3,6 @@
 
 #include <linux/compiler.h>
 #include <linux/types.h>
-#include <asm/processor.h>
 //#include <asm/cmpxchg.h>
 
 /* An 64bit atomic type */
diff --git a/lib/atomic64_test.c b/lib/atomic64_test.c
index 83c33a5b..d51e25a 100644
--- a/lib/atomic64_test.c
+++ b/lib/atomic64_test.c
@@ -16,6 +16,10 @@
 #include <linux/kernel.h>
 #include <linux/atomic.h>
 
+#ifdef CONFIG_X86
+#include <asm/processor.h>	/* for boot_cpu_has below */
+#endif
+
 #define TEST(bit, op, c_op, val)				\
 do {								\
 	atomic##bit##_set(&v, v0);				\
-- 
2.4.3


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

* [PATCH 2/4] tracepoints: Move struct tracepoint to new tracepoint-defs.h header
  2015-12-02  1:00 [PATCH 1/4] x86: Don't include asm/processor.h into asm/atomic.h Andi Kleen
@ 2015-12-02  1:00 ` Andi Kleen
  2015-12-02  1:56   ` Steven Rostedt
                     ` (2 more replies)
  2015-12-02  1:00 ` [PATCH 3/4] x86: Add trace point for MSR accesses Andi Kleen
                   ` (3 subsequent siblings)
  4 siblings, 3 replies; 25+ messages in thread
From: Andi Kleen @ 2015-12-02  1:00 UTC (permalink / raw)
  To: x86; +Cc: rostedt, peterz, linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Steven recommended open coding access to tracepoint->key to add
trace points to headers. Unfortunately this is difficult for some
headers (such as x86 asm/msr.h) because including tracepoint.h
includes so many other headers that it causes include loops.
The main problem is the include of linux/rcupdate.h, which
pulls in a lot of other headers. The rcu header is only needed
when actually defining trace points.

Move the struct tracepoint into a separate tracepoint-defs.h
header that can be included without pulling in all of RCU.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 include/linux/tracepoint-defs.h | 27 +++++++++++++++++++++++++++
 include/linux/tracepoint.h      | 16 +---------------
 2 files changed, 28 insertions(+), 15 deletions(-)
 create mode 100644 include/linux/tracepoint-defs.h

diff --git a/include/linux/tracepoint-defs.h b/include/linux/tracepoint-defs.h
new file mode 100644
index 0000000..e1ee97c
--- /dev/null
+++ b/include/linux/tracepoint-defs.h
@@ -0,0 +1,27 @@
+#ifndef TRACEPOINT_DEFS_H
+#define TRACEPOINT_DEFS_H 1
+
+/*
+ * File can be included directly by headers who only want to access
+ * tracepoint->key to guard out of line trace calls. Otherwise
+ * linux/tracepoint.h should be used.
+ */
+
+#include <linux/atomic.h>
+#include <linux/static_key.h>
+
+struct tracepoint_func {
+	void *func;
+	void *data;
+	int prio;
+};
+
+struct tracepoint {
+	const char *name;		/* Tracepoint name */
+	struct static_key key;
+	void (*regfunc)(void);
+	void (*unregfunc)(void);
+	struct tracepoint_func __rcu *funcs;
+};
+
+#endif
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 696a339c..f7c732b 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -17,26 +17,12 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/rcupdate.h>
-#include <linux/static_key.h>
+#include <linux/tracepoint-defs.h>
 
 struct module;
 struct tracepoint;
 struct notifier_block;
 
-struct tracepoint_func {
-	void *func;
-	void *data;
-	int prio;
-};
-
-struct tracepoint {
-	const char *name;		/* Tracepoint name */
-	struct static_key key;
-	void (*regfunc)(void);
-	void (*unregfunc)(void);
-	struct tracepoint_func __rcu *funcs;
-};
-
 struct trace_enum_map {
 	const char		*system;
 	const char		*enum_string;
-- 
2.4.3


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

* [PATCH 3/4] x86: Add trace point for MSR accesses
  2015-12-02  1:00 [PATCH 1/4] x86: Don't include asm/processor.h into asm/atomic.h Andi Kleen
  2015-12-02  1:00 ` [PATCH 2/4] tracepoints: Move struct tracepoint to new tracepoint-defs.h header Andi Kleen
@ 2015-12-02  1:00 ` Andi Kleen
  2015-12-02  2:03   ` Steven Rostedt
                     ` (2 more replies)
  2015-12-02  1:01 ` [PATCH 4/4] perf, x86: Remove old MSR perf tracing code Andi Kleen
                   ` (2 subsequent siblings)
  4 siblings, 3 replies; 25+ messages in thread
From: Andi Kleen @ 2015-12-02  1:00 UTC (permalink / raw)
  To: x86; +Cc: rostedt, peterz, linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

For debugging low level code interacting with the CPU
it is often useful to trace the MSR read/writes. This gives
a concise summary of PMU and other operations.

perf has an ad-hoc way to do this using trace_printk,
but it's somewhat limited (and also now spews ugly boot
messages when enabled)

Instead define real trace points for all MSR accesses.

This adds three new trace points: read_msr and write_msr
and rdpmc.

They also report if the access faulted (if *_safe is used)

This allows filtering and triggering on specific
MSR values, which allows various more advanced
debugging techniques.

All the values are well defined in the CPU documentation.

The trace can be post processed with
Documentation/trace/postprocess/decode_msr.py
to add symbolic MSR names to the trace.

I only added it to native MSR accesses in C, not paravirtualized
or in entry*.S (which is not too interesting)

Originally the patch kit moved the MSRs out of line.
This uses an alternative approach recommended by Steven Rostedt
of only moving the trace calls out of line, but open coding the
access to the jump label.

v2:
Move MSR trace events to arch/x86/include/asm/msr-trace.h
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 Documentation/trace/events-msr.txt            | 37 +++++++++++++++++
 Documentation/trace/postprocess/decode_msr.py | 37 +++++++++++++++++
 arch/x86/include/asm/msr-trace.h              | 57 +++++++++++++++++++++++++++
 arch/x86/include/asm/msr.h                    | 31 +++++++++++++++
 arch/x86/lib/msr.c                            | 26 ++++++++++++
 5 files changed, 188 insertions(+)
 create mode 100644 Documentation/trace/events-msr.txt
 create mode 100755 Documentation/trace/postprocess/decode_msr.py
 create mode 100644 arch/x86/include/asm/msr-trace.h

diff --git a/Documentation/trace/events-msr.txt b/Documentation/trace/events-msr.txt
new file mode 100644
index 0000000..78c383b
--- /dev/null
+++ b/Documentation/trace/events-msr.txt
@@ -0,0 +1,37 @@
+
+The x86 kernel supports tracing most MSR (Model Specific Register) accesses.
+To see the definition of the MSRs on Intel systems please see the SDM
+at http://www.intel.com/sdm (Volume 3)
+
+Available trace points:
+
+/sys/kernel/debug/tracing/events/msr/
+
+Trace MSR reads
+
+read_msr
+
+msr: MSR number
+val: Value written
+failed: 1 if the access failed, otherwise 0
+
+
+Trace MSR writes
+
+write_msr
+
+msr: MSR number
+val: Value written
+failed: 1 if the access failed, otherwise 0
+
+
+Trace RDPMC in kernel
+
+rdpmc
+
+The trace data can be post processed with the postprocess/decode_msr.py script
+
+cat /sys/kernel/debug/tracing/trace | decode_msr.py /usr/src/linux/include/asm/msr-index.h
+
+to add symbolic MSR names.
+
diff --git a/Documentation/trace/postprocess/decode_msr.py b/Documentation/trace/postprocess/decode_msr.py
new file mode 100755
index 0000000..0ab40e0
--- /dev/null
+++ b/Documentation/trace/postprocess/decode_msr.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+# add symbolic names to read_msr / write_msr in trace
+# decode_msr msr-index.h < trace
+import sys
+import re
+
+msrs = dict()
+
+with open(sys.argv[1] if len(sys.argv) > 1 else "msr-index.h", "r") as f:
+	for j in f:
+		m = re.match(r'#define (MSR_\w+)\s+(0x[0-9a-fA-F]+)', j)
+		if m:
+			msrs[int(m.group(2), 16)] = m.group(1)
+
+extra_ranges = (
+	( "MSR_LASTBRANCH_%d_FROM_IP", 0x680, 0x69F ),
+	( "MSR_LASTBRANCH_%d_TO_IP", 0x6C0, 0x6DF ),
+	( "LBR_INFO_%d", 0xdc0, 0xddf ),
+)
+
+for j in sys.stdin:
+	m = re.search(r'(read|write)_msr:\s+([0-9a-f]+)', j)
+	if m:
+		r = None
+		num = int(m.group(2), 16)
+		if num in msrs:
+			r = msrs[num]
+		else:
+			for er in extra_ranges:
+				if er[1] <= num <= er[2]:
+					r = er[0] % (num - er[1],)
+					break
+		if r:
+			j = j.replace(" " + m.group(2), " " + r + "(" + m.group(2) + ")")
+	print j,
+
+
diff --git a/arch/x86/include/asm/msr-trace.h b/arch/x86/include/asm/msr-trace.h
new file mode 100644
index 0000000..7567225
--- /dev/null
+++ b/arch/x86/include/asm/msr-trace.h
@@ -0,0 +1,57 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM msr
+
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE msr-trace
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH asm/
+
+#if !defined(_TRACE_MSR_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_MSR_H
+
+#include <linux/tracepoint.h>
+
+/*
+ * Tracing for x86 model specific registers. Directly maps to the
+ * RDMSR/WRMSR instructions.
+ */
+
+DECLARE_EVENT_CLASS(msr_trace_class,
+	    TP_PROTO(unsigned msr, u64 val, int failed),
+	    TP_ARGS(msr, val, failed),
+	    TP_STRUCT__entry(
+		    __field(	unsigned,	msr )
+		    __field(    u64,		val )
+		    __field(    int,		failed )
+	    ),
+	    TP_fast_assign(
+		    __entry->msr = msr;
+		    __entry->val = val;
+		    __entry->failed = failed;
+	    ),
+	    TP_printk("%x, value %llx%s",
+		      __entry->msr,
+		      __entry->val,
+		      __entry->failed ? " #GP" : "")
+);
+
+DEFINE_EVENT(msr_trace_class, read_msr,
+	     TP_PROTO(unsigned msr, u64 val, int failed),
+	     TP_ARGS(msr, val, failed)
+);
+
+DEFINE_EVENT(msr_trace_class, write_msr,
+	     TP_PROTO(unsigned msr, u64 val, int failed),
+	     TP_ARGS(msr, val, failed)
+);
+
+DEFINE_EVENT(msr_trace_class, rdpmc,
+	     TP_PROTO(unsigned msr, u64 val, int failed),
+	     TP_ARGS(msr, val, failed)
+);
+
+#endif /* _TRACE_MSR_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 77d8b28..fedd6e6 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -57,11 +57,34 @@ static inline unsigned long long native_read_tscp(unsigned int *aux)
 #define EAX_EDX_RET(val, low, high)	"=A" (val)
 #endif
 
+#ifdef CONFIG_TRACEPOINTS
+/*
+ * Be very careful with includes. This header is prone to include loops.
+ */
+#include <asm/atomic.h>
+#include <linux/tracepoint-defs.h>
+
+extern struct tracepoint __tracepoint_read_msr;
+extern struct tracepoint __tracepoint_write_msr;
+extern struct tracepoint __tracepoint_rdpmc;
+#define msr_tracepoint_active(t) static_key_false(&(t).key)
+extern void do_trace_write_msr(unsigned msr, u64 val, int failed);
+extern void do_trace_read_msr(unsigned msr, u64 val, int failed);
+extern void do_trace_rdpmc(unsigned msr, u64 val, int failed);
+#else
+#define msr_tracepoint_active(t) false
+static inline void do_trace_write_msr(unsigned msr, u64 val, int failed) {}
+static inline void do_trace_read_msr(unsigned msr, u64 val, int failed) {}
+static inline void do_trace_rdpmc(unsigned msr, u64 val, int failed) {}
+#endif
+
 static inline unsigned long long native_read_msr(unsigned int msr)
 {
 	DECLARE_ARGS(val, low, high);
 
 	asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr));
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), 0);
 	return EAX_EDX_VAL(val, low, high);
 }
 
@@ -78,6 +101,8 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
 		     _ASM_EXTABLE(2b, 3b)
 		     : [err] "=r" (*err), EAX_EDX_RET(val, low, high)
 		     : "c" (msr), [fault] "i" (-EIO));
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), *err);
 	return EAX_EDX_VAL(val, low, high);
 }
 
@@ -85,6 +110,8 @@ static inline void native_write_msr(unsigned int msr,
 				    unsigned low, unsigned high)
 {
 	asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_write_msr(msr, ((u64)high << 32 | low), 0);
 }
 
 /* Can be uninlined because referenced by paravirt */
@@ -102,6 +129,8 @@ notrace static inline int native_write_msr_safe(unsigned int msr,
 		     : "c" (msr), "0" (low), "d" (high),
 		       [fault] "i" (-EIO)
 		     : "memory");
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_write_msr(msr, ((u64)high << 32 | low), err);
 	return err;
 }
 
@@ -160,6 +189,8 @@ static inline unsigned long long native_read_pmc(int counter)
 	DECLARE_ARGS(val, low, high);
 
 	asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
+	if (msr_tracepoint_active(__tracepoint_rdpmc))
+		do_trace_rdpmc(counter, EAX_EDX_VAL(val, low, high), 0);
 	return EAX_EDX_VAL(val, low, high);
 }
 
diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c
index 4362373..004c861 100644
--- a/arch/x86/lib/msr.c
+++ b/arch/x86/lib/msr.c
@@ -1,6 +1,8 @@
 #include <linux/module.h>
 #include <linux/preempt.h>
 #include <asm/msr.h>
+#define CREATE_TRACE_POINTS
+#include <asm/msr-trace.h>
 
 struct msr *msrs_alloc(void)
 {
@@ -108,3 +110,27 @@ int msr_clear_bit(u32 msr, u8 bit)
 {
 	return __flip_bit(msr, bit, false);
 }
+
+#ifdef CONFIG_TRACEPOINTS
+void do_trace_write_msr(unsigned msr, u64 val, int failed)
+{
+	trace_write_msr(msr, val, failed);
+}
+EXPORT_SYMBOL(do_trace_write_msr);
+EXPORT_TRACEPOINT_SYMBOL(write_msr);
+
+void do_trace_read_msr(unsigned msr, u64 val, int failed)
+{
+	trace_read_msr(msr, val, failed);
+}
+EXPORT_SYMBOL(do_trace_read_msr);
+EXPORT_TRACEPOINT_SYMBOL(read_msr);
+
+void do_trace_rdpmc(unsigned counter, u64 val, int failed)
+{
+	trace_rdpmc(counter, val, failed);
+}
+EXPORT_SYMBOL(do_trace_rdpmc);
+EXPORT_TRACEPOINT_SYMBOL(rdpmc);
+
+#endif
-- 
2.4.3


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

* [PATCH 4/4] perf, x86: Remove old MSR perf tracing code
  2015-12-02  1:00 [PATCH 1/4] x86: Don't include asm/processor.h into asm/atomic.h Andi Kleen
  2015-12-02  1:00 ` [PATCH 2/4] tracepoints: Move struct tracepoint to new tracepoint-defs.h header Andi Kleen
  2015-12-02  1:00 ` [PATCH 3/4] x86: Add trace point for MSR accesses Andi Kleen
@ 2015-12-02  1:01 ` Andi Kleen
  2015-12-04 12:00   ` [tip:perf/core] perf/x86: " tip-bot for Andi Kleen
  2015-12-06 13:19   ` tip-bot for Andi Kleen
  2015-12-04 11:58 ` [tip:perf/core] x86/headers: Don't include asm/processor.h in asm /atomic.h tip-bot for Andi Kleen
  2015-12-06 13:18 ` tip-bot for Andi Kleen
  4 siblings, 2 replies; 25+ messages in thread
From: Andi Kleen @ 2015-12-02  1:01 UTC (permalink / raw)
  To: x86; +Cc: rostedt, peterz, linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Now that we have generic MSR trace points we can remove the old
hackish perf MSR read tracing code.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event.h | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 499f533..5300247 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -14,17 +14,7 @@
 
 #include <linux/perf_event.h>
 
-#if 0
-#undef wrmsrl
-#define wrmsrl(msr, val) 						\
-do {									\
-	unsigned int _msr = (msr);					\
-	u64 _val = (val);						\
-	trace_printk("wrmsrl(%x, %Lx)\n", (unsigned int)(_msr),		\
-			(unsigned long long)(_val));			\
-	native_write_msr((_msr), (u32)(_val), (u32)(_val >> 32));	\
-} while (0)
-#endif
+/* To enable MSR tracing please use the generic trace points. */
 
 /*
  *          |   NHM/WSM    |      SNB     |
-- 
2.4.3


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

* Re: [PATCH 2/4] tracepoints: Move struct tracepoint to new tracepoint-defs.h header
  2015-12-02  1:00 ` [PATCH 2/4] tracepoints: Move struct tracepoint to new tracepoint-defs.h header Andi Kleen
@ 2015-12-02  1:56   ` Steven Rostedt
  2015-12-04 11:59   ` [tip:perf/core] " tip-bot for Andi Kleen
  2015-12-06 13:18   ` tip-bot for Andi Kleen
  2 siblings, 0 replies; 25+ messages in thread
From: Steven Rostedt @ 2015-12-02  1:56 UTC (permalink / raw)
  To: Andi Kleen; +Cc: x86, peterz, linux-kernel, Andi Kleen

On Tue,  1 Dec 2015 17:00:58 -0800
Andi Kleen <andi@firstfloor.org> wrote:

> From: Andi Kleen <ak@linux.intel.com>
> 
> Steven recommended open coding access to tracepoint->key to add
> trace points to headers. Unfortunately this is difficult for some
> headers (such as x86 asm/msr.h) because including tracepoint.h
> includes so many other headers that it causes include loops.
> The main problem is the include of linux/rcupdate.h, which
> pulls in a lot of other headers. The rcu header is only needed
> when actually defining trace points.
> 
> Move the struct tracepoint into a separate tracepoint-defs.h
> header that can be included without pulling in all of RCU.
> 
> Signed-off-by: Andi Kleen <ak@linux.intel.com>

Acked-by: Steven Rostedt <rostedt@goodmis.org>

-- Steve

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

* Re: [PATCH 3/4] x86: Add trace point for MSR accesses
  2015-12-02  1:00 ` [PATCH 3/4] x86: Add trace point for MSR accesses Andi Kleen
@ 2015-12-02  2:03   ` Steven Rostedt
  2015-12-04 11:59   ` [tip:perf/core] x86, tracing, perf: " tip-bot for Andi Kleen
  2015-12-06 13:19   ` tip-bot for Andi Kleen
  2 siblings, 0 replies; 25+ messages in thread
From: Steven Rostedt @ 2015-12-02  2:03 UTC (permalink / raw)
  To: Andi Kleen; +Cc: x86, peterz, linux-kernel, Andi Kleen

On Tue,  1 Dec 2015 17:00:59 -0800
Andi Kleen <andi@firstfloor.org> wrote:

> From: Andi Kleen <ak@linux.intel.com>
> 
> For debugging low level code interacting with the CPU
> it is often useful to trace the MSR read/writes. This gives
> a concise summary of PMU and other operations.
> 
> perf has an ad-hoc way to do this using trace_printk,
> but it's somewhat limited (and also now spews ugly boot
> messages when enabled)
> 
> Instead define real trace points for all MSR accesses.
> 
> This adds three new trace points: read_msr and write_msr
> and rdpmc.
> 
> They also report if the access faulted (if *_safe is used)
> 
> This allows filtering and triggering on specific
> MSR values, which allows various more advanced
> debugging techniques.
> 
> All the values are well defined in the CPU documentation.
> 
> The trace can be post processed with
> Documentation/trace/postprocess/decode_msr.py
> to add symbolic MSR names to the trace.
> 
> I only added it to native MSR accesses in C, not paravirtualized
> or in entry*.S (which is not too interesting)
> 
> Originally the patch kit moved the MSRs out of line.
> This uses an alternative approach recommended by Steven Rostedt
> of only moving the trace calls out of line, but open coding the
> access to the jump label.
> 
> v2:
> Move MSR trace events to arch/x86/include/asm/msr-trace.h
> Signed-off-by: Andi Kleen <ak@linux.intel.com>
>

For the general tracing part.

Acked-by: Steven Rostedt <rostedt@goodmis.org>

-- Steve

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

* [tip:perf/core] x86/headers: Don't include asm/processor.h in asm /atomic.h
  2015-12-02  1:00 [PATCH 1/4] x86: Don't include asm/processor.h into asm/atomic.h Andi Kleen
                   ` (2 preceding siblings ...)
  2015-12-02  1:01 ` [PATCH 4/4] perf, x86: Remove old MSR perf tracing code Andi Kleen
@ 2015-12-04 11:58 ` tip-bot for Andi Kleen
  2015-12-06 13:18 ` tip-bot for Andi Kleen
  4 siblings, 0 replies; 25+ messages in thread
From: tip-bot for Andi Kleen @ 2015-12-04 11:58 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: eranian, hpa, jolsa, torvalds, acme, vincent.weaver,
	linux-kernel, peterz, tglx, ak, efault, mingo

Commit-ID:  d8cc58c8a099bb36371f4e4807fd6d34b301808f
Gitweb:     http://git.kernel.org/tip/d8cc58c8a099bb36371f4e4807fd6d34b301808f
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Tue, 1 Dec 2015 17:00:57 -0800
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 4 Dec 2015 10:58:33 +0100

x86/headers: Don't include asm/processor.h in asm/atomic.h

asm/atomic.h doesn't really need asm/processor.h anymore. Everything
it uses has moved to other header files. So remove that include.

processor.h is a nasty header that includes lots of
other headers and makes it prone to include loops. Removing the
include here makes asm/atomic.h a "leaf" header that can
be safely included in most other headers.

The only fallout is in the lib/atomic tester which relied on
this implicit include. Give it an explicit include.
(the include is in ifdef because the user is also in ifdef)

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: rostedt@goodmis.org
Link: http://lkml.kernel.org/r/1449018060-1742-1-git-send-email-andi@firstfloor.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/atomic.h      | 1 -
 arch/x86/include/asm/atomic64_32.h | 1 -
 lib/atomic64_test.c                | 4 ++++
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h
index ae5fb83..3e86742 100644
--- a/arch/x86/include/asm/atomic.h
+++ b/arch/x86/include/asm/atomic.h
@@ -3,7 +3,6 @@
 
 #include <linux/compiler.h>
 #include <linux/types.h>
-#include <asm/processor.h>
 #include <asm/alternative.h>
 #include <asm/cmpxchg.h>
 #include <asm/rmwcc.h>
diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h
index a11c30b..a984111 100644
--- a/arch/x86/include/asm/atomic64_32.h
+++ b/arch/x86/include/asm/atomic64_32.h
@@ -3,7 +3,6 @@
 
 #include <linux/compiler.h>
 #include <linux/types.h>
-#include <asm/processor.h>
 //#include <asm/cmpxchg.h>
 
 /* An 64bit atomic type */
diff --git a/lib/atomic64_test.c b/lib/atomic64_test.c
index 83c33a5b..d51e25a 100644
--- a/lib/atomic64_test.c
+++ b/lib/atomic64_test.c
@@ -16,6 +16,10 @@
 #include <linux/kernel.h>
 #include <linux/atomic.h>
 
+#ifdef CONFIG_X86
+#include <asm/processor.h>	/* for boot_cpu_has below */
+#endif
+
 #define TEST(bit, op, c_op, val)				\
 do {								\
 	atomic##bit##_set(&v, v0);				\

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

* [tip:perf/core] tracepoints: Move struct tracepoint to new tracepoint-defs.h header
  2015-12-02  1:00 ` [PATCH 2/4] tracepoints: Move struct tracepoint to new tracepoint-defs.h header Andi Kleen
  2015-12-02  1:56   ` Steven Rostedt
@ 2015-12-04 11:59   ` tip-bot for Andi Kleen
  2015-12-06 13:18   ` tip-bot for Andi Kleen
  2 siblings, 0 replies; 25+ messages in thread
From: tip-bot for Andi Kleen @ 2015-12-04 11:59 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: ak, vincent.weaver, rostedt, peterz, tglx, efault, linux-kernel,
	eranian, mingo, acme, hpa, jolsa, torvalds

Commit-ID:  44eed5cd81f3a95ab6dd67b627e0d83a769efa1f
Gitweb:     http://git.kernel.org/tip/44eed5cd81f3a95ab6dd67b627e0d83a769efa1f
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Tue, 1 Dec 2015 17:00:58 -0800
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 4 Dec 2015 10:58:34 +0100

tracepoints: Move struct tracepoint to new tracepoint-defs.h header

Steven recommended open coding access to tracepoint->key to add
trace points to headers. Unfortunately this is difficult for some
headers (such as x86 asm/msr.h) because including tracepoint.h
includes so many other headers that it causes include loops.
The main problem is the include of linux/rcupdate.h, which
pulls in a lot of other headers. The rcu header is only needed
when actually defining trace points.

Move the struct tracepoint into a separate tracepoint-defs.h
header that can be included without pulling in all of RCU.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Link: http://lkml.kernel.org/r/1449018060-1742-2-git-send-email-andi@firstfloor.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/linux/tracepoint-defs.h | 27 +++++++++++++++++++++++++++
 include/linux/tracepoint.h      | 16 +---------------
 2 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/include/linux/tracepoint-defs.h b/include/linux/tracepoint-defs.h
new file mode 100644
index 0000000..e1ee97c
--- /dev/null
+++ b/include/linux/tracepoint-defs.h
@@ -0,0 +1,27 @@
+#ifndef TRACEPOINT_DEFS_H
+#define TRACEPOINT_DEFS_H 1
+
+/*
+ * File can be included directly by headers who only want to access
+ * tracepoint->key to guard out of line trace calls. Otherwise
+ * linux/tracepoint.h should be used.
+ */
+
+#include <linux/atomic.h>
+#include <linux/static_key.h>
+
+struct tracepoint_func {
+	void *func;
+	void *data;
+	int prio;
+};
+
+struct tracepoint {
+	const char *name;		/* Tracepoint name */
+	struct static_key key;
+	void (*regfunc)(void);
+	void (*unregfunc)(void);
+	struct tracepoint_func __rcu *funcs;
+};
+
+#endif
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 696a339c..f7c732b 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -17,26 +17,12 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/rcupdate.h>
-#include <linux/static_key.h>
+#include <linux/tracepoint-defs.h>
 
 struct module;
 struct tracepoint;
 struct notifier_block;
 
-struct tracepoint_func {
-	void *func;
-	void *data;
-	int prio;
-};
-
-struct tracepoint {
-	const char *name;		/* Tracepoint name */
-	struct static_key key;
-	void (*regfunc)(void);
-	void (*unregfunc)(void);
-	struct tracepoint_func __rcu *funcs;
-};
-
 struct trace_enum_map {
 	const char		*system;
 	const char		*enum_string;

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

* [tip:perf/core] x86, tracing, perf: Add trace point for MSR accesses
  2015-12-02  1:00 ` [PATCH 3/4] x86: Add trace point for MSR accesses Andi Kleen
  2015-12-02  2:03   ` Steven Rostedt
@ 2015-12-04 11:59   ` tip-bot for Andi Kleen
  2015-12-04 12:11     ` Borislav Petkov
  2015-12-06 13:19   ` tip-bot for Andi Kleen
  2 siblings, 1 reply; 25+ messages in thread
From: tip-bot for Andi Kleen @ 2015-12-04 11:59 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: vincent.weaver, eranian, hpa, efault, peterz, jolsa, torvalds,
	tglx, ak, rostedt, acme, mingo, linux-kernel

Commit-ID:  07b41f5cf37b34ef3de4f40fbaf8547abe690abb
Gitweb:     http://git.kernel.org/tip/07b41f5cf37b34ef3de4f40fbaf8547abe690abb
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Tue, 1 Dec 2015 17:00:59 -0800
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 4 Dec 2015 10:58:34 +0100

x86, tracing, perf: Add trace point for MSR accesses

For debugging low level code interacting with the CPU it is often
useful to trace the MSR read/writes. This gives a concise summary of
PMU and other operations.

perf has an ad-hoc way to do this using trace_printk, but it's
somewhat limited (and also now spews ugly boot messages when enabled)

Instead define real trace points for all MSR accesses.

This adds three new trace points: read_msr and write_msr and rdpmc.

They also report if the access faulted (if *_safe is used)

This allows filtering and triggering on specific MSR values, which
allows various more advanced debugging techniques.

All the values are well defined in the CPU documentation.

The trace can be post processed with
Documentation/trace/postprocess/decode_msr.py to add symbolic MSR
names to the trace.

I only added it to native MSR accesses in C, not paravirtualized or in
entry*.S (which is not too interesting)

Originally the patch kit moved the MSRs out of line.  This uses an
alternative approach recommended by Steven Rostedt of only moving the
trace calls out of line, but open coding the access to the jump label.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Link: http://lkml.kernel.org/r/1449018060-1742-3-git-send-email-andi@firstfloor.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 Documentation/trace/events-msr.txt            | 37 +++++++++++++++++
 Documentation/trace/postprocess/decode_msr.py | 37 +++++++++++++++++
 arch/x86/include/asm/msr-trace.h              | 57 +++++++++++++++++++++++++++
 arch/x86/include/asm/msr.h                    | 31 +++++++++++++++
 arch/x86/lib/msr.c                            | 26 ++++++++++++
 5 files changed, 188 insertions(+)

diff --git a/Documentation/trace/events-msr.txt b/Documentation/trace/events-msr.txt
new file mode 100644
index 0000000..78c383b
--- /dev/null
+++ b/Documentation/trace/events-msr.txt
@@ -0,0 +1,37 @@
+
+The x86 kernel supports tracing most MSR (Model Specific Register) accesses.
+To see the definition of the MSRs on Intel systems please see the SDM
+at http://www.intel.com/sdm (Volume 3)
+
+Available trace points:
+
+/sys/kernel/debug/tracing/events/msr/
+
+Trace MSR reads
+
+read_msr
+
+msr: MSR number
+val: Value written
+failed: 1 if the access failed, otherwise 0
+
+
+Trace MSR writes
+
+write_msr
+
+msr: MSR number
+val: Value written
+failed: 1 if the access failed, otherwise 0
+
+
+Trace RDPMC in kernel
+
+rdpmc
+
+The trace data can be post processed with the postprocess/decode_msr.py script
+
+cat /sys/kernel/debug/tracing/trace | decode_msr.py /usr/src/linux/include/asm/msr-index.h
+
+to add symbolic MSR names.
+
diff --git a/Documentation/trace/postprocess/decode_msr.py b/Documentation/trace/postprocess/decode_msr.py
new file mode 100644
index 0000000..0ab40e0
--- /dev/null
+++ b/Documentation/trace/postprocess/decode_msr.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+# add symbolic names to read_msr / write_msr in trace
+# decode_msr msr-index.h < trace
+import sys
+import re
+
+msrs = dict()
+
+with open(sys.argv[1] if len(sys.argv) > 1 else "msr-index.h", "r") as f:
+	for j in f:
+		m = re.match(r'#define (MSR_\w+)\s+(0x[0-9a-fA-F]+)', j)
+		if m:
+			msrs[int(m.group(2), 16)] = m.group(1)
+
+extra_ranges = (
+	( "MSR_LASTBRANCH_%d_FROM_IP", 0x680, 0x69F ),
+	( "MSR_LASTBRANCH_%d_TO_IP", 0x6C0, 0x6DF ),
+	( "LBR_INFO_%d", 0xdc0, 0xddf ),
+)
+
+for j in sys.stdin:
+	m = re.search(r'(read|write)_msr:\s+([0-9a-f]+)', j)
+	if m:
+		r = None
+		num = int(m.group(2), 16)
+		if num in msrs:
+			r = msrs[num]
+		else:
+			for er in extra_ranges:
+				if er[1] <= num <= er[2]:
+					r = er[0] % (num - er[1],)
+					break
+		if r:
+			j = j.replace(" " + m.group(2), " " + r + "(" + m.group(2) + ")")
+	print j,
+
+
diff --git a/arch/x86/include/asm/msr-trace.h b/arch/x86/include/asm/msr-trace.h
new file mode 100644
index 0000000..7567225
--- /dev/null
+++ b/arch/x86/include/asm/msr-trace.h
@@ -0,0 +1,57 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM msr
+
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE msr-trace
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH asm/
+
+#if !defined(_TRACE_MSR_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_MSR_H
+
+#include <linux/tracepoint.h>
+
+/*
+ * Tracing for x86 model specific registers. Directly maps to the
+ * RDMSR/WRMSR instructions.
+ */
+
+DECLARE_EVENT_CLASS(msr_trace_class,
+	    TP_PROTO(unsigned msr, u64 val, int failed),
+	    TP_ARGS(msr, val, failed),
+	    TP_STRUCT__entry(
+		    __field(	unsigned,	msr )
+		    __field(    u64,		val )
+		    __field(    int,		failed )
+	    ),
+	    TP_fast_assign(
+		    __entry->msr = msr;
+		    __entry->val = val;
+		    __entry->failed = failed;
+	    ),
+	    TP_printk("%x, value %llx%s",
+		      __entry->msr,
+		      __entry->val,
+		      __entry->failed ? " #GP" : "")
+);
+
+DEFINE_EVENT(msr_trace_class, read_msr,
+	     TP_PROTO(unsigned msr, u64 val, int failed),
+	     TP_ARGS(msr, val, failed)
+);
+
+DEFINE_EVENT(msr_trace_class, write_msr,
+	     TP_PROTO(unsigned msr, u64 val, int failed),
+	     TP_ARGS(msr, val, failed)
+);
+
+DEFINE_EVENT(msr_trace_class, rdpmc,
+	     TP_PROTO(unsigned msr, u64 val, int failed),
+	     TP_ARGS(msr, val, failed)
+);
+
+#endif /* _TRACE_MSR_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 77d8b28..fedd6e6 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -57,11 +57,34 @@ static inline unsigned long long native_read_tscp(unsigned int *aux)
 #define EAX_EDX_RET(val, low, high)	"=A" (val)
 #endif
 
+#ifdef CONFIG_TRACEPOINTS
+/*
+ * Be very careful with includes. This header is prone to include loops.
+ */
+#include <asm/atomic.h>
+#include <linux/tracepoint-defs.h>
+
+extern struct tracepoint __tracepoint_read_msr;
+extern struct tracepoint __tracepoint_write_msr;
+extern struct tracepoint __tracepoint_rdpmc;
+#define msr_tracepoint_active(t) static_key_false(&(t).key)
+extern void do_trace_write_msr(unsigned msr, u64 val, int failed);
+extern void do_trace_read_msr(unsigned msr, u64 val, int failed);
+extern void do_trace_rdpmc(unsigned msr, u64 val, int failed);
+#else
+#define msr_tracepoint_active(t) false
+static inline void do_trace_write_msr(unsigned msr, u64 val, int failed) {}
+static inline void do_trace_read_msr(unsigned msr, u64 val, int failed) {}
+static inline void do_trace_rdpmc(unsigned msr, u64 val, int failed) {}
+#endif
+
 static inline unsigned long long native_read_msr(unsigned int msr)
 {
 	DECLARE_ARGS(val, low, high);
 
 	asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr));
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), 0);
 	return EAX_EDX_VAL(val, low, high);
 }
 
@@ -78,6 +101,8 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
 		     _ASM_EXTABLE(2b, 3b)
 		     : [err] "=r" (*err), EAX_EDX_RET(val, low, high)
 		     : "c" (msr), [fault] "i" (-EIO));
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), *err);
 	return EAX_EDX_VAL(val, low, high);
 }
 
@@ -85,6 +110,8 @@ static inline void native_write_msr(unsigned int msr,
 				    unsigned low, unsigned high)
 {
 	asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_write_msr(msr, ((u64)high << 32 | low), 0);
 }
 
 /* Can be uninlined because referenced by paravirt */
@@ -102,6 +129,8 @@ notrace static inline int native_write_msr_safe(unsigned int msr,
 		     : "c" (msr), "0" (low), "d" (high),
 		       [fault] "i" (-EIO)
 		     : "memory");
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_write_msr(msr, ((u64)high << 32 | low), err);
 	return err;
 }
 
@@ -160,6 +189,8 @@ static inline unsigned long long native_read_pmc(int counter)
 	DECLARE_ARGS(val, low, high);
 
 	asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
+	if (msr_tracepoint_active(__tracepoint_rdpmc))
+		do_trace_rdpmc(counter, EAX_EDX_VAL(val, low, high), 0);
 	return EAX_EDX_VAL(val, low, high);
 }
 
diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c
index 4362373..004c861 100644
--- a/arch/x86/lib/msr.c
+++ b/arch/x86/lib/msr.c
@@ -1,6 +1,8 @@
 #include <linux/module.h>
 #include <linux/preempt.h>
 #include <asm/msr.h>
+#define CREATE_TRACE_POINTS
+#include <asm/msr-trace.h>
 
 struct msr *msrs_alloc(void)
 {
@@ -108,3 +110,27 @@ int msr_clear_bit(u32 msr, u8 bit)
 {
 	return __flip_bit(msr, bit, false);
 }
+
+#ifdef CONFIG_TRACEPOINTS
+void do_trace_write_msr(unsigned msr, u64 val, int failed)
+{
+	trace_write_msr(msr, val, failed);
+}
+EXPORT_SYMBOL(do_trace_write_msr);
+EXPORT_TRACEPOINT_SYMBOL(write_msr);
+
+void do_trace_read_msr(unsigned msr, u64 val, int failed)
+{
+	trace_read_msr(msr, val, failed);
+}
+EXPORT_SYMBOL(do_trace_read_msr);
+EXPORT_TRACEPOINT_SYMBOL(read_msr);
+
+void do_trace_rdpmc(unsigned counter, u64 val, int failed)
+{
+	trace_rdpmc(counter, val, failed);
+}
+EXPORT_SYMBOL(do_trace_rdpmc);
+EXPORT_TRACEPOINT_SYMBOL(rdpmc);
+
+#endif

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

* [tip:perf/core] perf/x86: Remove old MSR perf tracing code
  2015-12-02  1:01 ` [PATCH 4/4] perf, x86: Remove old MSR perf tracing code Andi Kleen
@ 2015-12-04 12:00   ` tip-bot for Andi Kleen
  2015-12-06 13:19   ` tip-bot for Andi Kleen
  1 sibling, 0 replies; 25+ messages in thread
From: tip-bot for Andi Kleen @ 2015-12-04 12:00 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, torvalds, vincent.weaver, eranian, efault, ak,
	mingo, tglx, peterz, hpa, jolsa, acme

Commit-ID:  23147ce9aca551931f8f17bb520b370df884f918
Gitweb:     http://git.kernel.org/tip/23147ce9aca551931f8f17bb520b370df884f918
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Tue, 1 Dec 2015 17:01:00 -0800
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 4 Dec 2015 10:58:35 +0100

perf/x86: Remove old MSR perf tracing code

Now that we have generic MSR trace points we can remove the old
hackish perf MSR read tracing code.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: rostedt@goodmis.org
Link: http://lkml.kernel.org/r/1449018060-1742-4-git-send-email-andi@firstfloor.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/cpu/perf_event.h | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 910928f..ce8768f 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -14,17 +14,7 @@
 
 #include <linux/perf_event.h>
 
-#if 0
-#undef wrmsrl
-#define wrmsrl(msr, val) 						\
-do {									\
-	unsigned int _msr = (msr);					\
-	u64 _val = (val);						\
-	trace_printk("wrmsrl(%x, %Lx)\n", (unsigned int)(_msr),		\
-			(unsigned long long)(_val));			\
-	native_write_msr((_msr), (u32)(_val), (u32)(_val >> 32));	\
-} while (0)
-#endif
+/* To enable MSR tracing please use the generic trace points. */
 
 /*
  *          |   NHM/WSM    |      SNB     |

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

* Re: [tip:perf/core] x86, tracing, perf: Add trace point for MSR accesses
  2015-12-04 11:59   ` [tip:perf/core] x86, tracing, perf: " tip-bot for Andi Kleen
@ 2015-12-04 12:11     ` Borislav Petkov
  2015-12-04 18:28       ` Andi Kleen
  0 siblings, 1 reply; 25+ messages in thread
From: Borislav Petkov @ 2015-12-04 12:11 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-tip-commits, vincent.weaver, eranian, hpa, efault, peterz,
	jolsa, torvalds, tglx, ak, rostedt, acme, mingo, linux-kernel

On Fri, Dec 04, 2015 at 03:59:42AM -0800, tip-bot for Andi Kleen wrote:
> Commit-ID:  07b41f5cf37b34ef3de4f40fbaf8547abe690abb
> Gitweb:     http://git.kernel.org/tip/07b41f5cf37b34ef3de4f40fbaf8547abe690abb
> Author:     Andi Kleen <ak@linux.intel.com>
> AuthorDate: Tue, 1 Dec 2015 17:00:59 -0800
> Committer:  Ingo Molnar <mingo@kernel.org>
> CommitDate: Fri, 4 Dec 2015 10:58:34 +0100
> 
> x86, tracing, perf: Add trace point for MSR accesses
> 
> For debugging low level code interacting with the CPU it is often
> useful to trace the MSR read/writes. This gives a concise summary of
> PMU and other operations.
> 
> perf has an ad-hoc way to do this using trace_printk, but it's
> somewhat limited (and also now spews ugly boot messages when enabled)
> 
> Instead define real trace points for all MSR accesses.
> 
> This adds three new trace points: read_msr and write_msr and rdpmc.
> 
> They also report if the access faulted (if *_safe is used)
> 
> This allows filtering and triggering on specific MSR values, which
> allows various more advanced debugging techniques.
> 
> All the values are well defined in the CPU documentation.
> 
> The trace can be post processed with
> Documentation/trace/postprocess/decode_msr.py to add symbolic MSR
> names to the trace.
> 
> I only added it to native MSR accesses in C, not paravirtualized or in
> entry*.S (which is not too interesting)
> 
> Originally the patch kit moved the MSRs out of line.  This uses an
> alternative approach recommended by Steven Rostedt of only moving the
> trace calls out of line, but open coding the access to the jump label.
> 
> Signed-off-by: Andi Kleen <ak@linux.intel.com>
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> Acked-by: Steven Rostedt <rostedt@goodmis.org>
> Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
> Cc: Jiri Olsa <jolsa@redhat.com>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Cc: Mike Galbraith <efault@gmx.de>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Stephane Eranian <eranian@google.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Vince Weaver <vincent.weaver@maine.edu>
> Link: http://lkml.kernel.org/r/1449018060-1742-3-git-send-email-andi@firstfloor.org
> Signed-off-by: Ingo Molnar <mingo@kernel.org>
> ---

...

> diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c
> index 4362373..004c861 100644
> --- a/arch/x86/lib/msr.c
> +++ b/arch/x86/lib/msr.c
> @@ -1,6 +1,8 @@
>  #include <linux/module.h>
>  #include <linux/preempt.h>
>  #include <asm/msr.h>
> +#define CREATE_TRACE_POINTS
> +#include <asm/msr-trace.h>
>  
>  struct msr *msrs_alloc(void)
>  {
> @@ -108,3 +110,27 @@ int msr_clear_bit(u32 msr, u8 bit)
>  {
>  	return __flip_bit(msr, bit, false);
>  }
> +
> +#ifdef CONFIG_TRACEPOINTS
> +void do_trace_write_msr(unsigned msr, u64 val, int failed)
> +{
> +	trace_write_msr(msr, val, failed);
> +}
> +EXPORT_SYMBOL(do_trace_write_msr);
> +EXPORT_TRACEPOINT_SYMBOL(write_msr);
> +
> +void do_trace_read_msr(unsigned msr, u64 val, int failed)
> +{
> +	trace_read_msr(msr, val, failed);
> +}
> +EXPORT_SYMBOL(do_trace_read_msr);
> +EXPORT_TRACEPOINT_SYMBOL(read_msr);
> +
> +void do_trace_rdpmc(unsigned counter, u64 val, int failed)
> +{
> +	trace_rdpmc(counter, val, failed);
> +}
> +EXPORT_SYMBOL(do_trace_rdpmc);
> +EXPORT_TRACEPOINT_SYMBOL(rdpmc);

Any particular reason why those are EXPORT_SYMBOL and not
EXPORT_SYMBOL_GPL?

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.

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

* Re: [tip:perf/core] x86, tracing, perf: Add trace point for MSR accesses
  2015-12-04 12:11     ` Borislav Petkov
@ 2015-12-04 18:28       ` Andi Kleen
  2015-12-04 18:30         ` Borislav Petkov
  0 siblings, 1 reply; 25+ messages in thread
From: Andi Kleen @ 2015-12-04 18:28 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Ingo Molnar, linux-tip-commits, vincent.weaver, eranian, hpa,
	efault, peterz, jolsa, torvalds, tglx, rostedt, acme,
	linux-kernel

> Any particular reason why those are EXPORT_SYMBOL and not
> EXPORT_SYMBOL_GPL?

Because making them GPL would prevent any non GPL driver from
using MSRs with tracing compiled in, which doesn't make any sense.

-Andi

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

* Re: [tip:perf/core] x86, tracing, perf: Add trace point for MSR accesses
  2015-12-04 18:28       ` Andi Kleen
@ 2015-12-04 18:30         ` Borislav Petkov
  2015-12-04 22:18           ` Andi Kleen
  2015-12-04 22:35           ` H. Peter Anvin
  0 siblings, 2 replies; 25+ messages in thread
From: Borislav Petkov @ 2015-12-04 18:30 UTC (permalink / raw)
  To: Andi Kleen
  Cc: Ingo Molnar, linux-tip-commits, vincent.weaver, eranian, hpa,
	efault, peterz, jolsa, torvalds, tglx, rostedt, acme,
	linux-kernel

On Fri, Dec 04, 2015 at 10:28:02AM -0800, Andi Kleen wrote:
> Because making them GPL would prevent any non GPL driver from
> using MSRs with tracing compiled in, which doesn't make any sense.

I know what EXPORT_SYMBOL_GPL means - I'm questioning the need of making
them available to non-GPL drivers.

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.

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

* Re: [tip:perf/core] x86, tracing, perf: Add trace point for MSR accesses
  2015-12-04 18:30         ` Borislav Petkov
@ 2015-12-04 22:18           ` Andi Kleen
  2015-12-04 22:27             ` Borislav Petkov
  2015-12-04 22:35           ` H. Peter Anvin
  1 sibling, 1 reply; 25+ messages in thread
From: Andi Kleen @ 2015-12-04 22:18 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Ingo Molnar, linux-tip-commits, vincent.weaver, eranian, hpa,
	efault, peterz, jolsa, torvalds, tglx, rostedt, acme,
	linux-kernel

On Fri, Dec 04, 2015 at 07:30:17PM +0100, Borislav Petkov wrote:
> On Fri, Dec 04, 2015 at 10:28:02AM -0800, Andi Kleen wrote:
> > Because making them GPL would prevent any non GPL driver from
> > using MSRs with tracing compiled in, which doesn't make any sense.
> 
> I know what EXPORT_SYMBOL_GPL means - I'm questioning the need of making
> them available to non-GPL drivers.

MSRs are not a GPLed facility.

-Andi

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

* Re: [tip:perf/core] x86, tracing, perf: Add trace point for MSR accesses
  2015-12-04 22:18           ` Andi Kleen
@ 2015-12-04 22:27             ` Borislav Petkov
  0 siblings, 0 replies; 25+ messages in thread
From: Borislav Petkov @ 2015-12-04 22:27 UTC (permalink / raw)
  To: Andi Kleen
  Cc: Ingo Molnar, linux-tip-commits, vincent.weaver, eranian, hpa,
	efault, peterz, jolsa, torvalds, tglx, rostedt, acme,
	linux-kernel

On Fri, Dec 04, 2015 at 02:18:56PM -0800, Andi Kleen wrote:
> On Fri, Dec 04, 2015 at 07:30:17PM +0100, Borislav Petkov wrote:
> > On Fri, Dec 04, 2015 at 10:28:02AM -0800, Andi Kleen wrote:
> > > Because making them GPL would prevent any non GPL driver from
> > > using MSRs with tracing compiled in, which doesn't make any sense.
> > 
> > I know what EXPORT_SYMBOL_GPL means - I'm questioning the need of making
> > them available to non-GPL drivers.
> 
> MSRs are not a GPLed facility.

Let me think of a similarly unrelated comeback: the sky is sometimes blue.

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.

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

* Re: [tip:perf/core] x86, tracing, perf: Add trace point for MSR accesses
  2015-12-04 18:30         ` Borislav Petkov
  2015-12-04 22:18           ` Andi Kleen
@ 2015-12-04 22:35           ` H. Peter Anvin
  2015-12-04 22:48             ` Borislav Petkov
  1 sibling, 1 reply; 25+ messages in thread
From: H. Peter Anvin @ 2015-12-04 22:35 UTC (permalink / raw)
  To: Borislav Petkov, Andi Kleen
  Cc: Ingo Molnar, linux-tip-commits, vincent.weaver, eranian, efault,
	peterz, jolsa, torvalds, tglx, rostedt, acme, linux-kernel

On December 4, 2015 10:30:17 AM PST, Borislav Petkov <bp@alien8.de> wrote:
>On Fri, Dec 04, 2015 at 10:28:02AM -0800, Andi Kleen wrote:
>> Because making them GPL would prevent any non GPL driver from
>> using MSRs with tracing compiled in, which doesn't make any sense.
>
>I know what EXPORT_SYMBOL_GPL means - I'm questioning the need of
>making
>them available to non-GPL drivers.

How about this: it is easy too easy to hard code MSR accesses, and the last things we need is alien non-GPL drivers doing their own low-level hacks bypassing these facilities.
-- 
Sent from my Android device with K-9 Mail. Please excuse brevity and formatting.

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

* Re: [tip:perf/core] x86, tracing, perf: Add trace point for MSR accesses
  2015-12-04 22:35           ` H. Peter Anvin
@ 2015-12-04 22:48             ` Borislav Petkov
  2015-12-04 22:57               ` H. Peter Anvin
  0 siblings, 1 reply; 25+ messages in thread
From: Borislav Petkov @ 2015-12-04 22:48 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Andi Kleen, Ingo Molnar, linux-tip-commits, vincent.weaver,
	eranian, efault, peterz, jolsa, torvalds, tglx, rostedt, acme,
	linux-kernel

On Fri, Dec 04, 2015 at 02:35:38PM -0800, H. Peter Anvin wrote:
> How about this: it is easy too easy to hard code MSR accesses, and the
> last things we need is alien non-GPL drivers doing their own low-level
> hacks bypassing these facilities.

Yeah, that doesn't stop alien, non-GPL drivers from doing

	asm("rdmsr ..)

Hell, they can even do naked byte opcodes " ...0f 32... "

But I see your point, thanks!

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.

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

* Re: [tip:perf/core] x86, tracing, perf: Add trace point for MSR accesses
  2015-12-04 22:48             ` Borislav Petkov
@ 2015-12-04 22:57               ` H. Peter Anvin
  0 siblings, 0 replies; 25+ messages in thread
From: H. Peter Anvin @ 2015-12-04 22:57 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Andi Kleen, Ingo Molnar, linux-tip-commits, vincent.weaver,
	eranian, efault, peterz, jolsa, torvalds, tglx, rostedt, acme,
	linux-kernel

On December 4, 2015 2:48:37 PM PST, Borislav Petkov <bp@alien8.de> wrote:
>On Fri, Dec 04, 2015 at 02:35:38PM -0800, H. Peter Anvin wrote:
>> How about this: it is easy too easy to hard code MSR accesses, and
>the
>> last things we need is alien non-GPL drivers doing their own
>low-level
>> hacks bypassing these facilities.
>
>Yeah, that doesn't stop alien, non-GPL drivers from doing
>
>	asm("rdmsr ..)
>
>Hell, they can even do naked byte opcodes " ...0f 32... "
>
>But I see your point, thanks!

Yes, we can't keep them from being stupid, and they clearly are being so in the first place, but we can at least make it a bit easier to not be.  Since it is so easy to do that dumb thing let's not make it harder.
-- 
Sent from my Android device with K-9 Mail. Please excuse brevity and formatting.

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

* [tip:perf/core] x86/headers: Don't include asm/processor.h in asm /atomic.h
  2015-12-02  1:00 [PATCH 1/4] x86: Don't include asm/processor.h into asm/atomic.h Andi Kleen
                   ` (3 preceding siblings ...)
  2015-12-04 11:58 ` [tip:perf/core] x86/headers: Don't include asm/processor.h in asm /atomic.h tip-bot for Andi Kleen
@ 2015-12-06 13:18 ` tip-bot for Andi Kleen
  4 siblings, 0 replies; 25+ messages in thread
From: tip-bot for Andi Kleen @ 2015-12-06 13:18 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, efault, tglx, torvalds, peterz, acme, vincent.weaver, jolsa,
	eranian, mingo, linux-kernel, ak

Commit-ID:  153a4334c439cfb62e1d31cee0c790ba4157813d
Gitweb:     http://git.kernel.org/tip/153a4334c439cfb62e1d31cee0c790ba4157813d
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Tue, 1 Dec 2015 17:00:57 -0800
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sun, 6 Dec 2015 12:56:03 +0100

x86/headers: Don't include asm/processor.h in asm/atomic.h

asm/atomic.h doesn't really need asm/processor.h anymore. Everything
it uses has moved to other header files. So remove that include.

processor.h is a nasty header that includes lots of
other headers and makes it prone to include loops. Removing the
include here makes asm/atomic.h a "leaf" header that can
be safely included in most other headers.

The only fallout is in the lib/atomic tester which relied on
this implicit include. Give it an explicit include.
(the include is in ifdef because the user is also in ifdef)

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: rostedt@goodmis.org
Link: http://lkml.kernel.org/r/1449018060-1742-1-git-send-email-andi@firstfloor.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/atomic.h      | 1 -
 arch/x86/include/asm/atomic64_32.h | 1 -
 lib/atomic64_test.c                | 4 ++++
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h
index ae5fb83..3e86742 100644
--- a/arch/x86/include/asm/atomic.h
+++ b/arch/x86/include/asm/atomic.h
@@ -3,7 +3,6 @@
 
 #include <linux/compiler.h>
 #include <linux/types.h>
-#include <asm/processor.h>
 #include <asm/alternative.h>
 #include <asm/cmpxchg.h>
 #include <asm/rmwcc.h>
diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h
index a11c30b..a984111 100644
--- a/arch/x86/include/asm/atomic64_32.h
+++ b/arch/x86/include/asm/atomic64_32.h
@@ -3,7 +3,6 @@
 
 #include <linux/compiler.h>
 #include <linux/types.h>
-#include <asm/processor.h>
 //#include <asm/cmpxchg.h>
 
 /* An 64bit atomic type */
diff --git a/lib/atomic64_test.c b/lib/atomic64_test.c
index 83c33a5b..d51e25a 100644
--- a/lib/atomic64_test.c
+++ b/lib/atomic64_test.c
@@ -16,6 +16,10 @@
 #include <linux/kernel.h>
 #include <linux/atomic.h>
 
+#ifdef CONFIG_X86
+#include <asm/processor.h>	/* for boot_cpu_has below */
+#endif
+
 #define TEST(bit, op, c_op, val)				\
 do {								\
 	atomic##bit##_set(&v, v0);				\

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

* [tip:perf/core] tracepoints: Move struct tracepoint to new tracepoint-defs.h header
  2015-12-02  1:00 ` [PATCH 2/4] tracepoints: Move struct tracepoint to new tracepoint-defs.h header Andi Kleen
  2015-12-02  1:56   ` Steven Rostedt
  2015-12-04 11:59   ` [tip:perf/core] " tip-bot for Andi Kleen
@ 2015-12-06 13:18   ` tip-bot for Andi Kleen
  2 siblings, 0 replies; 25+ messages in thread
From: tip-bot for Andi Kleen @ 2015-12-06 13:18 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, eranian, linux-kernel, vincent.weaver, peterz, mingo, acme,
	ak, tglx, efault, rostedt, jolsa, torvalds

Commit-ID:  bd2a634d9e852b9b6100f9ae9c3c790b0ff91ce0
Gitweb:     http://git.kernel.org/tip/bd2a634d9e852b9b6100f9ae9c3c790b0ff91ce0
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Tue, 1 Dec 2015 17:00:58 -0800
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sun, 6 Dec 2015 12:56:06 +0100

tracepoints: Move struct tracepoint to new tracepoint-defs.h header

Steven recommended open coding access to tracepoint->key to add
trace points to headers. Unfortunately this is difficult for some
headers (such as x86 asm/msr.h) because including tracepoint.h
includes so many other headers that it causes include loops.
The main problem is the include of linux/rcupdate.h, which
pulls in a lot of other headers. The rcu header is only needed
when actually defining trace points.

Move the struct tracepoint into a separate tracepoint-defs.h
header that can be included without pulling in all of RCU.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Link: http://lkml.kernel.org/r/1449018060-1742-2-git-send-email-andi@firstfloor.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/linux/tracepoint-defs.h | 27 +++++++++++++++++++++++++++
 include/linux/tracepoint.h      | 16 +---------------
 2 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/include/linux/tracepoint-defs.h b/include/linux/tracepoint-defs.h
new file mode 100644
index 0000000..e1ee97c
--- /dev/null
+++ b/include/linux/tracepoint-defs.h
@@ -0,0 +1,27 @@
+#ifndef TRACEPOINT_DEFS_H
+#define TRACEPOINT_DEFS_H 1
+
+/*
+ * File can be included directly by headers who only want to access
+ * tracepoint->key to guard out of line trace calls. Otherwise
+ * linux/tracepoint.h should be used.
+ */
+
+#include <linux/atomic.h>
+#include <linux/static_key.h>
+
+struct tracepoint_func {
+	void *func;
+	void *data;
+	int prio;
+};
+
+struct tracepoint {
+	const char *name;		/* Tracepoint name */
+	struct static_key key;
+	void (*regfunc)(void);
+	void (*unregfunc)(void);
+	struct tracepoint_func __rcu *funcs;
+};
+
+#endif
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 696a339c..f7c732b 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -17,26 +17,12 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/rcupdate.h>
-#include <linux/static_key.h>
+#include <linux/tracepoint-defs.h>
 
 struct module;
 struct tracepoint;
 struct notifier_block;
 
-struct tracepoint_func {
-	void *func;
-	void *data;
-	int prio;
-};
-
-struct tracepoint {
-	const char *name;		/* Tracepoint name */
-	struct static_key key;
-	void (*regfunc)(void);
-	void (*unregfunc)(void);
-	struct tracepoint_func __rcu *funcs;
-};
-
 struct trace_enum_map {
 	const char		*system;
 	const char		*enum_string;

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

* [tip:perf/core] x86, tracing, perf: Add trace point for MSR accesses
  2015-12-02  1:00 ` [PATCH 3/4] x86: Add trace point for MSR accesses Andi Kleen
  2015-12-02  2:03   ` Steven Rostedt
  2015-12-04 11:59   ` [tip:perf/core] x86, tracing, perf: " tip-bot for Andi Kleen
@ 2015-12-06 13:19   ` tip-bot for Andi Kleen
  2 siblings, 0 replies; 25+ messages in thread
From: tip-bot for Andi Kleen @ 2015-12-06 13:19 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: efault, mingo, peterz, jolsa, rostedt, linux-kernel, ak, hpa,
	acme, torvalds, tglx, vincent.weaver, eranian

Commit-ID:  7f47d8cc039f8746e0038fe05f1ddcb15a2e27f0
Gitweb:     http://git.kernel.org/tip/7f47d8cc039f8746e0038fe05f1ddcb15a2e27f0
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Tue, 1 Dec 2015 17:00:59 -0800
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sun, 6 Dec 2015 12:56:10 +0100

x86, tracing, perf: Add trace point for MSR accesses

For debugging low level code interacting with the CPU it is often
useful to trace the MSR read/writes. This gives a concise summary of
PMU and other operations.

perf has an ad-hoc way to do this using trace_printk, but it's
somewhat limited (and also now spews ugly boot messages when enabled)

Instead define real trace points for all MSR accesses.

This adds three new trace points: read_msr and write_msr and rdpmc.

They also report if the access faulted (if *_safe is used)

This allows filtering and triggering on specific MSR values, which
allows various more advanced debugging techniques.

All the values are well defined in the CPU documentation.

The trace can be post processed with
Documentation/trace/postprocess/decode_msr.py to add symbolic MSR
names to the trace.

I only added it to native MSR accesses in C, not paravirtualized or in
entry*.S (which is not too interesting)

Originally the patch kit moved the MSRs out of line.  This uses an
alternative approach recommended by Steven Rostedt of only moving the
trace calls out of line, but open coding the access to the jump label.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Link: http://lkml.kernel.org/r/1449018060-1742-3-git-send-email-andi@firstfloor.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 Documentation/trace/events-msr.txt            | 37 +++++++++++++++++
 Documentation/trace/postprocess/decode_msr.py | 37 +++++++++++++++++
 arch/x86/include/asm/msr-trace.h              | 57 +++++++++++++++++++++++++++
 arch/x86/include/asm/msr.h                    | 31 +++++++++++++++
 arch/x86/lib/msr.c                            | 26 ++++++++++++
 5 files changed, 188 insertions(+)

diff --git a/Documentation/trace/events-msr.txt b/Documentation/trace/events-msr.txt
new file mode 100644
index 0000000..78c383b
--- /dev/null
+++ b/Documentation/trace/events-msr.txt
@@ -0,0 +1,37 @@
+
+The x86 kernel supports tracing most MSR (Model Specific Register) accesses.
+To see the definition of the MSRs on Intel systems please see the SDM
+at http://www.intel.com/sdm (Volume 3)
+
+Available trace points:
+
+/sys/kernel/debug/tracing/events/msr/
+
+Trace MSR reads
+
+read_msr
+
+msr: MSR number
+val: Value written
+failed: 1 if the access failed, otherwise 0
+
+
+Trace MSR writes
+
+write_msr
+
+msr: MSR number
+val: Value written
+failed: 1 if the access failed, otherwise 0
+
+
+Trace RDPMC in kernel
+
+rdpmc
+
+The trace data can be post processed with the postprocess/decode_msr.py script
+
+cat /sys/kernel/debug/tracing/trace | decode_msr.py /usr/src/linux/include/asm/msr-index.h
+
+to add symbolic MSR names.
+
diff --git a/Documentation/trace/postprocess/decode_msr.py b/Documentation/trace/postprocess/decode_msr.py
new file mode 100644
index 0000000..0ab40e0
--- /dev/null
+++ b/Documentation/trace/postprocess/decode_msr.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+# add symbolic names to read_msr / write_msr in trace
+# decode_msr msr-index.h < trace
+import sys
+import re
+
+msrs = dict()
+
+with open(sys.argv[1] if len(sys.argv) > 1 else "msr-index.h", "r") as f:
+	for j in f:
+		m = re.match(r'#define (MSR_\w+)\s+(0x[0-9a-fA-F]+)', j)
+		if m:
+			msrs[int(m.group(2), 16)] = m.group(1)
+
+extra_ranges = (
+	( "MSR_LASTBRANCH_%d_FROM_IP", 0x680, 0x69F ),
+	( "MSR_LASTBRANCH_%d_TO_IP", 0x6C0, 0x6DF ),
+	( "LBR_INFO_%d", 0xdc0, 0xddf ),
+)
+
+for j in sys.stdin:
+	m = re.search(r'(read|write)_msr:\s+([0-9a-f]+)', j)
+	if m:
+		r = None
+		num = int(m.group(2), 16)
+		if num in msrs:
+			r = msrs[num]
+		else:
+			for er in extra_ranges:
+				if er[1] <= num <= er[2]:
+					r = er[0] % (num - er[1],)
+					break
+		if r:
+			j = j.replace(" " + m.group(2), " " + r + "(" + m.group(2) + ")")
+	print j,
+
+
diff --git a/arch/x86/include/asm/msr-trace.h b/arch/x86/include/asm/msr-trace.h
new file mode 100644
index 0000000..7567225
--- /dev/null
+++ b/arch/x86/include/asm/msr-trace.h
@@ -0,0 +1,57 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM msr
+
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE msr-trace
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH asm/
+
+#if !defined(_TRACE_MSR_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_MSR_H
+
+#include <linux/tracepoint.h>
+
+/*
+ * Tracing for x86 model specific registers. Directly maps to the
+ * RDMSR/WRMSR instructions.
+ */
+
+DECLARE_EVENT_CLASS(msr_trace_class,
+	    TP_PROTO(unsigned msr, u64 val, int failed),
+	    TP_ARGS(msr, val, failed),
+	    TP_STRUCT__entry(
+		    __field(	unsigned,	msr )
+		    __field(    u64,		val )
+		    __field(    int,		failed )
+	    ),
+	    TP_fast_assign(
+		    __entry->msr = msr;
+		    __entry->val = val;
+		    __entry->failed = failed;
+	    ),
+	    TP_printk("%x, value %llx%s",
+		      __entry->msr,
+		      __entry->val,
+		      __entry->failed ? " #GP" : "")
+);
+
+DEFINE_EVENT(msr_trace_class, read_msr,
+	     TP_PROTO(unsigned msr, u64 val, int failed),
+	     TP_ARGS(msr, val, failed)
+);
+
+DEFINE_EVENT(msr_trace_class, write_msr,
+	     TP_PROTO(unsigned msr, u64 val, int failed),
+	     TP_ARGS(msr, val, failed)
+);
+
+DEFINE_EVENT(msr_trace_class, rdpmc,
+	     TP_PROTO(unsigned msr, u64 val, int failed),
+	     TP_ARGS(msr, val, failed)
+);
+
+#endif /* _TRACE_MSR_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 77d8b28..fedd6e6 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -57,11 +57,34 @@ static inline unsigned long long native_read_tscp(unsigned int *aux)
 #define EAX_EDX_RET(val, low, high)	"=A" (val)
 #endif
 
+#ifdef CONFIG_TRACEPOINTS
+/*
+ * Be very careful with includes. This header is prone to include loops.
+ */
+#include <asm/atomic.h>
+#include <linux/tracepoint-defs.h>
+
+extern struct tracepoint __tracepoint_read_msr;
+extern struct tracepoint __tracepoint_write_msr;
+extern struct tracepoint __tracepoint_rdpmc;
+#define msr_tracepoint_active(t) static_key_false(&(t).key)
+extern void do_trace_write_msr(unsigned msr, u64 val, int failed);
+extern void do_trace_read_msr(unsigned msr, u64 val, int failed);
+extern void do_trace_rdpmc(unsigned msr, u64 val, int failed);
+#else
+#define msr_tracepoint_active(t) false
+static inline void do_trace_write_msr(unsigned msr, u64 val, int failed) {}
+static inline void do_trace_read_msr(unsigned msr, u64 val, int failed) {}
+static inline void do_trace_rdpmc(unsigned msr, u64 val, int failed) {}
+#endif
+
 static inline unsigned long long native_read_msr(unsigned int msr)
 {
 	DECLARE_ARGS(val, low, high);
 
 	asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr));
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), 0);
 	return EAX_EDX_VAL(val, low, high);
 }
 
@@ -78,6 +101,8 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
 		     _ASM_EXTABLE(2b, 3b)
 		     : [err] "=r" (*err), EAX_EDX_RET(val, low, high)
 		     : "c" (msr), [fault] "i" (-EIO));
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), *err);
 	return EAX_EDX_VAL(val, low, high);
 }
 
@@ -85,6 +110,8 @@ static inline void native_write_msr(unsigned int msr,
 				    unsigned low, unsigned high)
 {
 	asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_write_msr(msr, ((u64)high << 32 | low), 0);
 }
 
 /* Can be uninlined because referenced by paravirt */
@@ -102,6 +129,8 @@ notrace static inline int native_write_msr_safe(unsigned int msr,
 		     : "c" (msr), "0" (low), "d" (high),
 		       [fault] "i" (-EIO)
 		     : "memory");
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_write_msr(msr, ((u64)high << 32 | low), err);
 	return err;
 }
 
@@ -160,6 +189,8 @@ static inline unsigned long long native_read_pmc(int counter)
 	DECLARE_ARGS(val, low, high);
 
 	asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
+	if (msr_tracepoint_active(__tracepoint_rdpmc))
+		do_trace_rdpmc(counter, EAX_EDX_VAL(val, low, high), 0);
 	return EAX_EDX_VAL(val, low, high);
 }
 
diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c
index 4362373..004c861 100644
--- a/arch/x86/lib/msr.c
+++ b/arch/x86/lib/msr.c
@@ -1,6 +1,8 @@
 #include <linux/module.h>
 #include <linux/preempt.h>
 #include <asm/msr.h>
+#define CREATE_TRACE_POINTS
+#include <asm/msr-trace.h>
 
 struct msr *msrs_alloc(void)
 {
@@ -108,3 +110,27 @@ int msr_clear_bit(u32 msr, u8 bit)
 {
 	return __flip_bit(msr, bit, false);
 }
+
+#ifdef CONFIG_TRACEPOINTS
+void do_trace_write_msr(unsigned msr, u64 val, int failed)
+{
+	trace_write_msr(msr, val, failed);
+}
+EXPORT_SYMBOL(do_trace_write_msr);
+EXPORT_TRACEPOINT_SYMBOL(write_msr);
+
+void do_trace_read_msr(unsigned msr, u64 val, int failed)
+{
+	trace_read_msr(msr, val, failed);
+}
+EXPORT_SYMBOL(do_trace_read_msr);
+EXPORT_TRACEPOINT_SYMBOL(read_msr);
+
+void do_trace_rdpmc(unsigned counter, u64 val, int failed)
+{
+	trace_rdpmc(counter, val, failed);
+}
+EXPORT_SYMBOL(do_trace_rdpmc);
+EXPORT_TRACEPOINT_SYMBOL(rdpmc);
+
+#endif

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

* [tip:perf/core] perf/x86: Remove old MSR perf tracing code
  2015-12-02  1:01 ` [PATCH 4/4] perf, x86: Remove old MSR perf tracing code Andi Kleen
  2015-12-04 12:00   ` [tip:perf/core] perf/x86: " tip-bot for Andi Kleen
@ 2015-12-06 13:19   ` tip-bot for Andi Kleen
  1 sibling, 0 replies; 25+ messages in thread
From: tip-bot for Andi Kleen @ 2015-12-06 13:19 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: vincent.weaver, mingo, jolsa, eranian, torvalds, ak, efault,
	peterz, linux-kernel, acme, tglx, hpa

Commit-ID:  f1ad44884a4c421ceaa9a4a8242aeeee6f686670
Gitweb:     http://git.kernel.org/tip/f1ad44884a4c421ceaa9a4a8242aeeee6f686670
Author:     Andi Kleen <ak@linux.intel.com>
AuthorDate: Tue, 1 Dec 2015 17:01:00 -0800
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sun, 6 Dec 2015 12:56:14 +0100

perf/x86: Remove old MSR perf tracing code

Now that we have generic MSR trace points we can remove the old
hackish perf MSR read tracing code.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: rostedt@goodmis.org
Link: http://lkml.kernel.org/r/1449018060-1742-4-git-send-email-andi@firstfloor.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/cpu/perf_event.h | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index a7ab350..799e6bd 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -14,17 +14,7 @@
 
 #include <linux/perf_event.h>
 
-#if 0
-#undef wrmsrl
-#define wrmsrl(msr, val) 						\
-do {									\
-	unsigned int _msr = (msr);					\
-	u64 _val = (val);						\
-	trace_printk("wrmsrl(%x, %Lx)\n", (unsigned int)(_msr),		\
-			(unsigned long long)(_val));			\
-	native_write_msr((_msr), (u32)(_val), (u32)(_val >> 32));	\
-} while (0)
-#endif
+/* To enable MSR tracing please use the generic trace points. */
 
 /*
  *          |   NHM/WSM    |      SNB     |

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

* [PATCH 3/4] x86: Add trace point for MSR accesses
  2015-10-21 20:14 Adding MSR trace points, new edition Andi Kleen
@ 2015-10-21 20:14 ` Andi Kleen
  0 siblings, 0 replies; 25+ messages in thread
From: Andi Kleen @ 2015-10-21 20:14 UTC (permalink / raw)
  To: x86; +Cc: rostedt, peterz, linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

For debugging low level code interacting with the CPU
it is often useful to trace the MSR read/writes. This gives
a concise summary of PMU and other operations.

perf has an ad-hoc way to do this using trace_printk,
but it's somewhat limited (and also now spews ugly boot
messages when enabled)

Instead define real trace points for all MSR accesses.

This adds three new trace points: read_msr and write_msr
and rdpmc.

They also report if the access faulted (if *_safe is used)

This allows filtering and triggering on specific
MSR values, which allows various more advanced
debugging techniques.

All the values are well defined in the CPU documentation.

The trace can be post processed with
Documentation/trace/postprocess/decode_msr.py
to add symbolic MSR names to the trace.

I only added it to native MSR accesses in C, not paravirtualized
or in entry*.S (which is not too interesting)

Originally the patch kit moved the MSRs out of line.
This uses an alternative approach recommended by Steven Rostedt
of only moving the trace calls out of line, but open coding the
access to the jump label.

v2:
Move MSR trace events to arch/x86/include/asm/msr-trace.h
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 Documentation/trace/events-msr.txt            | 37 +++++++++++++++++
 Documentation/trace/postprocess/decode_msr.py | 37 +++++++++++++++++
 arch/x86/include/asm/msr-trace.h              | 57 +++++++++++++++++++++++++++
 arch/x86/include/asm/msr.h                    | 31 +++++++++++++++
 arch/x86/lib/msr.c                            | 26 ++++++++++++
 5 files changed, 188 insertions(+)
 create mode 100644 Documentation/trace/events-msr.txt
 create mode 100755 Documentation/trace/postprocess/decode_msr.py
 create mode 100644 arch/x86/include/asm/msr-trace.h

diff --git a/Documentation/trace/events-msr.txt b/Documentation/trace/events-msr.txt
new file mode 100644
index 0000000..78c383b
--- /dev/null
+++ b/Documentation/trace/events-msr.txt
@@ -0,0 +1,37 @@
+
+The x86 kernel supports tracing most MSR (Model Specific Register) accesses.
+To see the definition of the MSRs on Intel systems please see the SDM
+at http://www.intel.com/sdm (Volume 3)
+
+Available trace points:
+
+/sys/kernel/debug/tracing/events/msr/
+
+Trace MSR reads
+
+read_msr
+
+msr: MSR number
+val: Value written
+failed: 1 if the access failed, otherwise 0
+
+
+Trace MSR writes
+
+write_msr
+
+msr: MSR number
+val: Value written
+failed: 1 if the access failed, otherwise 0
+
+
+Trace RDPMC in kernel
+
+rdpmc
+
+The trace data can be post processed with the postprocess/decode_msr.py script
+
+cat /sys/kernel/debug/tracing/trace | decode_msr.py /usr/src/linux/include/asm/msr-index.h
+
+to add symbolic MSR names.
+
diff --git a/Documentation/trace/postprocess/decode_msr.py b/Documentation/trace/postprocess/decode_msr.py
new file mode 100755
index 0000000..0ab40e0
--- /dev/null
+++ b/Documentation/trace/postprocess/decode_msr.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+# add symbolic names to read_msr / write_msr in trace
+# decode_msr msr-index.h < trace
+import sys
+import re
+
+msrs = dict()
+
+with open(sys.argv[1] if len(sys.argv) > 1 else "msr-index.h", "r") as f:
+	for j in f:
+		m = re.match(r'#define (MSR_\w+)\s+(0x[0-9a-fA-F]+)', j)
+		if m:
+			msrs[int(m.group(2), 16)] = m.group(1)
+
+extra_ranges = (
+	( "MSR_LASTBRANCH_%d_FROM_IP", 0x680, 0x69F ),
+	( "MSR_LASTBRANCH_%d_TO_IP", 0x6C0, 0x6DF ),
+	( "LBR_INFO_%d", 0xdc0, 0xddf ),
+)
+
+for j in sys.stdin:
+	m = re.search(r'(read|write)_msr:\s+([0-9a-f]+)', j)
+	if m:
+		r = None
+		num = int(m.group(2), 16)
+		if num in msrs:
+			r = msrs[num]
+		else:
+			for er in extra_ranges:
+				if er[1] <= num <= er[2]:
+					r = er[0] % (num - er[1],)
+					break
+		if r:
+			j = j.replace(" " + m.group(2), " " + r + "(" + m.group(2) + ")")
+	print j,
+
+
diff --git a/arch/x86/include/asm/msr-trace.h b/arch/x86/include/asm/msr-trace.h
new file mode 100644
index 0000000..7567225
--- /dev/null
+++ b/arch/x86/include/asm/msr-trace.h
@@ -0,0 +1,57 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM msr
+
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE msr-trace
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH asm/
+
+#if !defined(_TRACE_MSR_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_MSR_H
+
+#include <linux/tracepoint.h>
+
+/*
+ * Tracing for x86 model specific registers. Directly maps to the
+ * RDMSR/WRMSR instructions.
+ */
+
+DECLARE_EVENT_CLASS(msr_trace_class,
+	    TP_PROTO(unsigned msr, u64 val, int failed),
+	    TP_ARGS(msr, val, failed),
+	    TP_STRUCT__entry(
+		    __field(	unsigned,	msr )
+		    __field(    u64,		val )
+		    __field(    int,		failed )
+	    ),
+	    TP_fast_assign(
+		    __entry->msr = msr;
+		    __entry->val = val;
+		    __entry->failed = failed;
+	    ),
+	    TP_printk("%x, value %llx%s",
+		      __entry->msr,
+		      __entry->val,
+		      __entry->failed ? " #GP" : "")
+);
+
+DEFINE_EVENT(msr_trace_class, read_msr,
+	     TP_PROTO(unsigned msr, u64 val, int failed),
+	     TP_ARGS(msr, val, failed)
+);
+
+DEFINE_EVENT(msr_trace_class, write_msr,
+	     TP_PROTO(unsigned msr, u64 val, int failed),
+	     TP_ARGS(msr, val, failed)
+);
+
+DEFINE_EVENT(msr_trace_class, rdpmc,
+	     TP_PROTO(unsigned msr, u64 val, int failed),
+	     TP_ARGS(msr, val, failed)
+);
+
+#endif /* _TRACE_MSR_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 77d8b28..fedd6e6 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -57,11 +57,34 @@ static inline unsigned long long native_read_tscp(unsigned int *aux)
 #define EAX_EDX_RET(val, low, high)	"=A" (val)
 #endif
 
+#ifdef CONFIG_TRACEPOINTS
+/*
+ * Be very careful with includes. This header is prone to include loops.
+ */
+#include <asm/atomic.h>
+#include <linux/tracepoint-defs.h>
+
+extern struct tracepoint __tracepoint_read_msr;
+extern struct tracepoint __tracepoint_write_msr;
+extern struct tracepoint __tracepoint_rdpmc;
+#define msr_tracepoint_active(t) static_key_false(&(t).key)
+extern void do_trace_write_msr(unsigned msr, u64 val, int failed);
+extern void do_trace_read_msr(unsigned msr, u64 val, int failed);
+extern void do_trace_rdpmc(unsigned msr, u64 val, int failed);
+#else
+#define msr_tracepoint_active(t) false
+static inline void do_trace_write_msr(unsigned msr, u64 val, int failed) {}
+static inline void do_trace_read_msr(unsigned msr, u64 val, int failed) {}
+static inline void do_trace_rdpmc(unsigned msr, u64 val, int failed) {}
+#endif
+
 static inline unsigned long long native_read_msr(unsigned int msr)
 {
 	DECLARE_ARGS(val, low, high);
 
 	asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr));
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), 0);
 	return EAX_EDX_VAL(val, low, high);
 }
 
@@ -78,6 +101,8 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
 		     _ASM_EXTABLE(2b, 3b)
 		     : [err] "=r" (*err), EAX_EDX_RET(val, low, high)
 		     : "c" (msr), [fault] "i" (-EIO));
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), *err);
 	return EAX_EDX_VAL(val, low, high);
 }
 
@@ -85,6 +110,8 @@ static inline void native_write_msr(unsigned int msr,
 				    unsigned low, unsigned high)
 {
 	asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_write_msr(msr, ((u64)high << 32 | low), 0);
 }
 
 /* Can be uninlined because referenced by paravirt */
@@ -102,6 +129,8 @@ notrace static inline int native_write_msr_safe(unsigned int msr,
 		     : "c" (msr), "0" (low), "d" (high),
 		       [fault] "i" (-EIO)
 		     : "memory");
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_write_msr(msr, ((u64)high << 32 | low), err);
 	return err;
 }
 
@@ -160,6 +189,8 @@ static inline unsigned long long native_read_pmc(int counter)
 	DECLARE_ARGS(val, low, high);
 
 	asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
+	if (msr_tracepoint_active(__tracepoint_rdpmc))
+		do_trace_rdpmc(counter, EAX_EDX_VAL(val, low, high), 0);
 	return EAX_EDX_VAL(val, low, high);
 }
 
diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c
index 4362373..004c861 100644
--- a/arch/x86/lib/msr.c
+++ b/arch/x86/lib/msr.c
@@ -1,6 +1,8 @@
 #include <linux/module.h>
 #include <linux/preempt.h>
 #include <asm/msr.h>
+#define CREATE_TRACE_POINTS
+#include <asm/msr-trace.h>
 
 struct msr *msrs_alloc(void)
 {
@@ -108,3 +110,27 @@ int msr_clear_bit(u32 msr, u8 bit)
 {
 	return __flip_bit(msr, bit, false);
 }
+
+#ifdef CONFIG_TRACEPOINTS
+void do_trace_write_msr(unsigned msr, u64 val, int failed)
+{
+	trace_write_msr(msr, val, failed);
+}
+EXPORT_SYMBOL(do_trace_write_msr);
+EXPORT_TRACEPOINT_SYMBOL(write_msr);
+
+void do_trace_read_msr(unsigned msr, u64 val, int failed)
+{
+	trace_read_msr(msr, val, failed);
+}
+EXPORT_SYMBOL(do_trace_read_msr);
+EXPORT_TRACEPOINT_SYMBOL(read_msr);
+
+void do_trace_rdpmc(unsigned counter, u64 val, int failed)
+{
+	trace_rdpmc(counter, val, failed);
+}
+EXPORT_SYMBOL(do_trace_rdpmc);
+EXPORT_TRACEPOINT_SYMBOL(rdpmc);
+
+#endif
-- 
2.4.3


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

* Re: [PATCH 3/4] x86: Add trace point for MSR accesses
  2015-10-20 18:40 ` [PATCH 3/4] x86: Add trace point for MSR accesses Andi Kleen
@ 2015-10-20 19:39   ` Steven Rostedt
  0 siblings, 0 replies; 25+ messages in thread
From: Steven Rostedt @ 2015-10-20 19:39 UTC (permalink / raw)
  To: Andi Kleen; +Cc: x86, peterz, linux-kernel, Andi Kleen

On Tue, 20 Oct 2015 11:40:45 -0700
Andi Kleen <andi@firstfloor.org> wrote:


> diff --git a/include/trace/events/msr.h b/include/trace/events/msr.h

Architecture specific tracepoints should not exist in include/trace.
Please move this to arch/x86/lib (or some other x86 directory).

See samples/trace_events/ for how to have a header outside of
include/trace.

-- Steve


> new file mode 100644
> index 0000000..b2232b5
> --- /dev/null
> +++ b/include/trace/events/msr.h
> @@ -0,0 +1,51 @@
> +#undef TRACE_SYSTEM
> +#define TRACE_SYSTEM msr
> +
> +#if !defined(_TRACE_MSR_H) || defined(TRACE_HEADER_MULTI_READ)
> +#define _TRACE_MSR_H
> +
> +#include <linux/tracepoint.h>
> +
> +/*
> + * Tracing for x86 model specific registers. Directly maps to the
> + * RDMSR/WRMSR instructions.
> + */
> +
> +DECLARE_EVENT_CLASS(msr_trace_class,
> +	    TP_PROTO(unsigned msr, u64 val, int failed),
> +	    TP_ARGS(msr, val, failed),
> +	    TP_STRUCT__entry(
> +		    __field(	unsigned,	msr )
> +		    __field(    u64,		val )
> +		    __field(    int,		failed )
> +	    ),
> +	    TP_fast_assign(
> +		    __entry->msr = msr;
> +		    __entry->val = val;
> +		    __entry->failed = failed;
> +	    ),
> +	    TP_printk("%x, value %llx%s",
> +		      __entry->msr,
> +		      __entry->val,
> +		      __entry->failed ? " #GP" : "")
> +);
> +
> +DEFINE_EVENT(msr_trace_class, read_msr,
> +	     TP_PROTO(unsigned msr, u64 val, int failed),
> +	     TP_ARGS(msr, val, failed)
> +);
> +
> +DEFINE_EVENT(msr_trace_class, write_msr,
> +	     TP_PROTO(unsigned msr, u64 val, int failed),
> +	     TP_ARGS(msr, val, failed)
> +);
> +
> +DEFINE_EVENT(msr_trace_class, rdpmc,
> +	     TP_PROTO(unsigned msr, u64 val, int failed),
> +	     TP_ARGS(msr, val, failed)
> +);
> +
> +#endif /* _TRACE_MSR_H */
> +
> +/* This part must be outside protection */
> +#include <trace/define_trace.h>


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

* [PATCH 3/4] x86: Add trace point for MSR accesses
  2015-10-20 18:40 Adding MSR trace points, new edition Andi Kleen
@ 2015-10-20 18:40 ` Andi Kleen
  2015-10-20 19:39   ` Steven Rostedt
  0 siblings, 1 reply; 25+ messages in thread
From: Andi Kleen @ 2015-10-20 18:40 UTC (permalink / raw)
  To: x86; +Cc: rostedt, peterz, linux-kernel, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

For debugging low level code interacting with the CPU
it is often useful to trace the MSR read/writes. This gives
a concise summary of PMU and other operations.

perf has an ad-hoc way to do this using trace_printk,
but it's somewhat limited (and also now spews ugly boot
messages when enabled)

Instead define real trace points for all MSR accesses.

This adds three new trace points: read_msr and write_msr
and rdpmc.

They also report if the access faulted (if *_safe is used)

This allows filtering and triggering on specific
MSR values, which allows various more advanced
debugging techniques.

All the values are well defined in the CPU documentation.

The trace can be post processed with
Documentation/trace/postprocess/decode_msr.py
to add symbolic MSR names to the trace.

I only added it to native MSR accesses in C, not paravirtualized
or in entry*.S (which is not too interesting)

Originally the patch kit moved the MSRs out of line.
This uses an alternative approach recommended by Steven Rostedt
of only moving the trace calls out of line, but open coding the
access to the jump label.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 Documentation/trace/events-msr.txt            | 37 +++++++++++++++++++
 Documentation/trace/postprocess/decode_msr.py | 37 +++++++++++++++++++
 arch/x86/include/asm/msr.h                    | 31 ++++++++++++++++
 arch/x86/lib/msr.c                            | 26 ++++++++++++++
 include/trace/events/msr.h                    | 51 +++++++++++++++++++++++++++
 5 files changed, 182 insertions(+)
 create mode 100644 Documentation/trace/events-msr.txt
 create mode 100755 Documentation/trace/postprocess/decode_msr.py
 create mode 100644 include/trace/events/msr.h

diff --git a/Documentation/trace/events-msr.txt b/Documentation/trace/events-msr.txt
new file mode 100644
index 0000000..78c383b
--- /dev/null
+++ b/Documentation/trace/events-msr.txt
@@ -0,0 +1,37 @@
+
+The x86 kernel supports tracing most MSR (Model Specific Register) accesses.
+To see the definition of the MSRs on Intel systems please see the SDM
+at http://www.intel.com/sdm (Volume 3)
+
+Available trace points:
+
+/sys/kernel/debug/tracing/events/msr/
+
+Trace MSR reads
+
+read_msr
+
+msr: MSR number
+val: Value written
+failed: 1 if the access failed, otherwise 0
+
+
+Trace MSR writes
+
+write_msr
+
+msr: MSR number
+val: Value written
+failed: 1 if the access failed, otherwise 0
+
+
+Trace RDPMC in kernel
+
+rdpmc
+
+The trace data can be post processed with the postprocess/decode_msr.py script
+
+cat /sys/kernel/debug/tracing/trace | decode_msr.py /usr/src/linux/include/asm/msr-index.h
+
+to add symbolic MSR names.
+
diff --git a/Documentation/trace/postprocess/decode_msr.py b/Documentation/trace/postprocess/decode_msr.py
new file mode 100755
index 0000000..0ab40e0
--- /dev/null
+++ b/Documentation/trace/postprocess/decode_msr.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+# add symbolic names to read_msr / write_msr in trace
+# decode_msr msr-index.h < trace
+import sys
+import re
+
+msrs = dict()
+
+with open(sys.argv[1] if len(sys.argv) > 1 else "msr-index.h", "r") as f:
+	for j in f:
+		m = re.match(r'#define (MSR_\w+)\s+(0x[0-9a-fA-F]+)', j)
+		if m:
+			msrs[int(m.group(2), 16)] = m.group(1)
+
+extra_ranges = (
+	( "MSR_LASTBRANCH_%d_FROM_IP", 0x680, 0x69F ),
+	( "MSR_LASTBRANCH_%d_TO_IP", 0x6C0, 0x6DF ),
+	( "LBR_INFO_%d", 0xdc0, 0xddf ),
+)
+
+for j in sys.stdin:
+	m = re.search(r'(read|write)_msr:\s+([0-9a-f]+)', j)
+	if m:
+		r = None
+		num = int(m.group(2), 16)
+		if num in msrs:
+			r = msrs[num]
+		else:
+			for er in extra_ranges:
+				if er[1] <= num <= er[2]:
+					r = er[0] % (num - er[1],)
+					break
+		if r:
+			j = j.replace(" " + m.group(2), " " + r + "(" + m.group(2) + ")")
+	print j,
+
+
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 77d8b28..fedd6e6 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -57,11 +57,34 @@ static inline unsigned long long native_read_tscp(unsigned int *aux)
 #define EAX_EDX_RET(val, low, high)	"=A" (val)
 #endif
 
+#ifdef CONFIG_TRACEPOINTS
+/*
+ * Be very careful with includes. This header is prone to include loops.
+ */
+#include <asm/atomic.h>
+#include <linux/tracepoint-defs.h>
+
+extern struct tracepoint __tracepoint_read_msr;
+extern struct tracepoint __tracepoint_write_msr;
+extern struct tracepoint __tracepoint_rdpmc;
+#define msr_tracepoint_active(t) static_key_false(&(t).key)
+extern void do_trace_write_msr(unsigned msr, u64 val, int failed);
+extern void do_trace_read_msr(unsigned msr, u64 val, int failed);
+extern void do_trace_rdpmc(unsigned msr, u64 val, int failed);
+#else
+#define msr_tracepoint_active(t) false
+static inline void do_trace_write_msr(unsigned msr, u64 val, int failed) {}
+static inline void do_trace_read_msr(unsigned msr, u64 val, int failed) {}
+static inline void do_trace_rdpmc(unsigned msr, u64 val, int failed) {}
+#endif
+
 static inline unsigned long long native_read_msr(unsigned int msr)
 {
 	DECLARE_ARGS(val, low, high);
 
 	asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr));
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), 0);
 	return EAX_EDX_VAL(val, low, high);
 }
 
@@ -78,6 +101,8 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
 		     _ASM_EXTABLE(2b, 3b)
 		     : [err] "=r" (*err), EAX_EDX_RET(val, low, high)
 		     : "c" (msr), [fault] "i" (-EIO));
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), *err);
 	return EAX_EDX_VAL(val, low, high);
 }
 
@@ -85,6 +110,8 @@ static inline void native_write_msr(unsigned int msr,
 				    unsigned low, unsigned high)
 {
 	asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_write_msr(msr, ((u64)high << 32 | low), 0);
 }
 
 /* Can be uninlined because referenced by paravirt */
@@ -102,6 +129,8 @@ notrace static inline int native_write_msr_safe(unsigned int msr,
 		     : "c" (msr), "0" (low), "d" (high),
 		       [fault] "i" (-EIO)
 		     : "memory");
+	if (msr_tracepoint_active(__tracepoint_read_msr))
+		do_trace_write_msr(msr, ((u64)high << 32 | low), err);
 	return err;
 }
 
@@ -160,6 +189,8 @@ static inline unsigned long long native_read_pmc(int counter)
 	DECLARE_ARGS(val, low, high);
 
 	asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
+	if (msr_tracepoint_active(__tracepoint_rdpmc))
+		do_trace_rdpmc(counter, EAX_EDX_VAL(val, low, high), 0);
 	return EAX_EDX_VAL(val, low, high);
 }
 
diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c
index 4362373..47248ee 100644
--- a/arch/x86/lib/msr.c
+++ b/arch/x86/lib/msr.c
@@ -1,6 +1,8 @@
 #include <linux/module.h>
 #include <linux/preempt.h>
 #include <asm/msr.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/msr.h>
 
 struct msr *msrs_alloc(void)
 {
@@ -108,3 +110,27 @@ int msr_clear_bit(u32 msr, u8 bit)
 {
 	return __flip_bit(msr, bit, false);
 }
+
+#ifdef CONFIG_TRACEPOINTS
+void do_trace_write_msr(unsigned msr, u64 val, int failed)
+{
+	trace_write_msr(msr, val, failed);
+}
+EXPORT_SYMBOL(do_trace_write_msr);
+EXPORT_TRACEPOINT_SYMBOL(write_msr);
+
+void do_trace_read_msr(unsigned msr, u64 val, int failed)
+{
+	trace_read_msr(msr, val, failed);
+}
+EXPORT_SYMBOL(do_trace_read_msr);
+EXPORT_TRACEPOINT_SYMBOL(read_msr);
+
+void do_trace_rdpmc(unsigned counter, u64 val, int failed)
+{
+	trace_rdpmc(counter, val, failed);
+}
+EXPORT_SYMBOL(do_trace_rdpmc);
+EXPORT_TRACEPOINT_SYMBOL(rdpmc);
+
+#endif
diff --git a/include/trace/events/msr.h b/include/trace/events/msr.h
new file mode 100644
index 0000000..b2232b5
--- /dev/null
+++ b/include/trace/events/msr.h
@@ -0,0 +1,51 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM msr
+
+#if !defined(_TRACE_MSR_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_MSR_H
+
+#include <linux/tracepoint.h>
+
+/*
+ * Tracing for x86 model specific registers. Directly maps to the
+ * RDMSR/WRMSR instructions.
+ */
+
+DECLARE_EVENT_CLASS(msr_trace_class,
+	    TP_PROTO(unsigned msr, u64 val, int failed),
+	    TP_ARGS(msr, val, failed),
+	    TP_STRUCT__entry(
+		    __field(	unsigned,	msr )
+		    __field(    u64,		val )
+		    __field(    int,		failed )
+	    ),
+	    TP_fast_assign(
+		    __entry->msr = msr;
+		    __entry->val = val;
+		    __entry->failed = failed;
+	    ),
+	    TP_printk("%x, value %llx%s",
+		      __entry->msr,
+		      __entry->val,
+		      __entry->failed ? " #GP" : "")
+);
+
+DEFINE_EVENT(msr_trace_class, read_msr,
+	     TP_PROTO(unsigned msr, u64 val, int failed),
+	     TP_ARGS(msr, val, failed)
+);
+
+DEFINE_EVENT(msr_trace_class, write_msr,
+	     TP_PROTO(unsigned msr, u64 val, int failed),
+	     TP_ARGS(msr, val, failed)
+);
+
+DEFINE_EVENT(msr_trace_class, rdpmc,
+	     TP_PROTO(unsigned msr, u64 val, int failed),
+	     TP_ARGS(msr, val, failed)
+);
+
+#endif /* _TRACE_MSR_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
-- 
2.4.3


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

end of thread, other threads:[~2015-12-06 13:20 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-02  1:00 [PATCH 1/4] x86: Don't include asm/processor.h into asm/atomic.h Andi Kleen
2015-12-02  1:00 ` [PATCH 2/4] tracepoints: Move struct tracepoint to new tracepoint-defs.h header Andi Kleen
2015-12-02  1:56   ` Steven Rostedt
2015-12-04 11:59   ` [tip:perf/core] " tip-bot for Andi Kleen
2015-12-06 13:18   ` tip-bot for Andi Kleen
2015-12-02  1:00 ` [PATCH 3/4] x86: Add trace point for MSR accesses Andi Kleen
2015-12-02  2:03   ` Steven Rostedt
2015-12-04 11:59   ` [tip:perf/core] x86, tracing, perf: " tip-bot for Andi Kleen
2015-12-04 12:11     ` Borislav Petkov
2015-12-04 18:28       ` Andi Kleen
2015-12-04 18:30         ` Borislav Petkov
2015-12-04 22:18           ` Andi Kleen
2015-12-04 22:27             ` Borislav Petkov
2015-12-04 22:35           ` H. Peter Anvin
2015-12-04 22:48             ` Borislav Petkov
2015-12-04 22:57               ` H. Peter Anvin
2015-12-06 13:19   ` tip-bot for Andi Kleen
2015-12-02  1:01 ` [PATCH 4/4] perf, x86: Remove old MSR perf tracing code Andi Kleen
2015-12-04 12:00   ` [tip:perf/core] perf/x86: " tip-bot for Andi Kleen
2015-12-06 13:19   ` tip-bot for Andi Kleen
2015-12-04 11:58 ` [tip:perf/core] x86/headers: Don't include asm/processor.h in asm /atomic.h tip-bot for Andi Kleen
2015-12-06 13:18 ` tip-bot for Andi Kleen
  -- strict thread matches above, loose matches on Subject: below --
2015-10-21 20:14 Adding MSR trace points, new edition Andi Kleen
2015-10-21 20:14 ` [PATCH 3/4] x86: Add trace point for MSR accesses Andi Kleen
2015-10-20 18:40 Adding MSR trace points, new edition Andi Kleen
2015-10-20 18:40 ` [PATCH 3/4] x86: Add trace point for MSR accesses Andi Kleen
2015-10-20 19:39   ` Steven Rostedt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).