All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] generic IPI tracing
@ 2014-07-25 20:05 ` Nicolas Pitre
  0 siblings, 0 replies; 30+ messages in thread
From: Nicolas Pitre @ 2014-07-25 20:05 UTC (permalink / raw)
  To: Steven Rostedt, Ingo Molnar
  Cc: Daniel Lezcano, Russell King - ARM Linux, Catalin Marinas,
	linux-kernel, linux-arm-kernel, linaro-kernel

This is v2 of the series initially posted here:

http://news.gmane.org/group/gmane.linux.kernel/thread=1750391

Steven / Ingo: Would you please merge those patches in your tree for some 
linux-next exposure and mainline inclusion? Patches 1 to 4 may go in now. 
I'm unsure about patch 5 so I'll leave it to your appreciation.

Changes since v1:

- added empty tracepoint_string when !CONFIG_TRACING, from Steven
- ipi_types[] is unconditionally marked with __tracepoint_string now
- added comment to arch/x86/kernel/smp.c justifying the #undef's
- collected ACKs, refined commit logs

diffstat:

 arch/arm/kernel/smp.c        | 70 ++++++++++++++++++------------
 arch/arm64/kernel/smp.c      | 65 +++++++++++++++++-----------
 arch/x86/kernel/smp.c        | 20 +++++++++
 include/linux/ftrace_event.h | 10 +++++
 include/trace/events/ipi.h   | 89 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 200 insertions(+), 54 deletions(-)


Nicolas


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

* [PATCH v2 0/5] generic IPI tracing
@ 2014-07-25 20:05 ` Nicolas Pitre
  0 siblings, 0 replies; 30+ messages in thread
From: Nicolas Pitre @ 2014-07-25 20:05 UTC (permalink / raw)
  To: linux-arm-kernel

This is v2 of the series initially posted here:

http://news.gmane.org/group/gmane.linux.kernel/thread=1750391

Steven / Ingo: Would you please merge those patches in your tree for some 
linux-next exposure and mainline inclusion? Patches 1 to 4 may go in now. 
I'm unsure about patch 5 so I'll leave it to your appreciation.

Changes since v1:

- added empty tracepoint_string when !CONFIG_TRACING, from Steven
- ipi_types[] is unconditionally marked with __tracepoint_string now
- added comment to arch/x86/kernel/smp.c justifying the #undef's
- collected ACKs, refined commit logs

diffstat:

 arch/arm/kernel/smp.c        | 70 ++++++++++++++++++------------
 arch/arm64/kernel/smp.c      | 65 +++++++++++++++++-----------
 arch/x86/kernel/smp.c        | 20 +++++++++
 include/linux/ftrace_event.h | 10 +++++
 include/trace/events/ipi.h   | 89 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 200 insertions(+), 54 deletions(-)


Nicolas

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

* [PATCH v2 1/5] tracing: Do not do anything special with tracepoint_string when tracing is disabled
  2014-07-25 20:05 ` Nicolas Pitre
@ 2014-07-25 20:05   ` Nicolas Pitre
  -1 siblings, 0 replies; 30+ messages in thread
From: Nicolas Pitre @ 2014-07-25 20:05 UTC (permalink / raw)
  To: Steven Rostedt, Ingo Molnar
  Cc: Daniel Lezcano, Russell King - ARM Linux, Catalin Marinas,
	linux-kernel, linux-arm-kernel, linaro-kernel

From: Steven Rostedt <rostedt@goodmis.org>

When CONFIG_TRACING is not enabled, there's no reason to save the trace
strings either by the linker or as a static variable that can be
referenced later. Simply pass back the string that is given to
tracepoint_string().

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Nicolas Pitre <nico@linaro.org>
---
 include/linux/ftrace_event.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index cff3106ffe..b29636327d 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -574,6 +574,7 @@ do {									\
 		__trace_printk(ip, fmt, ##args);			\
 } while (0)
 
+#ifdef CONFIG_TRACING
 /**
  * tracepoint_string - register constant persistent string to trace system
  * @str - a constant persistent string that will be referenced in tracepoints
@@ -607,6 +608,15 @@ do {									\
 		___tp_str;						\
 	})
 #define __tracepoint_string	__attribute__((section("__tracepoint_str")))
+#else
+/*
+ * tracepoint_string() is used to save the string address for userspace
+ * tracing tools. When tracing isn't configured, there's no need to save
+ * anything.
+ */
+# define tracepoint_string(str) str
+# define __tracepoint_string
+#endif
 
 #ifdef CONFIG_PERF_EVENTS
 struct perf_event;
-- 
1.8.4.108.g55ea5f6


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

* [PATCH v2 1/5] tracing: Do not do anything special with tracepoint_string when tracing is disabled
@ 2014-07-25 20:05   ` Nicolas Pitre
  0 siblings, 0 replies; 30+ messages in thread
From: Nicolas Pitre @ 2014-07-25 20:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: Steven Rostedt <rostedt@goodmis.org>

When CONFIG_TRACING is not enabled, there's no reason to save the trace
strings either by the linker or as a static variable that can be
referenced later. Simply pass back the string that is given to
tracepoint_string().

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Nicolas Pitre <nico@linaro.org>
---
 include/linux/ftrace_event.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index cff3106ffe..b29636327d 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -574,6 +574,7 @@ do {									\
 		__trace_printk(ip, fmt, ##args);			\
 } while (0)
 
+#ifdef CONFIG_TRACING
 /**
  * tracepoint_string - register constant persistent string to trace system
  * @str - a constant persistent string that will be referenced in tracepoints
@@ -607,6 +608,15 @@ do {									\
 		___tp_str;						\
 	})
 #define __tracepoint_string	__attribute__((section("__tracepoint_str")))
+#else
+/*
+ * tracepoint_string() is used to save the string address for userspace
+ * tracing tools. When tracing isn't configured, there's no need to save
+ * anything.
+ */
+# define tracepoint_string(str) str
+# define __tracepoint_string
+#endif
 
 #ifdef CONFIG_PERF_EVENTS
 struct perf_event;
-- 
1.8.4.108.g55ea5f6

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

* [PATCH v2 2/5] tracepoint: add generic tracepoint definitions for IPI tracing
  2014-07-25 20:05 ` Nicolas Pitre
@ 2014-07-25 20:05   ` Nicolas Pitre
  -1 siblings, 0 replies; 30+ messages in thread
From: Nicolas Pitre @ 2014-07-25 20:05 UTC (permalink / raw)
  To: Steven Rostedt, Ingo Molnar
  Cc: Daniel Lezcano, Russell King - ARM Linux, Catalin Marinas,
	linux-kernel, linux-arm-kernel, linaro-kernel

The Inter Processor Interrupt is used to make another processor do a
specific action such as rescheduling tasks, signal a timer event or
execute something in another CPU's context. IRQs are already traceable
but IPIs were not. Tracing them is useful for monitoring IPI latency,
or to verify when they are the source of CPU wake-ups with power
management implications.

Three trace hooks are defined: ipi_raise, ipi_entry and ipi_exit. To make
them portable, a string is used to identify them and correlate related
events. Additionally, ipi_raise records a bitmask representing targeted
CPUs.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 include/trace/events/ipi.h | 89 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 89 insertions(+)
 create mode 100644 include/trace/events/ipi.h

diff --git a/include/trace/events/ipi.h b/include/trace/events/ipi.h
new file mode 100644
index 0000000000..834a7362a6
--- /dev/null
+++ b/include/trace/events/ipi.h
@@ -0,0 +1,89 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM ipi
+
+#if !defined(_TRACE_IPI_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_IPI_H
+
+#include <linux/tracepoint.h>
+
+/**
+ * ipi_raise - called when a smp cross call is made
+ *
+ * @mask: mask of recipient CPUs for the IPI
+ * @reason: string identifying the IPI purpose
+ *
+ * It is necessary for @reason to be a static string declared with
+ * __tracepoint_string.
+ */
+TRACE_EVENT(ipi_raise,
+
+	TP_PROTO(const struct cpumask *mask, const char *reason),
+
+	TP_ARGS(mask, reason),
+
+	TP_STRUCT__entry(
+		__bitmask(target_cpus, nr_cpumask_bits)
+		__field(const char *, reason)
+	),
+
+	TP_fast_assign(
+		__assign_bitmask(target_cpus, cpumask_bits(mask), nr_cpumask_bits);
+		__entry->reason = reason;
+	),
+
+	TP_printk("target_mask=%s (%s)", __get_bitmask(target_cpus), __entry->reason)
+);
+
+DECLARE_EVENT_CLASS(ipi_handler,
+
+	TP_PROTO(const char *reason),
+
+	TP_ARGS(reason),
+
+	TP_STRUCT__entry(
+		__field(const char *, reason)
+	),
+
+	TP_fast_assign(
+		__entry->reason = reason;
+	),
+
+	TP_printk("(%s)", __entry->reason)
+);
+
+/**
+ * ipi_entry - called immediately before the IPI handler
+ *
+ * @reason: string identifying the IPI purpose
+ *
+ * It is necessary for @reason to be a static string declared with
+ * __tracepoint_string, ideally the same as used with trace_ipi_raise
+ * for that IPI.
+ */
+DEFINE_EVENT(ipi_handler, ipi_entry,
+
+	TP_PROTO(const char *reason),
+
+	TP_ARGS(reason)
+);
+
+/**
+ * ipi_exit - called immediately after the IPI handler returns
+ *
+ * @reason: string identifying the IPI purpose
+ *
+ * It is necessary for @reason to be a static string declared with
+ * __tracepoint_string, ideally the same as used with trace_ipi_raise for
+ * that IPI.
+ */
+DEFINE_EVENT(ipi_handler, ipi_exit,
+
+	TP_PROTO(const char *reason),
+
+	TP_ARGS(reason)
+);
+
+#endif /* _TRACE_IPI_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
-- 
1.8.4.108.g55ea5f6


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

* [PATCH v2 2/5] tracepoint: add generic tracepoint definitions for IPI tracing
@ 2014-07-25 20:05   ` Nicolas Pitre
  0 siblings, 0 replies; 30+ messages in thread
From: Nicolas Pitre @ 2014-07-25 20:05 UTC (permalink / raw)
  To: linux-arm-kernel

The Inter Processor Interrupt is used to make another processor do a
specific action such as rescheduling tasks, signal a timer event or
execute something in another CPU's context. IRQs are already traceable
but IPIs were not. Tracing them is useful for monitoring IPI latency,
or to verify when they are the source of CPU wake-ups with power
management implications.

Three trace hooks are defined: ipi_raise, ipi_entry and ipi_exit. To make
them portable, a string is used to identify them and correlate related
events. Additionally, ipi_raise records a bitmask representing targeted
CPUs.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 include/trace/events/ipi.h | 89 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 89 insertions(+)
 create mode 100644 include/trace/events/ipi.h

diff --git a/include/trace/events/ipi.h b/include/trace/events/ipi.h
new file mode 100644
index 0000000000..834a7362a6
--- /dev/null
+++ b/include/trace/events/ipi.h
@@ -0,0 +1,89 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM ipi
+
+#if !defined(_TRACE_IPI_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_IPI_H
+
+#include <linux/tracepoint.h>
+
+/**
+ * ipi_raise - called when a smp cross call is made
+ *
+ * @mask: mask of recipient CPUs for the IPI
+ * @reason: string identifying the IPI purpose
+ *
+ * It is necessary for @reason to be a static string declared with
+ * __tracepoint_string.
+ */
+TRACE_EVENT(ipi_raise,
+
+	TP_PROTO(const struct cpumask *mask, const char *reason),
+
+	TP_ARGS(mask, reason),
+
+	TP_STRUCT__entry(
+		__bitmask(target_cpus, nr_cpumask_bits)
+		__field(const char *, reason)
+	),
+
+	TP_fast_assign(
+		__assign_bitmask(target_cpus, cpumask_bits(mask), nr_cpumask_bits);
+		__entry->reason = reason;
+	),
+
+	TP_printk("target_mask=%s (%s)", __get_bitmask(target_cpus), __entry->reason)
+);
+
+DECLARE_EVENT_CLASS(ipi_handler,
+
+	TP_PROTO(const char *reason),
+
+	TP_ARGS(reason),
+
+	TP_STRUCT__entry(
+		__field(const char *, reason)
+	),
+
+	TP_fast_assign(
+		__entry->reason = reason;
+	),
+
+	TP_printk("(%s)", __entry->reason)
+);
+
+/**
+ * ipi_entry - called immediately before the IPI handler
+ *
+ * @reason: string identifying the IPI purpose
+ *
+ * It is necessary for @reason to be a static string declared with
+ * __tracepoint_string, ideally the same as used with trace_ipi_raise
+ * for that IPI.
+ */
+DEFINE_EVENT(ipi_handler, ipi_entry,
+
+	TP_PROTO(const char *reason),
+
+	TP_ARGS(reason)
+);
+
+/**
+ * ipi_exit - called immediately after the IPI handler returns
+ *
+ * @reason: string identifying the IPI purpose
+ *
+ * It is necessary for @reason to be a static string declared with
+ * __tracepoint_string, ideally the same as used with trace_ipi_raise for
+ * that IPI.
+ */
+DEFINE_EVENT(ipi_handler, ipi_exit,
+
+	TP_PROTO(const char *reason),
+
+	TP_ARGS(reason)
+);
+
+#endif /* _TRACE_IPI_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
-- 
1.8.4.108.g55ea5f6

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

* [PATCH v2 3/5] ARM: add IPI tracepoints
  2014-07-25 20:05 ` Nicolas Pitre
@ 2014-07-25 20:05   ` Nicolas Pitre
  -1 siblings, 0 replies; 30+ messages in thread
From: Nicolas Pitre @ 2014-07-25 20:05 UTC (permalink / raw)
  To: Steven Rostedt, Ingo Molnar
  Cc: Daniel Lezcano, Russell King - ARM Linux, Catalin Marinas,
	linux-kernel, linux-arm-kernel, linaro-kernel

The strings used to list IPIs in /proc/interrupts are reused for tracing
purposes.

While at it, prevent a negative ipinr from escaping the range check
in handle_IPI().

Signed-off-by: Nicolas Pitre <nico@linaro.org>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
---
 arch/arm/kernel/smp.c | 70 ++++++++++++++++++++++++++++++---------------------
 1 file changed, 42 insertions(+), 28 deletions(-)

diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 7c4fada440..9388a3d479 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -47,6 +47,9 @@
 #include <asm/mach/arch.h>
 #include <asm/mpu.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/ipi.h>
+
 /*
  * as from 2.5, kernels no longer have an init_tasks structure
  * so we need some other way of telling a new secondary core
@@ -430,38 +433,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 	}
 }
 
-static void (*smp_cross_call)(const struct cpumask *, unsigned int);
+static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
 
 void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
 {
-	if (!smp_cross_call)
-		smp_cross_call = fn;
-}
-
-void arch_send_call_function_ipi_mask(const struct cpumask *mask)
-{
-	smp_cross_call(mask, IPI_CALL_FUNC);
-}
-
-void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
-{
-	smp_cross_call(mask, IPI_WAKEUP);
-}
-
-void arch_send_call_function_single_ipi(int cpu)
-{
-	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+	if (!__smp_cross_call)
+		__smp_cross_call = fn;
 }
 
-#ifdef CONFIG_IRQ_WORK
-void arch_irq_work_raise(void)
-{
-	if (is_smp())
-		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
-}
-#endif
-
-static const char *ipi_types[NR_IPI] = {
+static const char *ipi_types[NR_IPI] __tracepoint_string = {
 #define S(x,s)	[x] = s
 	S(IPI_WAKEUP, "CPU wakeup interrupts"),
 	S(IPI_TIMER, "Timer broadcast interrupts"),
@@ -473,6 +453,12 @@ static const char *ipi_types[NR_IPI] = {
 	S(IPI_COMPLETION, "completion interrupts"),
 };
 
+static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
+{
+	trace_ipi_raise(target, ipi_types[ipinr]);
+	__smp_cross_call(target, ipinr);
+}
+
 void show_ipi_list(struct seq_file *p, int prec)
 {
 	unsigned int cpu, i;
@@ -499,6 +485,29 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
 	return sum;
 }
 
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
+{
+	smp_cross_call(mask, IPI_CALL_FUNC);
+}
+
+void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
+{
+	smp_cross_call(mask, IPI_WAKEUP);
+}
+
+void arch_send_call_function_single_ipi(int cpu)
+{
+	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+}
+
+#ifdef CONFIG_IRQ_WORK
+void arch_irq_work_raise(void)
+{
+	if (is_smp())
+		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
+}
+#endif
+
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 void tick_broadcast(const struct cpumask *mask)
 {
@@ -556,8 +565,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
 	unsigned int cpu = smp_processor_id();
 	struct pt_regs *old_regs = set_irq_regs(regs);
 
-	if (ipinr < NR_IPI)
+	if ((unsigned)ipinr < NR_IPI) {
+		trace_ipi_entry(ipi_types[ipinr]);
 		__inc_irq_stat(cpu, ipi_irqs[ipinr]);
+	}
 
 	switch (ipinr) {
 	case IPI_WAKEUP:
@@ -612,6 +623,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
 		       cpu, ipinr);
 		break;
 	}
+
+	if ((unsigned)ipinr < NR_IPI)
+		trace_ipi_exit(ipi_types[ipinr]);
 	set_irq_regs(old_regs);
 }
 
-- 
1.8.4.108.g55ea5f6


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

* [PATCH v2 3/5] ARM: add IPI tracepoints
@ 2014-07-25 20:05   ` Nicolas Pitre
  0 siblings, 0 replies; 30+ messages in thread
From: Nicolas Pitre @ 2014-07-25 20:05 UTC (permalink / raw)
  To: linux-arm-kernel

The strings used to list IPIs in /proc/interrupts are reused for tracing
purposes.

While at it, prevent a negative ipinr from escaping the range check
in handle_IPI().

Signed-off-by: Nicolas Pitre <nico@linaro.org>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
---
 arch/arm/kernel/smp.c | 70 ++++++++++++++++++++++++++++++---------------------
 1 file changed, 42 insertions(+), 28 deletions(-)

diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 7c4fada440..9388a3d479 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -47,6 +47,9 @@
 #include <asm/mach/arch.h>
 #include <asm/mpu.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/ipi.h>
+
 /*
  * as from 2.5, kernels no longer have an init_tasks structure
  * so we need some other way of telling a new secondary core
@@ -430,38 +433,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 	}
 }
 
-static void (*smp_cross_call)(const struct cpumask *, unsigned int);
+static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
 
 void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
 {
-	if (!smp_cross_call)
-		smp_cross_call = fn;
-}
-
-void arch_send_call_function_ipi_mask(const struct cpumask *mask)
-{
-	smp_cross_call(mask, IPI_CALL_FUNC);
-}
-
-void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
-{
-	smp_cross_call(mask, IPI_WAKEUP);
-}
-
-void arch_send_call_function_single_ipi(int cpu)
-{
-	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+	if (!__smp_cross_call)
+		__smp_cross_call = fn;
 }
 
-#ifdef CONFIG_IRQ_WORK
-void arch_irq_work_raise(void)
-{
-	if (is_smp())
-		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
-}
-#endif
-
-static const char *ipi_types[NR_IPI] = {
+static const char *ipi_types[NR_IPI] __tracepoint_string = {
 #define S(x,s)	[x] = s
 	S(IPI_WAKEUP, "CPU wakeup interrupts"),
 	S(IPI_TIMER, "Timer broadcast interrupts"),
@@ -473,6 +453,12 @@ static const char *ipi_types[NR_IPI] = {
 	S(IPI_COMPLETION, "completion interrupts"),
 };
 
+static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
+{
+	trace_ipi_raise(target, ipi_types[ipinr]);
+	__smp_cross_call(target, ipinr);
+}
+
 void show_ipi_list(struct seq_file *p, int prec)
 {
 	unsigned int cpu, i;
@@ -499,6 +485,29 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
 	return sum;
 }
 
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
+{
+	smp_cross_call(mask, IPI_CALL_FUNC);
+}
+
+void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
+{
+	smp_cross_call(mask, IPI_WAKEUP);
+}
+
+void arch_send_call_function_single_ipi(int cpu)
+{
+	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+}
+
+#ifdef CONFIG_IRQ_WORK
+void arch_irq_work_raise(void)
+{
+	if (is_smp())
+		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
+}
+#endif
+
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 void tick_broadcast(const struct cpumask *mask)
 {
@@ -556,8 +565,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
 	unsigned int cpu = smp_processor_id();
 	struct pt_regs *old_regs = set_irq_regs(regs);
 
-	if (ipinr < NR_IPI)
+	if ((unsigned)ipinr < NR_IPI) {
+		trace_ipi_entry(ipi_types[ipinr]);
 		__inc_irq_stat(cpu, ipi_irqs[ipinr]);
+	}
 
 	switch (ipinr) {
 	case IPI_WAKEUP:
@@ -612,6 +623,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
 		       cpu, ipinr);
 		break;
 	}
+
+	if ((unsigned)ipinr < NR_IPI)
+		trace_ipi_exit(ipi_types[ipinr]);
 	set_irq_regs(old_regs);
 }
 
-- 
1.8.4.108.g55ea5f6

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

* [PATCH v2 4/5] ARM64: add IPI tracepoints
  2014-07-25 20:05 ` Nicolas Pitre
@ 2014-07-25 20:05   ` Nicolas Pitre
  -1 siblings, 0 replies; 30+ messages in thread
From: Nicolas Pitre @ 2014-07-25 20:05 UTC (permalink / raw)
  To: Steven Rostedt, Ingo Molnar
  Cc: Daniel Lezcano, Russell King - ARM Linux, Catalin Marinas,
	linux-kernel, linux-arm-kernel, linaro-kernel

The strings used to list IPIs in /proc/interrupts are reused for tracing
purposes.

While at it, the code is slightly cleaned up so the ipi_types array
indices are no longer offset by IPI_RESCHEDULE whose value is 0 anyway.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/kernel/smp.c | 65 +++++++++++++++++++++++++++++--------------------
 1 file changed, 39 insertions(+), 26 deletions(-)

diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 40f38f46c8..a89c66f3b4 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -50,6 +50,9 @@
 #include <asm/tlbflush.h>
 #include <asm/ptrace.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/ipi.h>
+
 /*
  * as from 2.5, kernels no longer have an init_tasks structure
  * so we need some other way of telling a new secondary core
@@ -307,8 +310,6 @@ void __init smp_prepare_boot_cpu(void)
 	set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
 }
 
-static void (*smp_cross_call)(const struct cpumask *, unsigned int);
-
 /*
  * Enumerate the possible CPU set from the device tree and build the
  * cpu logical map array containing MPIDR values related to logical
@@ -463,32 +464,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 	}
 }
 
+static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
 
 void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
 {
-	smp_cross_call = fn;
+	__smp_cross_call = fn;
 }
 
-void arch_send_call_function_ipi_mask(const struct cpumask *mask)
-{
-	smp_cross_call(mask, IPI_CALL_FUNC);
-}
-
-void arch_send_call_function_single_ipi(int cpu)
-{
-	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
-}
-
-#ifdef CONFIG_IRQ_WORK
-void arch_irq_work_raise(void)
-{
-	if (smp_cross_call)
-		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
-}
-#endif
-
-static const char *ipi_types[NR_IPI] = {
-#define S(x,s)	[x - IPI_RESCHEDULE] = s
+static const char *ipi_types[NR_IPI] __tracepoint_string = {
+#define S(x,s)	[x] = s
 	S(IPI_RESCHEDULE, "Rescheduling interrupts"),
 	S(IPI_CALL_FUNC, "Function call interrupts"),
 	S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
@@ -497,12 +481,18 @@ static const char *ipi_types[NR_IPI] = {
 	S(IPI_IRQ_WORK, "IRQ work interrupts"),
 };
 
+static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
+{
+	trace_ipi_raise(target, ipi_types[ipinr]);
+	__smp_cross_call(target, ipinr);
+}
+
 void show_ipi_list(struct seq_file *p, int prec)
 {
 	unsigned int cpu, i;
 
 	for (i = 0; i < NR_IPI; i++) {
-		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i + IPI_RESCHEDULE,
+		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
 			   prec >= 4 ? " " : "");
 		for_each_online_cpu(cpu)
 			seq_printf(p, "%10u ",
@@ -522,6 +512,24 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
 	return sum;
 }
 
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
+{
+	smp_cross_call(mask, IPI_CALL_FUNC);
+}
+
+void arch_send_call_function_single_ipi(int cpu)
+{
+	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+}
+
+#ifdef CONFIG_IRQ_WORK
+void arch_irq_work_raise(void)
+{
+	if (__smp_cross_call)
+		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
+}
+#endif
+
 static DEFINE_RAW_SPINLOCK(stop_lock);
 
 /*
@@ -553,8 +561,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
 	unsigned int cpu = smp_processor_id();
 	struct pt_regs *old_regs = set_irq_regs(regs);
 
-	if (ipinr >= IPI_RESCHEDULE && ipinr < IPI_RESCHEDULE + NR_IPI)
-		__inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_RESCHEDULE]);
+	if ((unsigned)ipinr < NR_IPI) {
+		trace_ipi_entry(ipi_types[ipinr]);
+		__inc_irq_stat(cpu, ipi_irqs[ipinr]);
+	}
 
 	switch (ipinr) {
 	case IPI_RESCHEDULE:
@@ -599,6 +609,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
 		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
 		break;
 	}
+
+	if ((unsigned)ipinr < NR_IPI)
+		trace_ipi_exit(ipi_types[ipinr]);
 	set_irq_regs(old_regs);
 }
 
-- 
1.8.4.108.g55ea5f6


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

* [PATCH v2 4/5] ARM64: add IPI tracepoints
@ 2014-07-25 20:05   ` Nicolas Pitre
  0 siblings, 0 replies; 30+ messages in thread
From: Nicolas Pitre @ 2014-07-25 20:05 UTC (permalink / raw)
  To: linux-arm-kernel

The strings used to list IPIs in /proc/interrupts are reused for tracing
purposes.

While at it, the code is slightly cleaned up so the ipi_types array
indices are no longer offset by IPI_RESCHEDULE whose value is 0 anyway.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/kernel/smp.c | 65 +++++++++++++++++++++++++++++--------------------
 1 file changed, 39 insertions(+), 26 deletions(-)

diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 40f38f46c8..a89c66f3b4 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -50,6 +50,9 @@
 #include <asm/tlbflush.h>
 #include <asm/ptrace.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/ipi.h>
+
 /*
  * as from 2.5, kernels no longer have an init_tasks structure
  * so we need some other way of telling a new secondary core
@@ -307,8 +310,6 @@ void __init smp_prepare_boot_cpu(void)
 	set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
 }
 
-static void (*smp_cross_call)(const struct cpumask *, unsigned int);
-
 /*
  * Enumerate the possible CPU set from the device tree and build the
  * cpu logical map array containing MPIDR values related to logical
@@ -463,32 +464,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 	}
 }
 
+static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
 
 void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
 {
-	smp_cross_call = fn;
+	__smp_cross_call = fn;
 }
 
-void arch_send_call_function_ipi_mask(const struct cpumask *mask)
-{
-	smp_cross_call(mask, IPI_CALL_FUNC);
-}
-
-void arch_send_call_function_single_ipi(int cpu)
-{
-	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
-}
-
-#ifdef CONFIG_IRQ_WORK
-void arch_irq_work_raise(void)
-{
-	if (smp_cross_call)
-		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
-}
-#endif
-
-static const char *ipi_types[NR_IPI] = {
-#define S(x,s)	[x - IPI_RESCHEDULE] = s
+static const char *ipi_types[NR_IPI] __tracepoint_string = {
+#define S(x,s)	[x] = s
 	S(IPI_RESCHEDULE, "Rescheduling interrupts"),
 	S(IPI_CALL_FUNC, "Function call interrupts"),
 	S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
@@ -497,12 +481,18 @@ static const char *ipi_types[NR_IPI] = {
 	S(IPI_IRQ_WORK, "IRQ work interrupts"),
 };
 
+static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
+{
+	trace_ipi_raise(target, ipi_types[ipinr]);
+	__smp_cross_call(target, ipinr);
+}
+
 void show_ipi_list(struct seq_file *p, int prec)
 {
 	unsigned int cpu, i;
 
 	for (i = 0; i < NR_IPI; i++) {
-		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i + IPI_RESCHEDULE,
+		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
 			   prec >= 4 ? " " : "");
 		for_each_online_cpu(cpu)
 			seq_printf(p, "%10u ",
@@ -522,6 +512,24 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
 	return sum;
 }
 
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
+{
+	smp_cross_call(mask, IPI_CALL_FUNC);
+}
+
+void arch_send_call_function_single_ipi(int cpu)
+{
+	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+}
+
+#ifdef CONFIG_IRQ_WORK
+void arch_irq_work_raise(void)
+{
+	if (__smp_cross_call)
+		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
+}
+#endif
+
 static DEFINE_RAW_SPINLOCK(stop_lock);
 
 /*
@@ -553,8 +561,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
 	unsigned int cpu = smp_processor_id();
 	struct pt_regs *old_regs = set_irq_regs(regs);
 
-	if (ipinr >= IPI_RESCHEDULE && ipinr < IPI_RESCHEDULE + NR_IPI)
-		__inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_RESCHEDULE]);
+	if ((unsigned)ipinr < NR_IPI) {
+		trace_ipi_entry(ipi_types[ipinr]);
+		__inc_irq_stat(cpu, ipi_irqs[ipinr]);
+	}
 
 	switch (ipinr) {
 	case IPI_RESCHEDULE:
@@ -599,6 +609,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
 		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
 		break;
 	}
+
+	if ((unsigned)ipinr < NR_IPI)
+		trace_ipi_exit(ipi_types[ipinr]);
 	set_irq_regs(old_regs);
 }
 
-- 
1.8.4.108.g55ea5f6

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

* [PATCH v2 5/5] X86: add IPI tracepoints
  2014-07-25 20:05 ` Nicolas Pitre
@ 2014-07-25 20:05   ` Nicolas Pitre
  -1 siblings, 0 replies; 30+ messages in thread
From: Nicolas Pitre @ 2014-07-25 20:05 UTC (permalink / raw)
  To: Steven Rostedt, Ingo Molnar
  Cc: Daniel Lezcano, Russell King - ARM Linux, Catalin Marinas,
	linux-kernel, linux-arm-kernel, linaro-kernel

On X86 there are already tracepoints for IRQ vectors through which IPIs
are handled.  However this is highly X86 specific, and the IPI signaling
is not currently traced.

This is an attempt at adding generic IPI tracepoints to X86.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
---
 arch/x86/kernel/smp.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index be8e1bde07..d193609bea 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -31,6 +31,16 @@
 #include <asm/apic.h>
 #include <asm/nmi.h>
 #include <asm/trace/irq_vectors.h>
+
+#define CREATE_TRACE_POINTS
+/*
+ * Those were defined in <asm/trace/irq_vectors.h> and cause problems
+ * when including <trace/events/ipi.h>.
+ */
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#include <trace/events/ipi.h>
+
 /*
  *	Some notes on x86 processor bugs affecting SMP operation:
  *
@@ -124,11 +134,13 @@ static void native_smp_send_reschedule(int cpu)
 		WARN_ON(1);
 		return;
 	}
+	trace_ipi_raise(cpumask_of(cpu), tracepoint_string("RESCHEDULE"));
 	apic->send_IPI_mask(cpumask_of(cpu), RESCHEDULE_VECTOR);
 }
 
 void native_send_call_func_single_ipi(int cpu)
 {
+	trace_ipi_raise(cpumask_of(cpu), tracepoint_string("CALL_FUNCTION_SINGLE"));
 	apic->send_IPI_mask(cpumask_of(cpu), CALL_FUNCTION_SINGLE_VECTOR);
 }
 
@@ -136,6 +148,8 @@ void native_send_call_func_ipi(const struct cpumask *mask)
 {
 	cpumask_var_t allbutself;
 
+	trace_ipi_raise(mask, tracepoint_string("CALL_FUNCTION"));
+
 	if (!alloc_cpumask_var(&allbutself, GFP_ATOMIC)) {
 		apic->send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
 		return;
@@ -252,8 +266,10 @@ finish:
  */
 static inline void __smp_reschedule_interrupt(void)
 {
+	trace_ipi_entry(tracepoint_string("RESCHEDULE"));
 	inc_irq_stat(irq_resched_count);
 	scheduler_ipi();
+	trace_ipi_exit(tracepoint_string("RESCHEDULE"));
 }
 
 __visible void smp_reschedule_interrupt(struct pt_regs *regs)
@@ -291,8 +307,10 @@ __visible void smp_trace_reschedule_interrupt(struct pt_regs *regs)
 
 static inline void __smp_call_function_interrupt(void)
 {
+	trace_ipi_entry(tracepoint_string("CALL_FUNCTION"));
 	generic_smp_call_function_interrupt();
 	inc_irq_stat(irq_call_count);
+	trace_ipi_exit(tracepoint_string("CALL_FUNCTION"));
 }
 
 __visible void smp_call_function_interrupt(struct pt_regs *regs)
@@ -313,8 +331,10 @@ __visible void smp_trace_call_function_interrupt(struct pt_regs *regs)
 
 static inline void __smp_call_function_single_interrupt(void)
 {
+	trace_ipi_entry(tracepoint_string("CALL_FUNCTION_SINGLE"));
 	generic_smp_call_function_single_interrupt();
 	inc_irq_stat(irq_call_count);
+	trace_ipi_exit(tracepoint_string("CALL_FUNCTION_SINGLE"));
 }
 
 __visible void smp_call_function_single_interrupt(struct pt_regs *regs)
-- 
1.8.4.108.g55ea5f6


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

* [PATCH v2 5/5] X86: add IPI tracepoints
@ 2014-07-25 20:05   ` Nicolas Pitre
  0 siblings, 0 replies; 30+ messages in thread
From: Nicolas Pitre @ 2014-07-25 20:05 UTC (permalink / raw)
  To: linux-arm-kernel

On X86 there are already tracepoints for IRQ vectors through which IPIs
are handled.  However this is highly X86 specific, and the IPI signaling
is not currently traced.

This is an attempt at adding generic IPI tracepoints to X86.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
---
 arch/x86/kernel/smp.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index be8e1bde07..d193609bea 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -31,6 +31,16 @@
 #include <asm/apic.h>
 #include <asm/nmi.h>
 #include <asm/trace/irq_vectors.h>
+
+#define CREATE_TRACE_POINTS
+/*
+ * Those were defined in <asm/trace/irq_vectors.h> and cause problems
+ * when including <trace/events/ipi.h>.
+ */
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#include <trace/events/ipi.h>
+
 /*
  *	Some notes on x86 processor bugs affecting SMP operation:
  *
@@ -124,11 +134,13 @@ static void native_smp_send_reschedule(int cpu)
 		WARN_ON(1);
 		return;
 	}
+	trace_ipi_raise(cpumask_of(cpu), tracepoint_string("RESCHEDULE"));
 	apic->send_IPI_mask(cpumask_of(cpu), RESCHEDULE_VECTOR);
 }
 
 void native_send_call_func_single_ipi(int cpu)
 {
+	trace_ipi_raise(cpumask_of(cpu), tracepoint_string("CALL_FUNCTION_SINGLE"));
 	apic->send_IPI_mask(cpumask_of(cpu), CALL_FUNCTION_SINGLE_VECTOR);
 }
 
@@ -136,6 +148,8 @@ void native_send_call_func_ipi(const struct cpumask *mask)
 {
 	cpumask_var_t allbutself;
 
+	trace_ipi_raise(mask, tracepoint_string("CALL_FUNCTION"));
+
 	if (!alloc_cpumask_var(&allbutself, GFP_ATOMIC)) {
 		apic->send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
 		return;
@@ -252,8 +266,10 @@ finish:
  */
 static inline void __smp_reschedule_interrupt(void)
 {
+	trace_ipi_entry(tracepoint_string("RESCHEDULE"));
 	inc_irq_stat(irq_resched_count);
 	scheduler_ipi();
+	trace_ipi_exit(tracepoint_string("RESCHEDULE"));
 }
 
 __visible void smp_reschedule_interrupt(struct pt_regs *regs)
@@ -291,8 +307,10 @@ __visible void smp_trace_reschedule_interrupt(struct pt_regs *regs)
 
 static inline void __smp_call_function_interrupt(void)
 {
+	trace_ipi_entry(tracepoint_string("CALL_FUNCTION"));
 	generic_smp_call_function_interrupt();
 	inc_irq_stat(irq_call_count);
+	trace_ipi_exit(tracepoint_string("CALL_FUNCTION"));
 }
 
 __visible void smp_call_function_interrupt(struct pt_regs *regs)
@@ -313,8 +331,10 @@ __visible void smp_trace_call_function_interrupt(struct pt_regs *regs)
 
 static inline void __smp_call_function_single_interrupt(void)
 {
+	trace_ipi_entry(tracepoint_string("CALL_FUNCTION_SINGLE"));
 	generic_smp_call_function_single_interrupt();
 	inc_irq_stat(irq_call_count);
+	trace_ipi_exit(tracepoint_string("CALL_FUNCTION_SINGLE"));
 }
 
 __visible void smp_call_function_single_interrupt(struct pt_regs *regs)
-- 
1.8.4.108.g55ea5f6

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

* Re: [PATCH v2 3/5] ARM: add IPI tracepoints
  2014-07-25 20:05   ` Nicolas Pitre
@ 2014-07-28  5:34     ` Daniel Lezcano
  -1 siblings, 0 replies; 30+ messages in thread
From: Daniel Lezcano @ 2014-07-28  5:34 UTC (permalink / raw)
  To: Nicolas Pitre, Steven Rostedt, Ingo Molnar
  Cc: Russell King - ARM Linux, Catalin Marinas, linux-kernel,
	linux-arm-kernel, linaro-kernel

On 07/25/2014 10:05 PM, Nicolas Pitre wrote:
> The strings used to list IPIs in /proc/interrupts are reused for tracing
> purposes.
>
> While at it, prevent a negative ipinr from escaping the range check
> in handle_IPI().
>
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> Acked-by: Steven Rostedt <rostedt@goodmis.org>

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

> ---
>   arch/arm/kernel/smp.c | 70 ++++++++++++++++++++++++++++++---------------------
>   1 file changed, 42 insertions(+), 28 deletions(-)
>
> diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
> index 7c4fada440..9388a3d479 100644
> --- a/arch/arm/kernel/smp.c
> +++ b/arch/arm/kernel/smp.c
> @@ -47,6 +47,9 @@
>   #include <asm/mach/arch.h>
>   #include <asm/mpu.h>
>
> +#define CREATE_TRACE_POINTS
> +#include <trace/events/ipi.h>
> +
>   /*
>    * as from 2.5, kernels no longer have an init_tasks structure
>    * so we need some other way of telling a new secondary core
> @@ -430,38 +433,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>   	}
>   }
>
> -static void (*smp_cross_call)(const struct cpumask *, unsigned int);
> +static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
>
>   void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
>   {
> -	if (!smp_cross_call)
> -		smp_cross_call = fn;
> -}
> -
> -void arch_send_call_function_ipi_mask(const struct cpumask *mask)
> -{
> -	smp_cross_call(mask, IPI_CALL_FUNC);
> -}
> -
> -void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
> -{
> -	smp_cross_call(mask, IPI_WAKEUP);
> -}
> -
> -void arch_send_call_function_single_ipi(int cpu)
> -{
> -	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
> +	if (!__smp_cross_call)
> +		__smp_cross_call = fn;
>   }
>
> -#ifdef CONFIG_IRQ_WORK
> -void arch_irq_work_raise(void)
> -{
> -	if (is_smp())
> -		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
> -}
> -#endif
> -
> -static const char *ipi_types[NR_IPI] = {
> +static const char *ipi_types[NR_IPI] __tracepoint_string = {
>   #define S(x,s)	[x] = s
>   	S(IPI_WAKEUP, "CPU wakeup interrupts"),
>   	S(IPI_TIMER, "Timer broadcast interrupts"),
> @@ -473,6 +453,12 @@ static const char *ipi_types[NR_IPI] = {
>   	S(IPI_COMPLETION, "completion interrupts"),
>   };
>
> +static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
> +{
> +	trace_ipi_raise(target, ipi_types[ipinr]);
> +	__smp_cross_call(target, ipinr);
> +}
> +
>   void show_ipi_list(struct seq_file *p, int prec)
>   {
>   	unsigned int cpu, i;
> @@ -499,6 +485,29 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
>   	return sum;
>   }
>
> +void arch_send_call_function_ipi_mask(const struct cpumask *mask)
> +{
> +	smp_cross_call(mask, IPI_CALL_FUNC);
> +}
> +
> +void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
> +{
> +	smp_cross_call(mask, IPI_WAKEUP);
> +}
> +
> +void arch_send_call_function_single_ipi(int cpu)
> +{
> +	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
> +}
> +
> +#ifdef CONFIG_IRQ_WORK
> +void arch_irq_work_raise(void)
> +{
> +	if (is_smp())
> +		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
> +}
> +#endif
> +
>   #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
>   void tick_broadcast(const struct cpumask *mask)
>   {
> @@ -556,8 +565,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
>   	unsigned int cpu = smp_processor_id();
>   	struct pt_regs *old_regs = set_irq_regs(regs);
>
> -	if (ipinr < NR_IPI)
> +	if ((unsigned)ipinr < NR_IPI) {
> +		trace_ipi_entry(ipi_types[ipinr]);
>   		__inc_irq_stat(cpu, ipi_irqs[ipinr]);
> +	}
>
>   	switch (ipinr) {
>   	case IPI_WAKEUP:
> @@ -612,6 +623,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
>   		       cpu, ipinr);
>   		break;
>   	}
> +
> +	if ((unsigned)ipinr < NR_IPI)
> +		trace_ipi_exit(ipi_types[ipinr]);
>   	set_irq_regs(old_regs);
>   }
>
>


-- 
  <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


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

* [PATCH v2 3/5] ARM: add IPI tracepoints
@ 2014-07-28  5:34     ` Daniel Lezcano
  0 siblings, 0 replies; 30+ messages in thread
From: Daniel Lezcano @ 2014-07-28  5:34 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/25/2014 10:05 PM, Nicolas Pitre wrote:
> The strings used to list IPIs in /proc/interrupts are reused for tracing
> purposes.
>
> While at it, prevent a negative ipinr from escaping the range check
> in handle_IPI().
>
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> Acked-by: Steven Rostedt <rostedt@goodmis.org>

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>

> ---
>   arch/arm/kernel/smp.c | 70 ++++++++++++++++++++++++++++++---------------------
>   1 file changed, 42 insertions(+), 28 deletions(-)
>
> diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
> index 7c4fada440..9388a3d479 100644
> --- a/arch/arm/kernel/smp.c
> +++ b/arch/arm/kernel/smp.c
> @@ -47,6 +47,9 @@
>   #include <asm/mach/arch.h>
>   #include <asm/mpu.h>
>
> +#define CREATE_TRACE_POINTS
> +#include <trace/events/ipi.h>
> +
>   /*
>    * as from 2.5, kernels no longer have an init_tasks structure
>    * so we need some other way of telling a new secondary core
> @@ -430,38 +433,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>   	}
>   }
>
> -static void (*smp_cross_call)(const struct cpumask *, unsigned int);
> +static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
>
>   void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
>   {
> -	if (!smp_cross_call)
> -		smp_cross_call = fn;
> -}
> -
> -void arch_send_call_function_ipi_mask(const struct cpumask *mask)
> -{
> -	smp_cross_call(mask, IPI_CALL_FUNC);
> -}
> -
> -void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
> -{
> -	smp_cross_call(mask, IPI_WAKEUP);
> -}
> -
> -void arch_send_call_function_single_ipi(int cpu)
> -{
> -	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
> +	if (!__smp_cross_call)
> +		__smp_cross_call = fn;
>   }
>
> -#ifdef CONFIG_IRQ_WORK
> -void arch_irq_work_raise(void)
> -{
> -	if (is_smp())
> -		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
> -}
> -#endif
> -
> -static const char *ipi_types[NR_IPI] = {
> +static const char *ipi_types[NR_IPI] __tracepoint_string = {
>   #define S(x,s)	[x] = s
>   	S(IPI_WAKEUP, "CPU wakeup interrupts"),
>   	S(IPI_TIMER, "Timer broadcast interrupts"),
> @@ -473,6 +453,12 @@ static const char *ipi_types[NR_IPI] = {
>   	S(IPI_COMPLETION, "completion interrupts"),
>   };
>
> +static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
> +{
> +	trace_ipi_raise(target, ipi_types[ipinr]);
> +	__smp_cross_call(target, ipinr);
> +}
> +
>   void show_ipi_list(struct seq_file *p, int prec)
>   {
>   	unsigned int cpu, i;
> @@ -499,6 +485,29 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
>   	return sum;
>   }
>
> +void arch_send_call_function_ipi_mask(const struct cpumask *mask)
> +{
> +	smp_cross_call(mask, IPI_CALL_FUNC);
> +}
> +
> +void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
> +{
> +	smp_cross_call(mask, IPI_WAKEUP);
> +}
> +
> +void arch_send_call_function_single_ipi(int cpu)
> +{
> +	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
> +}
> +
> +#ifdef CONFIG_IRQ_WORK
> +void arch_irq_work_raise(void)
> +{
> +	if (is_smp())
> +		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
> +}
> +#endif
> +
>   #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
>   void tick_broadcast(const struct cpumask *mask)
>   {
> @@ -556,8 +565,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
>   	unsigned int cpu = smp_processor_id();
>   	struct pt_regs *old_regs = set_irq_regs(regs);
>
> -	if (ipinr < NR_IPI)
> +	if ((unsigned)ipinr < NR_IPI) {
> +		trace_ipi_entry(ipi_types[ipinr]);
>   		__inc_irq_stat(cpu, ipi_irqs[ipinr]);
> +	}
>
>   	switch (ipinr) {
>   	case IPI_WAKEUP:
> @@ -612,6 +623,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
>   		       cpu, ipinr);
>   		break;
>   	}
> +
> +	if ((unsigned)ipinr < NR_IPI)
> +		trace_ipi_exit(ipi_types[ipinr]);
>   	set_irq_regs(old_regs);
>   }
>
>


-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

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

* Re: [PATCH v2 3/5] ARM: add IPI tracepoints
  2014-07-25 20:05   ` Nicolas Pitre
@ 2014-08-06 19:51     ` Steven Rostedt
  -1 siblings, 0 replies; 30+ messages in thread
From: Steven Rostedt @ 2014-08-06 19:51 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Nicolas Pitre, Ingo Molnar, Daniel Lezcano, Catalin Marinas,
	linux-kernel, linux-arm-kernel, linaro-kernel

Russell,

Can you give me your Acked-by for this, and I can pull it through my
tree?

Thanks,

-- Steve


On Fri, 25 Jul 2014 16:05:31 -0400
Nicolas Pitre <nicolas.pitre@linaro.org> wrote:

> The strings used to list IPIs in /proc/interrupts are reused for tracing
> purposes.
> 
> While at it, prevent a negative ipinr from escaping the range check
> in handle_IPI().
> 
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> Acked-by: Steven Rostedt <rostedt@goodmis.org>
> ---
>  arch/arm/kernel/smp.c | 70 ++++++++++++++++++++++++++++++---------------------
>  1 file changed, 42 insertions(+), 28 deletions(-)
> 
> diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
> index 7c4fada440..9388a3d479 100644
> --- a/arch/arm/kernel/smp.c
> +++ b/arch/arm/kernel/smp.c
> @@ -47,6 +47,9 @@
>  #include <asm/mach/arch.h>
>  #include <asm/mpu.h>
>  
> +#define CREATE_TRACE_POINTS
> +#include <trace/events/ipi.h>
> +
>  /*
>   * as from 2.5, kernels no longer have an init_tasks structure
>   * so we need some other way of telling a new secondary core
> @@ -430,38 +433,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>  	}
>  }
>  
> -static void (*smp_cross_call)(const struct cpumask *, unsigned int);
> +static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
>  
>  void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
>  {
> -	if (!smp_cross_call)
> -		smp_cross_call = fn;
> -}
> -
> -void arch_send_call_function_ipi_mask(const struct cpumask *mask)
> -{
> -	smp_cross_call(mask, IPI_CALL_FUNC);
> -}
> -
> -void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
> -{
> -	smp_cross_call(mask, IPI_WAKEUP);
> -}
> -
> -void arch_send_call_function_single_ipi(int cpu)
> -{
> -	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
> +	if (!__smp_cross_call)
> +		__smp_cross_call = fn;
>  }
>  
> -#ifdef CONFIG_IRQ_WORK
> -void arch_irq_work_raise(void)
> -{
> -	if (is_smp())
> -		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
> -}
> -#endif
> -
> -static const char *ipi_types[NR_IPI] = {
> +static const char *ipi_types[NR_IPI] __tracepoint_string = {
>  #define S(x,s)	[x] = s
>  	S(IPI_WAKEUP, "CPU wakeup interrupts"),
>  	S(IPI_TIMER, "Timer broadcast interrupts"),
> @@ -473,6 +453,12 @@ static const char *ipi_types[NR_IPI] = {
>  	S(IPI_COMPLETION, "completion interrupts"),
>  };
>  
> +static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
> +{
> +	trace_ipi_raise(target, ipi_types[ipinr]);
> +	__smp_cross_call(target, ipinr);
> +}
> +
>  void show_ipi_list(struct seq_file *p, int prec)
>  {
>  	unsigned int cpu, i;
> @@ -499,6 +485,29 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
>  	return sum;
>  }
>  
> +void arch_send_call_function_ipi_mask(const struct cpumask *mask)
> +{
> +	smp_cross_call(mask, IPI_CALL_FUNC);
> +}
> +
> +void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
> +{
> +	smp_cross_call(mask, IPI_WAKEUP);
> +}
> +
> +void arch_send_call_function_single_ipi(int cpu)
> +{
> +	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
> +}
> +
> +#ifdef CONFIG_IRQ_WORK
> +void arch_irq_work_raise(void)
> +{
> +	if (is_smp())
> +		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
> +}
> +#endif
> +
>  #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
>  void tick_broadcast(const struct cpumask *mask)
>  {
> @@ -556,8 +565,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
>  	unsigned int cpu = smp_processor_id();
>  	struct pt_regs *old_regs = set_irq_regs(regs);
>  
> -	if (ipinr < NR_IPI)
> +	if ((unsigned)ipinr < NR_IPI) {
> +		trace_ipi_entry(ipi_types[ipinr]);
>  		__inc_irq_stat(cpu, ipi_irqs[ipinr]);
> +	}
>  
>  	switch (ipinr) {
>  	case IPI_WAKEUP:
> @@ -612,6 +623,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
>  		       cpu, ipinr);
>  		break;
>  	}
> +
> +	if ((unsigned)ipinr < NR_IPI)
> +		trace_ipi_exit(ipi_types[ipinr]);
>  	set_irq_regs(old_regs);
>  }
>  


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

* [PATCH v2 3/5] ARM: add IPI tracepoints
@ 2014-08-06 19:51     ` Steven Rostedt
  0 siblings, 0 replies; 30+ messages in thread
From: Steven Rostedt @ 2014-08-06 19:51 UTC (permalink / raw)
  To: linux-arm-kernel

Russell,

Can you give me your Acked-by for this, and I can pull it through my
tree?

Thanks,

-- Steve


On Fri, 25 Jul 2014 16:05:31 -0400
Nicolas Pitre <nicolas.pitre@linaro.org> wrote:

> The strings used to list IPIs in /proc/interrupts are reused for tracing
> purposes.
> 
> While at it, prevent a negative ipinr from escaping the range check
> in handle_IPI().
> 
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> Acked-by: Steven Rostedt <rostedt@goodmis.org>
> ---
>  arch/arm/kernel/smp.c | 70 ++++++++++++++++++++++++++++++---------------------
>  1 file changed, 42 insertions(+), 28 deletions(-)
> 
> diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
> index 7c4fada440..9388a3d479 100644
> --- a/arch/arm/kernel/smp.c
> +++ b/arch/arm/kernel/smp.c
> @@ -47,6 +47,9 @@
>  #include <asm/mach/arch.h>
>  #include <asm/mpu.h>
>  
> +#define CREATE_TRACE_POINTS
> +#include <trace/events/ipi.h>
> +
>  /*
>   * as from 2.5, kernels no longer have an init_tasks structure
>   * so we need some other way of telling a new secondary core
> @@ -430,38 +433,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>  	}
>  }
>  
> -static void (*smp_cross_call)(const struct cpumask *, unsigned int);
> +static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
>  
>  void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
>  {
> -	if (!smp_cross_call)
> -		smp_cross_call = fn;
> -}
> -
> -void arch_send_call_function_ipi_mask(const struct cpumask *mask)
> -{
> -	smp_cross_call(mask, IPI_CALL_FUNC);
> -}
> -
> -void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
> -{
> -	smp_cross_call(mask, IPI_WAKEUP);
> -}
> -
> -void arch_send_call_function_single_ipi(int cpu)
> -{
> -	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
> +	if (!__smp_cross_call)
> +		__smp_cross_call = fn;
>  }
>  
> -#ifdef CONFIG_IRQ_WORK
> -void arch_irq_work_raise(void)
> -{
> -	if (is_smp())
> -		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
> -}
> -#endif
> -
> -static const char *ipi_types[NR_IPI] = {
> +static const char *ipi_types[NR_IPI] __tracepoint_string = {
>  #define S(x,s)	[x] = s
>  	S(IPI_WAKEUP, "CPU wakeup interrupts"),
>  	S(IPI_TIMER, "Timer broadcast interrupts"),
> @@ -473,6 +453,12 @@ static const char *ipi_types[NR_IPI] = {
>  	S(IPI_COMPLETION, "completion interrupts"),
>  };
>  
> +static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
> +{
> +	trace_ipi_raise(target, ipi_types[ipinr]);
> +	__smp_cross_call(target, ipinr);
> +}
> +
>  void show_ipi_list(struct seq_file *p, int prec)
>  {
>  	unsigned int cpu, i;
> @@ -499,6 +485,29 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
>  	return sum;
>  }
>  
> +void arch_send_call_function_ipi_mask(const struct cpumask *mask)
> +{
> +	smp_cross_call(mask, IPI_CALL_FUNC);
> +}
> +
> +void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
> +{
> +	smp_cross_call(mask, IPI_WAKEUP);
> +}
> +
> +void arch_send_call_function_single_ipi(int cpu)
> +{
> +	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
> +}
> +
> +#ifdef CONFIG_IRQ_WORK
> +void arch_irq_work_raise(void)
> +{
> +	if (is_smp())
> +		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
> +}
> +#endif
> +
>  #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
>  void tick_broadcast(const struct cpumask *mask)
>  {
> @@ -556,8 +565,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
>  	unsigned int cpu = smp_processor_id();
>  	struct pt_regs *old_regs = set_irq_regs(regs);
>  
> -	if (ipinr < NR_IPI)
> +	if ((unsigned)ipinr < NR_IPI) {
> +		trace_ipi_entry(ipi_types[ipinr]);
>  		__inc_irq_stat(cpu, ipi_irqs[ipinr]);
> +	}
>  
>  	switch (ipinr) {
>  	case IPI_WAKEUP:
> @@ -612,6 +623,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
>  		       cpu, ipinr);
>  		break;
>  	}
> +
> +	if ((unsigned)ipinr < NR_IPI)
> +		trace_ipi_exit(ipi_types[ipinr]);
>  	set_irq_regs(old_regs);
>  }
>  

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

* Re: [PATCH v2 4/5] ARM64: add IPI tracepoints
  2014-07-25 20:05   ` Nicolas Pitre
@ 2014-08-06 19:52     ` Steven Rostedt
  -1 siblings, 0 replies; 30+ messages in thread
From: Steven Rostedt @ 2014-08-06 19:52 UTC (permalink / raw)
  To: Russell King - ARM Linux, Will Deacon
  Cc: Nicolas Pitre, Ingo Molnar, Daniel Lezcano, Catalin Marinas,
	linux-kernel, linux-arm-kernel, linaro-kernel

Will and Russell,

Can you give me your Acked-by for this, and I can pull it through my
tree?

Thanks,

-- Steve


On Fri, 25 Jul 2014 16:05:32 -0400
Nicolas Pitre <nicolas.pitre@linaro.org> wrote:

> The strings used to list IPIs in /proc/interrupts are reused for tracing
> purposes.
> 
> While at it, the code is slightly cleaned up so the ipi_types array
> indices are no longer offset by IPI_RESCHEDULE whose value is 0 anyway.
> 
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> Acked-by: Steven Rostedt <rostedt@goodmis.org>
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> ---
>  arch/arm64/kernel/smp.c | 65 +++++++++++++++++++++++++++++--------------------
>  1 file changed, 39 insertions(+), 26 deletions(-)
> 
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 40f38f46c8..a89c66f3b4 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -50,6 +50,9 @@
>  #include <asm/tlbflush.h>
>  #include <asm/ptrace.h>
>  
> +#define CREATE_TRACE_POINTS
> +#include <trace/events/ipi.h>
> +
>  /*
>   * as from 2.5, kernels no longer have an init_tasks structure
>   * so we need some other way of telling a new secondary core
> @@ -307,8 +310,6 @@ void __init smp_prepare_boot_cpu(void)
>  	set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
>  }
>  
> -static void (*smp_cross_call)(const struct cpumask *, unsigned int);
> -
>  /*
>   * Enumerate the possible CPU set from the device tree and build the
>   * cpu logical map array containing MPIDR values related to logical
> @@ -463,32 +464,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>  	}
>  }
>  
> +static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
>  
>  void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
>  {
> -	smp_cross_call = fn;
> +	__smp_cross_call = fn;
>  }
>  
> -void arch_send_call_function_ipi_mask(const struct cpumask *mask)
> -{
> -	smp_cross_call(mask, IPI_CALL_FUNC);
> -}
> -
> -void arch_send_call_function_single_ipi(int cpu)
> -{
> -	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
> -}
> -
> -#ifdef CONFIG_IRQ_WORK
> -void arch_irq_work_raise(void)
> -{
> -	if (smp_cross_call)
> -		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
> -}
> -#endif
> -
> -static const char *ipi_types[NR_IPI] = {
> -#define S(x,s)	[x - IPI_RESCHEDULE] = s
> +static const char *ipi_types[NR_IPI] __tracepoint_string = {
> +#define S(x,s)	[x] = s
>  	S(IPI_RESCHEDULE, "Rescheduling interrupts"),
>  	S(IPI_CALL_FUNC, "Function call interrupts"),
>  	S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
> @@ -497,12 +481,18 @@ static const char *ipi_types[NR_IPI] = {
>  	S(IPI_IRQ_WORK, "IRQ work interrupts"),
>  };
>  
> +static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
> +{
> +	trace_ipi_raise(target, ipi_types[ipinr]);
> +	__smp_cross_call(target, ipinr);
> +}
> +
>  void show_ipi_list(struct seq_file *p, int prec)
>  {
>  	unsigned int cpu, i;
>  
>  	for (i = 0; i < NR_IPI; i++) {
> -		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i + IPI_RESCHEDULE,
> +		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
>  			   prec >= 4 ? " " : "");
>  		for_each_online_cpu(cpu)
>  			seq_printf(p, "%10u ",
> @@ -522,6 +512,24 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
>  	return sum;
>  }
>  
> +void arch_send_call_function_ipi_mask(const struct cpumask *mask)
> +{
> +	smp_cross_call(mask, IPI_CALL_FUNC);
> +}
> +
> +void arch_send_call_function_single_ipi(int cpu)
> +{
> +	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
> +}
> +
> +#ifdef CONFIG_IRQ_WORK
> +void arch_irq_work_raise(void)
> +{
> +	if (__smp_cross_call)
> +		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
> +}
> +#endif
> +
>  static DEFINE_RAW_SPINLOCK(stop_lock);
>  
>  /*
> @@ -553,8 +561,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
>  	unsigned int cpu = smp_processor_id();
>  	struct pt_regs *old_regs = set_irq_regs(regs);
>  
> -	if (ipinr >= IPI_RESCHEDULE && ipinr < IPI_RESCHEDULE + NR_IPI)
> -		__inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_RESCHEDULE]);
> +	if ((unsigned)ipinr < NR_IPI) {
> +		trace_ipi_entry(ipi_types[ipinr]);
> +		__inc_irq_stat(cpu, ipi_irqs[ipinr]);
> +	}
>  
>  	switch (ipinr) {
>  	case IPI_RESCHEDULE:
> @@ -599,6 +609,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
>  		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
>  		break;
>  	}
> +
> +	if ((unsigned)ipinr < NR_IPI)
> +		trace_ipi_exit(ipi_types[ipinr]);
>  	set_irq_regs(old_regs);
>  }
>  


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

* [PATCH v2 4/5] ARM64: add IPI tracepoints
@ 2014-08-06 19:52     ` Steven Rostedt
  0 siblings, 0 replies; 30+ messages in thread
From: Steven Rostedt @ 2014-08-06 19:52 UTC (permalink / raw)
  To: linux-arm-kernel

Will and Russell,

Can you give me your Acked-by for this, and I can pull it through my
tree?

Thanks,

-- Steve


On Fri, 25 Jul 2014 16:05:32 -0400
Nicolas Pitre <nicolas.pitre@linaro.org> wrote:

> The strings used to list IPIs in /proc/interrupts are reused for tracing
> purposes.
> 
> While at it, the code is slightly cleaned up so the ipi_types array
> indices are no longer offset by IPI_RESCHEDULE whose value is 0 anyway.
> 
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> Acked-by: Steven Rostedt <rostedt@goodmis.org>
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> ---
>  arch/arm64/kernel/smp.c | 65 +++++++++++++++++++++++++++++--------------------
>  1 file changed, 39 insertions(+), 26 deletions(-)
> 
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 40f38f46c8..a89c66f3b4 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -50,6 +50,9 @@
>  #include <asm/tlbflush.h>
>  #include <asm/ptrace.h>
>  
> +#define CREATE_TRACE_POINTS
> +#include <trace/events/ipi.h>
> +
>  /*
>   * as from 2.5, kernels no longer have an init_tasks structure
>   * so we need some other way of telling a new secondary core
> @@ -307,8 +310,6 @@ void __init smp_prepare_boot_cpu(void)
>  	set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
>  }
>  
> -static void (*smp_cross_call)(const struct cpumask *, unsigned int);
> -
>  /*
>   * Enumerate the possible CPU set from the device tree and build the
>   * cpu logical map array containing MPIDR values related to logical
> @@ -463,32 +464,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
>  	}
>  }
>  
> +static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
>  
>  void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
>  {
> -	smp_cross_call = fn;
> +	__smp_cross_call = fn;
>  }
>  
> -void arch_send_call_function_ipi_mask(const struct cpumask *mask)
> -{
> -	smp_cross_call(mask, IPI_CALL_FUNC);
> -}
> -
> -void arch_send_call_function_single_ipi(int cpu)
> -{
> -	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
> -}
> -
> -#ifdef CONFIG_IRQ_WORK
> -void arch_irq_work_raise(void)
> -{
> -	if (smp_cross_call)
> -		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
> -}
> -#endif
> -
> -static const char *ipi_types[NR_IPI] = {
> -#define S(x,s)	[x - IPI_RESCHEDULE] = s
> +static const char *ipi_types[NR_IPI] __tracepoint_string = {
> +#define S(x,s)	[x] = s
>  	S(IPI_RESCHEDULE, "Rescheduling interrupts"),
>  	S(IPI_CALL_FUNC, "Function call interrupts"),
>  	S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
> @@ -497,12 +481,18 @@ static const char *ipi_types[NR_IPI] = {
>  	S(IPI_IRQ_WORK, "IRQ work interrupts"),
>  };
>  
> +static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
> +{
> +	trace_ipi_raise(target, ipi_types[ipinr]);
> +	__smp_cross_call(target, ipinr);
> +}
> +
>  void show_ipi_list(struct seq_file *p, int prec)
>  {
>  	unsigned int cpu, i;
>  
>  	for (i = 0; i < NR_IPI; i++) {
> -		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i + IPI_RESCHEDULE,
> +		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
>  			   prec >= 4 ? " " : "");
>  		for_each_online_cpu(cpu)
>  			seq_printf(p, "%10u ",
> @@ -522,6 +512,24 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
>  	return sum;
>  }
>  
> +void arch_send_call_function_ipi_mask(const struct cpumask *mask)
> +{
> +	smp_cross_call(mask, IPI_CALL_FUNC);
> +}
> +
> +void arch_send_call_function_single_ipi(int cpu)
> +{
> +	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
> +}
> +
> +#ifdef CONFIG_IRQ_WORK
> +void arch_irq_work_raise(void)
> +{
> +	if (__smp_cross_call)
> +		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
> +}
> +#endif
> +
>  static DEFINE_RAW_SPINLOCK(stop_lock);
>  
>  /*
> @@ -553,8 +561,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
>  	unsigned int cpu = smp_processor_id();
>  	struct pt_regs *old_regs = set_irq_regs(regs);
>  
> -	if (ipinr >= IPI_RESCHEDULE && ipinr < IPI_RESCHEDULE + NR_IPI)
> -		__inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_RESCHEDULE]);
> +	if ((unsigned)ipinr < NR_IPI) {
> +		trace_ipi_entry(ipi_types[ipinr]);
> +		__inc_irq_stat(cpu, ipi_irqs[ipinr]);
> +	}
>  
>  	switch (ipinr) {
>  	case IPI_RESCHEDULE:
> @@ -599,6 +609,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
>  		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
>  		break;
>  	}
> +
> +	if ((unsigned)ipinr < NR_IPI)
> +		trace_ipi_exit(ipi_types[ipinr]);
>  	set_irq_regs(old_regs);
>  }
>  

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

* Re: [PATCH v2 4/5] ARM64: add IPI tracepoints
  2014-08-06 19:52     ` Steven Rostedt
@ 2014-08-06 20:28       ` Nicolas Pitre
  -1 siblings, 0 replies; 30+ messages in thread
From: Nicolas Pitre @ 2014-08-06 20:28 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Russell King - ARM Linux, Will Deacon, Ingo Molnar,
	Daniel Lezcano, Catalin Marinas, linux-kernel, linux-arm-kernel,
	linaro-kernel

On Wed, 6 Aug 2014, Steven Rostedt wrote:

> Will and Russell,
> 
> Can you give me your Acked-by for this, and I can pull it through my
> tree?

Catalin (the ARM64 maintainer) already provided his.


> 
> Thanks,
> 
> -- Steve
> 
> 
> On Fri, 25 Jul 2014 16:05:32 -0400
> Nicolas Pitre <nicolas.pitre@linaro.org> wrote:
> 
> > The strings used to list IPIs in /proc/interrupts are reused for tracing
> > purposes.
> > 
> > While at it, the code is slightly cleaned up so the ipi_types array
> > indices are no longer offset by IPI_RESCHEDULE whose value is 0 anyway.
> > 
> > Signed-off-by: Nicolas Pitre <nico@linaro.org>
> > Acked-by: Steven Rostedt <rostedt@goodmis.org>
> > Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> > ---
> >  arch/arm64/kernel/smp.c | 65 +++++++++++++++++++++++++++++--------------------
> >  1 file changed, 39 insertions(+), 26 deletions(-)
> > 
> > diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> > index 40f38f46c8..a89c66f3b4 100644
> > --- a/arch/arm64/kernel/smp.c
> > +++ b/arch/arm64/kernel/smp.c
> > @@ -50,6 +50,9 @@
> >  #include <asm/tlbflush.h>
> >  #include <asm/ptrace.h>
> >  
> > +#define CREATE_TRACE_POINTS
> > +#include <trace/events/ipi.h>
> > +
> >  /*
> >   * as from 2.5, kernels no longer have an init_tasks structure
> >   * so we need some other way of telling a new secondary core
> > @@ -307,8 +310,6 @@ void __init smp_prepare_boot_cpu(void)
> >  	set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
> >  }
> >  
> > -static void (*smp_cross_call)(const struct cpumask *, unsigned int);
> > -
> >  /*
> >   * Enumerate the possible CPU set from the device tree and build the
> >   * cpu logical map array containing MPIDR values related to logical
> > @@ -463,32 +464,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
> >  	}
> >  }
> >  
> > +static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
> >  
> >  void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
> >  {
> > -	smp_cross_call = fn;
> > +	__smp_cross_call = fn;
> >  }
> >  
> > -void arch_send_call_function_ipi_mask(const struct cpumask *mask)
> > -{
> > -	smp_cross_call(mask, IPI_CALL_FUNC);
> > -}
> > -
> > -void arch_send_call_function_single_ipi(int cpu)
> > -{
> > -	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
> > -}
> > -
> > -#ifdef CONFIG_IRQ_WORK
> > -void arch_irq_work_raise(void)
> > -{
> > -	if (smp_cross_call)
> > -		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
> > -}
> > -#endif
> > -
> > -static const char *ipi_types[NR_IPI] = {
> > -#define S(x,s)	[x - IPI_RESCHEDULE] = s
> > +static const char *ipi_types[NR_IPI] __tracepoint_string = {
> > +#define S(x,s)	[x] = s
> >  	S(IPI_RESCHEDULE, "Rescheduling interrupts"),
> >  	S(IPI_CALL_FUNC, "Function call interrupts"),
> >  	S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
> > @@ -497,12 +481,18 @@ static const char *ipi_types[NR_IPI] = {
> >  	S(IPI_IRQ_WORK, "IRQ work interrupts"),
> >  };
> >  
> > +static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
> > +{
> > +	trace_ipi_raise(target, ipi_types[ipinr]);
> > +	__smp_cross_call(target, ipinr);
> > +}
> > +
> >  void show_ipi_list(struct seq_file *p, int prec)
> >  {
> >  	unsigned int cpu, i;
> >  
> >  	for (i = 0; i < NR_IPI; i++) {
> > -		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i + IPI_RESCHEDULE,
> > +		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
> >  			   prec >= 4 ? " " : "");
> >  		for_each_online_cpu(cpu)
> >  			seq_printf(p, "%10u ",
> > @@ -522,6 +512,24 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
> >  	return sum;
> >  }
> >  
> > +void arch_send_call_function_ipi_mask(const struct cpumask *mask)
> > +{
> > +	smp_cross_call(mask, IPI_CALL_FUNC);
> > +}
> > +
> > +void arch_send_call_function_single_ipi(int cpu)
> > +{
> > +	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
> > +}
> > +
> > +#ifdef CONFIG_IRQ_WORK
> > +void arch_irq_work_raise(void)
> > +{
> > +	if (__smp_cross_call)
> > +		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
> > +}
> > +#endif
> > +
> >  static DEFINE_RAW_SPINLOCK(stop_lock);
> >  
> >  /*
> > @@ -553,8 +561,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
> >  	unsigned int cpu = smp_processor_id();
> >  	struct pt_regs *old_regs = set_irq_regs(regs);
> >  
> > -	if (ipinr >= IPI_RESCHEDULE && ipinr < IPI_RESCHEDULE + NR_IPI)
> > -		__inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_RESCHEDULE]);
> > +	if ((unsigned)ipinr < NR_IPI) {
> > +		trace_ipi_entry(ipi_types[ipinr]);
> > +		__inc_irq_stat(cpu, ipi_irqs[ipinr]);
> > +	}
> >  
> >  	switch (ipinr) {
> >  	case IPI_RESCHEDULE:
> > @@ -599,6 +609,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
> >  		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
> >  		break;
> >  	}
> > +
> > +	if ((unsigned)ipinr < NR_IPI)
> > +		trace_ipi_exit(ipi_types[ipinr]);
> >  	set_irq_regs(old_regs);
> >  }
> >  
> 
> 

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

* [PATCH v2 4/5] ARM64: add IPI tracepoints
@ 2014-08-06 20:28       ` Nicolas Pitre
  0 siblings, 0 replies; 30+ messages in thread
From: Nicolas Pitre @ 2014-08-06 20:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 6 Aug 2014, Steven Rostedt wrote:

> Will and Russell,
> 
> Can you give me your Acked-by for this, and I can pull it through my
> tree?

Catalin (the ARM64 maintainer) already provided his.


> 
> Thanks,
> 
> -- Steve
> 
> 
> On Fri, 25 Jul 2014 16:05:32 -0400
> Nicolas Pitre <nicolas.pitre@linaro.org> wrote:
> 
> > The strings used to list IPIs in /proc/interrupts are reused for tracing
> > purposes.
> > 
> > While at it, the code is slightly cleaned up so the ipi_types array
> > indices are no longer offset by IPI_RESCHEDULE whose value is 0 anyway.
> > 
> > Signed-off-by: Nicolas Pitre <nico@linaro.org>
> > Acked-by: Steven Rostedt <rostedt@goodmis.org>
> > Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> > ---
> >  arch/arm64/kernel/smp.c | 65 +++++++++++++++++++++++++++++--------------------
> >  1 file changed, 39 insertions(+), 26 deletions(-)
> > 
> > diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> > index 40f38f46c8..a89c66f3b4 100644
> > --- a/arch/arm64/kernel/smp.c
> > +++ b/arch/arm64/kernel/smp.c
> > @@ -50,6 +50,9 @@
> >  #include <asm/tlbflush.h>
> >  #include <asm/ptrace.h>
> >  
> > +#define CREATE_TRACE_POINTS
> > +#include <trace/events/ipi.h>
> > +
> >  /*
> >   * as from 2.5, kernels no longer have an init_tasks structure
> >   * so we need some other way of telling a new secondary core
> > @@ -307,8 +310,6 @@ void __init smp_prepare_boot_cpu(void)
> >  	set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
> >  }
> >  
> > -static void (*smp_cross_call)(const struct cpumask *, unsigned int);
> > -
> >  /*
> >   * Enumerate the possible CPU set from the device tree and build the
> >   * cpu logical map array containing MPIDR values related to logical
> > @@ -463,32 +464,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
> >  	}
> >  }
> >  
> > +static void (*__smp_cross_call)(const struct cpumask *, unsigned int);
> >  
> >  void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
> >  {
> > -	smp_cross_call = fn;
> > +	__smp_cross_call = fn;
> >  }
> >  
> > -void arch_send_call_function_ipi_mask(const struct cpumask *mask)
> > -{
> > -	smp_cross_call(mask, IPI_CALL_FUNC);
> > -}
> > -
> > -void arch_send_call_function_single_ipi(int cpu)
> > -{
> > -	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
> > -}
> > -
> > -#ifdef CONFIG_IRQ_WORK
> > -void arch_irq_work_raise(void)
> > -{
> > -	if (smp_cross_call)
> > -		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
> > -}
> > -#endif
> > -
> > -static const char *ipi_types[NR_IPI] = {
> > -#define S(x,s)	[x - IPI_RESCHEDULE] = s
> > +static const char *ipi_types[NR_IPI] __tracepoint_string = {
> > +#define S(x,s)	[x] = s
> >  	S(IPI_RESCHEDULE, "Rescheduling interrupts"),
> >  	S(IPI_CALL_FUNC, "Function call interrupts"),
> >  	S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
> > @@ -497,12 +481,18 @@ static const char *ipi_types[NR_IPI] = {
> >  	S(IPI_IRQ_WORK, "IRQ work interrupts"),
> >  };
> >  
> > +static void smp_cross_call(const struct cpumask *target, unsigned int ipinr)
> > +{
> > +	trace_ipi_raise(target, ipi_types[ipinr]);
> > +	__smp_cross_call(target, ipinr);
> > +}
> > +
> >  void show_ipi_list(struct seq_file *p, int prec)
> >  {
> >  	unsigned int cpu, i;
> >  
> >  	for (i = 0; i < NR_IPI; i++) {
> > -		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i + IPI_RESCHEDULE,
> > +		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
> >  			   prec >= 4 ? " " : "");
> >  		for_each_online_cpu(cpu)
> >  			seq_printf(p, "%10u ",
> > @@ -522,6 +512,24 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
> >  	return sum;
> >  }
> >  
> > +void arch_send_call_function_ipi_mask(const struct cpumask *mask)
> > +{
> > +	smp_cross_call(mask, IPI_CALL_FUNC);
> > +}
> > +
> > +void arch_send_call_function_single_ipi(int cpu)
> > +{
> > +	smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
> > +}
> > +
> > +#ifdef CONFIG_IRQ_WORK
> > +void arch_irq_work_raise(void)
> > +{
> > +	if (__smp_cross_call)
> > +		smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK);
> > +}
> > +#endif
> > +
> >  static DEFINE_RAW_SPINLOCK(stop_lock);
> >  
> >  /*
> > @@ -553,8 +561,10 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
> >  	unsigned int cpu = smp_processor_id();
> >  	struct pt_regs *old_regs = set_irq_regs(regs);
> >  
> > -	if (ipinr >= IPI_RESCHEDULE && ipinr < IPI_RESCHEDULE + NR_IPI)
> > -		__inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_RESCHEDULE]);
> > +	if ((unsigned)ipinr < NR_IPI) {
> > +		trace_ipi_entry(ipi_types[ipinr]);
> > +		__inc_irq_stat(cpu, ipi_irqs[ipinr]);
> > +	}
> >  
> >  	switch (ipinr) {
> >  	case IPI_RESCHEDULE:
> > @@ -599,6 +609,9 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
> >  		pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr);
> >  		break;
> >  	}
> > +
> > +	if ((unsigned)ipinr < NR_IPI)
> > +		trace_ipi_exit(ipi_types[ipinr]);
> >  	set_irq_regs(old_regs);
> >  }
> >  
> 
> 

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

* Re: [PATCH v2 4/5] ARM64: add IPI tracepoints
  2014-08-06 19:52     ` Steven Rostedt
@ 2014-08-07  9:18       ` Will Deacon
  -1 siblings, 0 replies; 30+ messages in thread
From: Will Deacon @ 2014-08-07  9:18 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Russell King - ARM Linux, Nicolas Pitre, Ingo Molnar,
	Daniel Lezcano, Catalin Marinas, linux-kernel, linux-arm-kernel,
	linaro-kernel

On Wed, Aug 06, 2014 at 08:52:37PM +0100, Steven Rostedt wrote:
> Will and Russell,
> 
> Can you give me your Acked-by for this, and I can pull it through my
> tree?

Looks fine to me:

  Acked-by: Will Deacon <will.deacon@arm.com>

I'm assuming there's a dependency on other patches going via the tracing
tree, hence why you're taking this?

Cheers,

Will

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

* [PATCH v2 4/5] ARM64: add IPI tracepoints
@ 2014-08-07  9:18       ` Will Deacon
  0 siblings, 0 replies; 30+ messages in thread
From: Will Deacon @ 2014-08-07  9:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Aug 06, 2014 at 08:52:37PM +0100, Steven Rostedt wrote:
> Will and Russell,
> 
> Can you give me your Acked-by for this, and I can pull it through my
> tree?

Looks fine to me:

  Acked-by: Will Deacon <will.deacon@arm.com>

I'm assuming there's a dependency on other patches going via the tracing
tree, hence why you're taking this?

Cheers,

Will

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

* Re: [PATCH v2 4/5] ARM64: add IPI tracepoints
  2014-08-07  9:18       ` Will Deacon
@ 2014-08-07 15:18         ` Steven Rostedt
  -1 siblings, 0 replies; 30+ messages in thread
From: Steven Rostedt @ 2014-08-07 15:18 UTC (permalink / raw)
  To: Will Deacon
  Cc: Russell King - ARM Linux, Nicolas Pitre, Ingo Molnar,
	Daniel Lezcano, Catalin Marinas, linux-kernel, linux-arm-kernel,
	linaro-kernel

On Thu, 7 Aug 2014 10:18:17 +0100
Will Deacon <will.deacon@arm.com> wrote:

> On Wed, Aug 06, 2014 at 08:52:37PM +0100, Steven Rostedt wrote:
> > Will and Russell,
> > 
> > Can you give me your Acked-by for this, and I can pull it through my
> > tree?
> 
> Looks fine to me:
> 
>   Acked-by: Will Deacon <will.deacon@arm.com>
> 
> I'm assuming there's a dependency on other patches going via the tracing
> tree, hence why you're taking this?

Yeah, there's some generic updates to the trace facility for these
tracepoints.

-- Steve

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

* [PATCH v2 4/5] ARM64: add IPI tracepoints
@ 2014-08-07 15:18         ` Steven Rostedt
  0 siblings, 0 replies; 30+ messages in thread
From: Steven Rostedt @ 2014-08-07 15:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 7 Aug 2014 10:18:17 +0100
Will Deacon <will.deacon@arm.com> wrote:

> On Wed, Aug 06, 2014 at 08:52:37PM +0100, Steven Rostedt wrote:
> > Will and Russell,
> > 
> > Can you give me your Acked-by for this, and I can pull it through my
> > tree?
> 
> Looks fine to me:
> 
>   Acked-by: Will Deacon <will.deacon@arm.com>
> 
> I'm assuming there's a dependency on other patches going via the tracing
> tree, hence why you're taking this?

Yeah, there's some generic updates to the trace facility for these
tracepoints.

-- Steve

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

* Re: [PATCH v2 5/5] X86: add IPI tracepoints
  2014-07-25 20:05   ` Nicolas Pitre
@ 2014-08-07 15:33     ` Steven Rostedt
  -1 siblings, 0 replies; 30+ messages in thread
From: Steven Rostedt @ 2014-08-07 15:33 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Ingo Molnar, Daniel Lezcano, Russell King - ARM Linux,
	Catalin Marinas, linux-kernel, linux-arm-kernel, linaro-kernel,
	H. Peter Anvin

Peter,

I'm pulling in Nicolas's changes to trace and the arm architectures. He
has this x86 patch. Do you think this would be fine as well? Otherwise,
I'll just add the arm patches, and push that for this merge window
(these patches have been out on the mailing list for some time, with no
changes).

-- Steve


On Fri, 25 Jul 2014 16:05:33 -0400
Nicolas Pitre <nicolas.pitre@linaro.org> wrote:

> On X86 there are already tracepoints for IRQ vectors through which IPIs
> are handled.  However this is highly X86 specific, and the IPI signaling
> is not currently traced.
> 
> This is an attempt at adding generic IPI tracepoints to X86.
> 
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> ---
>  arch/x86/kernel/smp.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
> index be8e1bde07..d193609bea 100644
> --- a/arch/x86/kernel/smp.c
> +++ b/arch/x86/kernel/smp.c
> @@ -31,6 +31,16 @@
>  #include <asm/apic.h>
>  #include <asm/nmi.h>
>  #include <asm/trace/irq_vectors.h>
> +
> +#define CREATE_TRACE_POINTS
> +/*
> + * Those were defined in <asm/trace/irq_vectors.h> and cause problems
> + * when including <trace/events/ipi.h>.
> + */
> +#undef TRACE_INCLUDE_PATH
> +#undef TRACE_INCLUDE_FILE
> +#include <trace/events/ipi.h>
> +
>  /*
>   *	Some notes on x86 processor bugs affecting SMP operation:
>   *
> @@ -124,11 +134,13 @@ static void native_smp_send_reschedule(int cpu)
>  		WARN_ON(1);
>  		return;
>  	}
> +	trace_ipi_raise(cpumask_of(cpu), tracepoint_string("RESCHEDULE"));
>  	apic->send_IPI_mask(cpumask_of(cpu), RESCHEDULE_VECTOR);
>  }
>  
>  void native_send_call_func_single_ipi(int cpu)
>  {
> +	trace_ipi_raise(cpumask_of(cpu), tracepoint_string("CALL_FUNCTION_SINGLE"));
>  	apic->send_IPI_mask(cpumask_of(cpu), CALL_FUNCTION_SINGLE_VECTOR);
>  }
>  
> @@ -136,6 +148,8 @@ void native_send_call_func_ipi(const struct cpumask *mask)
>  {
>  	cpumask_var_t allbutself;
>  
> +	trace_ipi_raise(mask, tracepoint_string("CALL_FUNCTION"));
> +
>  	if (!alloc_cpumask_var(&allbutself, GFP_ATOMIC)) {
>  		apic->send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
>  		return;
> @@ -252,8 +266,10 @@ finish:
>   */
>  static inline void __smp_reschedule_interrupt(void)
>  {
> +	trace_ipi_entry(tracepoint_string("RESCHEDULE"));
>  	inc_irq_stat(irq_resched_count);
>  	scheduler_ipi();
> +	trace_ipi_exit(tracepoint_string("RESCHEDULE"));
>  }
>  
>  __visible void smp_reschedule_interrupt(struct pt_regs *regs)
> @@ -291,8 +307,10 @@ __visible void smp_trace_reschedule_interrupt(struct pt_regs *regs)
>  
>  static inline void __smp_call_function_interrupt(void)
>  {
> +	trace_ipi_entry(tracepoint_string("CALL_FUNCTION"));
>  	generic_smp_call_function_interrupt();
>  	inc_irq_stat(irq_call_count);
> +	trace_ipi_exit(tracepoint_string("CALL_FUNCTION"));
>  }
>  
>  __visible void smp_call_function_interrupt(struct pt_regs *regs)
> @@ -313,8 +331,10 @@ __visible void smp_trace_call_function_interrupt(struct pt_regs *regs)
>  
>  static inline void __smp_call_function_single_interrupt(void)
>  {
> +	trace_ipi_entry(tracepoint_string("CALL_FUNCTION_SINGLE"));
>  	generic_smp_call_function_single_interrupt();
>  	inc_irq_stat(irq_call_count);
> +	trace_ipi_exit(tracepoint_string("CALL_FUNCTION_SINGLE"));
>  }
>  
>  __visible void smp_call_function_single_interrupt(struct pt_regs *regs)


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

* [PATCH v2 5/5] X86: add IPI tracepoints
@ 2014-08-07 15:33     ` Steven Rostedt
  0 siblings, 0 replies; 30+ messages in thread
From: Steven Rostedt @ 2014-08-07 15:33 UTC (permalink / raw)
  To: linux-arm-kernel

Peter,

I'm pulling in Nicolas's changes to trace and the arm architectures. He
has this x86 patch. Do you think this would be fine as well? Otherwise,
I'll just add the arm patches, and push that for this merge window
(these patches have been out on the mailing list for some time, with no
changes).

-- Steve


On Fri, 25 Jul 2014 16:05:33 -0400
Nicolas Pitre <nicolas.pitre@linaro.org> wrote:

> On X86 there are already tracepoints for IRQ vectors through which IPIs
> are handled.  However this is highly X86 specific, and the IPI signaling
> is not currently traced.
> 
> This is an attempt at adding generic IPI tracepoints to X86.
> 
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> ---
>  arch/x86/kernel/smp.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
> index be8e1bde07..d193609bea 100644
> --- a/arch/x86/kernel/smp.c
> +++ b/arch/x86/kernel/smp.c
> @@ -31,6 +31,16 @@
>  #include <asm/apic.h>
>  #include <asm/nmi.h>
>  #include <asm/trace/irq_vectors.h>
> +
> +#define CREATE_TRACE_POINTS
> +/*
> + * Those were defined in <asm/trace/irq_vectors.h> and cause problems
> + * when including <trace/events/ipi.h>.
> + */
> +#undef TRACE_INCLUDE_PATH
> +#undef TRACE_INCLUDE_FILE
> +#include <trace/events/ipi.h>
> +
>  /*
>   *	Some notes on x86 processor bugs affecting SMP operation:
>   *
> @@ -124,11 +134,13 @@ static void native_smp_send_reschedule(int cpu)
>  		WARN_ON(1);
>  		return;
>  	}
> +	trace_ipi_raise(cpumask_of(cpu), tracepoint_string("RESCHEDULE"));
>  	apic->send_IPI_mask(cpumask_of(cpu), RESCHEDULE_VECTOR);
>  }
>  
>  void native_send_call_func_single_ipi(int cpu)
>  {
> +	trace_ipi_raise(cpumask_of(cpu), tracepoint_string("CALL_FUNCTION_SINGLE"));
>  	apic->send_IPI_mask(cpumask_of(cpu), CALL_FUNCTION_SINGLE_VECTOR);
>  }
>  
> @@ -136,6 +148,8 @@ void native_send_call_func_ipi(const struct cpumask *mask)
>  {
>  	cpumask_var_t allbutself;
>  
> +	trace_ipi_raise(mask, tracepoint_string("CALL_FUNCTION"));
> +
>  	if (!alloc_cpumask_var(&allbutself, GFP_ATOMIC)) {
>  		apic->send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
>  		return;
> @@ -252,8 +266,10 @@ finish:
>   */
>  static inline void __smp_reschedule_interrupt(void)
>  {
> +	trace_ipi_entry(tracepoint_string("RESCHEDULE"));
>  	inc_irq_stat(irq_resched_count);
>  	scheduler_ipi();
> +	trace_ipi_exit(tracepoint_string("RESCHEDULE"));
>  }
>  
>  __visible void smp_reschedule_interrupt(struct pt_regs *regs)
> @@ -291,8 +307,10 @@ __visible void smp_trace_reschedule_interrupt(struct pt_regs *regs)
>  
>  static inline void __smp_call_function_interrupt(void)
>  {
> +	trace_ipi_entry(tracepoint_string("CALL_FUNCTION"));
>  	generic_smp_call_function_interrupt();
>  	inc_irq_stat(irq_call_count);
> +	trace_ipi_exit(tracepoint_string("CALL_FUNCTION"));
>  }
>  
>  __visible void smp_call_function_interrupt(struct pt_regs *regs)
> @@ -313,8 +331,10 @@ __visible void smp_trace_call_function_interrupt(struct pt_regs *regs)
>  
>  static inline void __smp_call_function_single_interrupt(void)
>  {
> +	trace_ipi_entry(tracepoint_string("CALL_FUNCTION_SINGLE"));
>  	generic_smp_call_function_single_interrupt();
>  	inc_irq_stat(irq_call_count);
> +	trace_ipi_exit(tracepoint_string("CALL_FUNCTION_SINGLE"));
>  }
>  
>  __visible void smp_call_function_single_interrupt(struct pt_regs *regs)

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

* Re: [PATCH v2 1/5] tracing: Do not do anything special with tracepoint_string when tracing is disabled
  2014-07-25 20:05   ` Nicolas Pitre
@ 2014-08-08  2:35     ` Steven Rostedt
  -1 siblings, 0 replies; 30+ messages in thread
From: Steven Rostedt @ 2014-08-08  2:35 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Ingo Molnar, Daniel Lezcano, Russell King - ARM Linux,
	Catalin Marinas, linux-kernel, linux-arm-kernel, linaro-kernel

Because ftrace_events.h is not included when config tracing is not
enabled, I got error messages when compiling arm and arm64 without
tracing enabled. This is the new patch I'm now testing that moves the
tracepoint_string code to include/linux/tracepoint.h as well.

-- Steve

>From 3c49b52b155d0f723792377e1a4480a0e7ca0ba2 Mon Sep 17 00:00:00 2001
From: Steven Rostedt <rostedt@goodmis.org>
Date: Fri, 25 Jul 2014 16:05:29 -0400
Subject: [PATCH] tracing: Do not do anything special with tracepoint_string
 when tracing is disabled

When CONFIG_TRACING is not enabled, there's no reason to save the trace
strings either by the linker or as a static variable that can be
referenced later. Simply pass back the string that is given to
tracepoint_string().

Had to move the define to include/linux/tracepoint.h so that it is still
visible when CONFIG_TRACING is not set.

Link: http://lkml.kernel.org/p/1406318733-26754-2-git-send-email-nicolas.pitre@linaro.org

Suggested-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 include/linux/ftrace_event.h | 34 ----------------------------------
 include/linux/tracepoint.h   | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 34 deletions(-)

diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index cff3106ffe2c..c9f619a2070f 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -574,40 +574,6 @@ do {									\
 		__trace_printk(ip, fmt, ##args);			\
 } while (0)
 
-/**
- * tracepoint_string - register constant persistent string to trace system
- * @str - a constant persistent string that will be referenced in tracepoints
- *
- * If constant strings are being used in tracepoints, it is faster and
- * more efficient to just save the pointer to the string and reference
- * that with a printf "%s" instead of saving the string in the ring buffer
- * and wasting space and time.
- *
- * The problem with the above approach is that userspace tools that read
- * the binary output of the trace buffers do not have access to the string.
- * Instead they just show the address of the string which is not very
- * useful to users.
- *
- * With tracepoint_string(), the string will be registered to the tracing
- * system and exported to userspace via the debugfs/tracing/printk_formats
- * file that maps the string address to the string text. This way userspace
- * tools that read the binary buffers have a way to map the pointers to
- * the ASCII strings they represent.
- *
- * The @str used must be a constant string and persistent as it would not
- * make sense to show a string that no longer exists. But it is still fine
- * to be used with modules, because when modules are unloaded, if they
- * had tracepoints, the ring buffers are cleared too. As long as the string
- * does not change during the life of the module, it is fine to use
- * tracepoint_string() within a module.
- */
-#define tracepoint_string(str)						\
-	({								\
-		static const char *___tp_str __tracepoint_string = str; \
-		___tp_str;						\
-	})
-#define __tracepoint_string	__attribute__((section("__tracepoint_str")))
-
 #ifdef CONFIG_PERF_EVENTS
 struct perf_event;
 
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 2e2a5f7717e5..b1293f15f592 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -249,6 +249,50 @@ extern void syscall_unregfunc(void);
 
 #endif /* CONFIG_TRACEPOINTS */
 
+#ifdef CONFIG_TRACING
+/**
+ * tracepoint_string - register constant persistent string to trace system
+ * @str - a constant persistent string that will be referenced in tracepoints
+ *
+ * If constant strings are being used in tracepoints, it is faster and
+ * more efficient to just save the pointer to the string and reference
+ * that with a printf "%s" instead of saving the string in the ring buffer
+ * and wasting space and time.
+ *
+ * The problem with the above approach is that userspace tools that read
+ * the binary output of the trace buffers do not have access to the string.
+ * Instead they just show the address of the string which is not very
+ * useful to users.
+ *
+ * With tracepoint_string(), the string will be registered to the tracing
+ * system and exported to userspace via the debugfs/tracing/printk_formats
+ * file that maps the string address to the string text. This way userspace
+ * tools that read the binary buffers have a way to map the pointers to
+ * the ASCII strings they represent.
+ *
+ * The @str used must be a constant string and persistent as it would not
+ * make sense to show a string that no longer exists. But it is still fine
+ * to be used with modules, because when modules are unloaded, if they
+ * had tracepoints, the ring buffers are cleared too. As long as the string
+ * does not change during the life of the module, it is fine to use
+ * tracepoint_string() within a module.
+ */
+#define tracepoint_string(str)						\
+	({								\
+		static const char *___tp_str __tracepoint_string = str; \
+		___tp_str;						\
+	})
+#define __tracepoint_string	__attribute__((section("__tracepoint_str")))
+#else
+/*
+ * tracepoint_string() is used to save the string address for userspace
+ * tracing tools. When tracing isn't configured, there's no need to save
+ * anything.
+ */
+# define tracepoint_string(str) str
+# define __tracepoint_string
+#endif
+
 /*
  * The need for the DECLARE_TRACE_NOARGS() is to handle the prototype
  * (void). "void" is a special value in a function prototype and can
-- 
2.0.1


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

* [PATCH v2 1/5] tracing: Do not do anything special with tracepoint_string when tracing is disabled
@ 2014-08-08  2:35     ` Steven Rostedt
  0 siblings, 0 replies; 30+ messages in thread
From: Steven Rostedt @ 2014-08-08  2:35 UTC (permalink / raw)
  To: linux-arm-kernel

Because ftrace_events.h is not included when config tracing is not
enabled, I got error messages when compiling arm and arm64 without
tracing enabled. This is the new patch I'm now testing that moves the
tracepoint_string code to include/linux/tracepoint.h as well.

-- Steve

>From 3c49b52b155d0f723792377e1a4480a0e7ca0ba2 Mon Sep 17 00:00:00 2001
From: Steven Rostedt <rostedt@goodmis.org>
Date: Fri, 25 Jul 2014 16:05:29 -0400
Subject: [PATCH] tracing: Do not do anything special with tracepoint_string
 when tracing is disabled

When CONFIG_TRACING is not enabled, there's no reason to save the trace
strings either by the linker or as a static variable that can be
referenced later. Simply pass back the string that is given to
tracepoint_string().

Had to move the define to include/linux/tracepoint.h so that it is still
visible when CONFIG_TRACING is not set.

Link: http://lkml.kernel.org/p/1406318733-26754-2-git-send-email-nicolas.pitre at linaro.org

Suggested-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 include/linux/ftrace_event.h | 34 ----------------------------------
 include/linux/tracepoint.h   | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 34 deletions(-)

diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index cff3106ffe2c..c9f619a2070f 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -574,40 +574,6 @@ do {									\
 		__trace_printk(ip, fmt, ##args);			\
 } while (0)
 
-/**
- * tracepoint_string - register constant persistent string to trace system
- * @str - a constant persistent string that will be referenced in tracepoints
- *
- * If constant strings are being used in tracepoints, it is faster and
- * more efficient to just save the pointer to the string and reference
- * that with a printf "%s" instead of saving the string in the ring buffer
- * and wasting space and time.
- *
- * The problem with the above approach is that userspace tools that read
- * the binary output of the trace buffers do not have access to the string.
- * Instead they just show the address of the string which is not very
- * useful to users.
- *
- * With tracepoint_string(), the string will be registered to the tracing
- * system and exported to userspace via the debugfs/tracing/printk_formats
- * file that maps the string address to the string text. This way userspace
- * tools that read the binary buffers have a way to map the pointers to
- * the ASCII strings they represent.
- *
- * The @str used must be a constant string and persistent as it would not
- * make sense to show a string that no longer exists. But it is still fine
- * to be used with modules, because when modules are unloaded, if they
- * had tracepoints, the ring buffers are cleared too. As long as the string
- * does not change during the life of the module, it is fine to use
- * tracepoint_string() within a module.
- */
-#define tracepoint_string(str)						\
-	({								\
-		static const char *___tp_str __tracepoint_string = str; \
-		___tp_str;						\
-	})
-#define __tracepoint_string	__attribute__((section("__tracepoint_str")))
-
 #ifdef CONFIG_PERF_EVENTS
 struct perf_event;
 
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 2e2a5f7717e5..b1293f15f592 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -249,6 +249,50 @@ extern void syscall_unregfunc(void);
 
 #endif /* CONFIG_TRACEPOINTS */
 
+#ifdef CONFIG_TRACING
+/**
+ * tracepoint_string - register constant persistent string to trace system
+ * @str - a constant persistent string that will be referenced in tracepoints
+ *
+ * If constant strings are being used in tracepoints, it is faster and
+ * more efficient to just save the pointer to the string and reference
+ * that with a printf "%s" instead of saving the string in the ring buffer
+ * and wasting space and time.
+ *
+ * The problem with the above approach is that userspace tools that read
+ * the binary output of the trace buffers do not have access to the string.
+ * Instead they just show the address of the string which is not very
+ * useful to users.
+ *
+ * With tracepoint_string(), the string will be registered to the tracing
+ * system and exported to userspace via the debugfs/tracing/printk_formats
+ * file that maps the string address to the string text. This way userspace
+ * tools that read the binary buffers have a way to map the pointers to
+ * the ASCII strings they represent.
+ *
+ * The @str used must be a constant string and persistent as it would not
+ * make sense to show a string that no longer exists. But it is still fine
+ * to be used with modules, because when modules are unloaded, if they
+ * had tracepoints, the ring buffers are cleared too. As long as the string
+ * does not change during the life of the module, it is fine to use
+ * tracepoint_string() within a module.
+ */
+#define tracepoint_string(str)						\
+	({								\
+		static const char *___tp_str __tracepoint_string = str; \
+		___tp_str;						\
+	})
+#define __tracepoint_string	__attribute__((section("__tracepoint_str")))
+#else
+/*
+ * tracepoint_string() is used to save the string address for userspace
+ * tracing tools. When tracing isn't configured, there's no need to save
+ * anything.
+ */
+# define tracepoint_string(str) str
+# define __tracepoint_string
+#endif
+
 /*
  * The need for the DECLARE_TRACE_NOARGS() is to handle the prototype
  * (void). "void" is a special value in a function prototype and can
-- 
2.0.1

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

* Re: [PATCH v2 1/5] tracing: Do not do anything special with tracepoint_string when tracing is disabled
  2014-08-08  2:35     ` Steven Rostedt
@ 2014-08-08  3:05       ` Nicolas Pitre
  -1 siblings, 0 replies; 30+ messages in thread
From: Nicolas Pitre @ 2014-08-08  3:05 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Ingo Molnar, Daniel Lezcano, Russell King - ARM Linux,
	Catalin Marinas, linux-kernel, linux-arm-kernel, linaro-kernel

On Thu, 7 Aug 2014, Steven Rostedt wrote:

> Because ftrace_events.h is not included when config tracing is not
> enabled, I got error messages when compiling arm and arm64 without
> tracing enabled. This is the new patch I'm now testing that moves the
> tracepoint_string code to include/linux/tracepoint.h as well.

Makes sense.



> 
> -- Steve
> 
> From 3c49b52b155d0f723792377e1a4480a0e7ca0ba2 Mon Sep 17 00:00:00 2001
> From: Steven Rostedt <rostedt@goodmis.org>
> Date: Fri, 25 Jul 2014 16:05:29 -0400
> Subject: [PATCH] tracing: Do not do anything special with tracepoint_string
>  when tracing is disabled
> 
> When CONFIG_TRACING is not enabled, there's no reason to save the trace
> strings either by the linker or as a static variable that can be
> referenced later. Simply pass back the string that is given to
> tracepoint_string().
> 
> Had to move the define to include/linux/tracepoint.h so that it is still
> visible when CONFIG_TRACING is not set.
> 
> Link: http://lkml.kernel.org/p/1406318733-26754-2-git-send-email-nicolas.pitre@linaro.org
> 
> Suggested-by: Nicolas Pitre <nico@linaro.org>
> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
> ---
>  include/linux/ftrace_event.h | 34 ----------------------------------
>  include/linux/tracepoint.h   | 44 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 44 insertions(+), 34 deletions(-)
> 
> diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
> index cff3106ffe2c..c9f619a2070f 100644
> --- a/include/linux/ftrace_event.h
> +++ b/include/linux/ftrace_event.h
> @@ -574,40 +574,6 @@ do {									\
>  		__trace_printk(ip, fmt, ##args);			\
>  } while (0)
>  
> -/**
> - * tracepoint_string - register constant persistent string to trace system
> - * @str - a constant persistent string that will be referenced in tracepoints
> - *
> - * If constant strings are being used in tracepoints, it is faster and
> - * more efficient to just save the pointer to the string and reference
> - * that with a printf "%s" instead of saving the string in the ring buffer
> - * and wasting space and time.
> - *
> - * The problem with the above approach is that userspace tools that read
> - * the binary output of the trace buffers do not have access to the string.
> - * Instead they just show the address of the string which is not very
> - * useful to users.
> - *
> - * With tracepoint_string(), the string will be registered to the tracing
> - * system and exported to userspace via the debugfs/tracing/printk_formats
> - * file that maps the string address to the string text. This way userspace
> - * tools that read the binary buffers have a way to map the pointers to
> - * the ASCII strings they represent.
> - *
> - * The @str used must be a constant string and persistent as it would not
> - * make sense to show a string that no longer exists. But it is still fine
> - * to be used with modules, because when modules are unloaded, if they
> - * had tracepoints, the ring buffers are cleared too. As long as the string
> - * does not change during the life of the module, it is fine to use
> - * tracepoint_string() within a module.
> - */
> -#define tracepoint_string(str)						\
> -	({								\
> -		static const char *___tp_str __tracepoint_string = str; \
> -		___tp_str;						\
> -	})
> -#define __tracepoint_string	__attribute__((section("__tracepoint_str")))
> -
>  #ifdef CONFIG_PERF_EVENTS
>  struct perf_event;
>  
> diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
> index 2e2a5f7717e5..b1293f15f592 100644
> --- a/include/linux/tracepoint.h
> +++ b/include/linux/tracepoint.h
> @@ -249,6 +249,50 @@ extern void syscall_unregfunc(void);
>  
>  #endif /* CONFIG_TRACEPOINTS */
>  
> +#ifdef CONFIG_TRACING
> +/**
> + * tracepoint_string - register constant persistent string to trace system
> + * @str - a constant persistent string that will be referenced in tracepoints
> + *
> + * If constant strings are being used in tracepoints, it is faster and
> + * more efficient to just save the pointer to the string and reference
> + * that with a printf "%s" instead of saving the string in the ring buffer
> + * and wasting space and time.
> + *
> + * The problem with the above approach is that userspace tools that read
> + * the binary output of the trace buffers do not have access to the string.
> + * Instead they just show the address of the string which is not very
> + * useful to users.
> + *
> + * With tracepoint_string(), the string will be registered to the tracing
> + * system and exported to userspace via the debugfs/tracing/printk_formats
> + * file that maps the string address to the string text. This way userspace
> + * tools that read the binary buffers have a way to map the pointers to
> + * the ASCII strings they represent.
> + *
> + * The @str used must be a constant string and persistent as it would not
> + * make sense to show a string that no longer exists. But it is still fine
> + * to be used with modules, because when modules are unloaded, if they
> + * had tracepoints, the ring buffers are cleared too. As long as the string
> + * does not change during the life of the module, it is fine to use
> + * tracepoint_string() within a module.
> + */
> +#define tracepoint_string(str)						\
> +	({								\
> +		static const char *___tp_str __tracepoint_string = str; \
> +		___tp_str;						\
> +	})
> +#define __tracepoint_string	__attribute__((section("__tracepoint_str")))
> +#else
> +/*
> + * tracepoint_string() is used to save the string address for userspace
> + * tracing tools. When tracing isn't configured, there's no need to save
> + * anything.
> + */
> +# define tracepoint_string(str) str
> +# define __tracepoint_string
> +#endif
> +
>  /*
>   * The need for the DECLARE_TRACE_NOARGS() is to handle the prototype
>   * (void). "void" is a special value in a function prototype and can
> -- 
> 2.0.1
> 
> 

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

* [PATCH v2 1/5] tracing: Do not do anything special with tracepoint_string when tracing is disabled
@ 2014-08-08  3:05       ` Nicolas Pitre
  0 siblings, 0 replies; 30+ messages in thread
From: Nicolas Pitre @ 2014-08-08  3:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 7 Aug 2014, Steven Rostedt wrote:

> Because ftrace_events.h is not included when config tracing is not
> enabled, I got error messages when compiling arm and arm64 without
> tracing enabled. This is the new patch I'm now testing that moves the
> tracepoint_string code to include/linux/tracepoint.h as well.

Makes sense.



> 
> -- Steve
> 
> From 3c49b52b155d0f723792377e1a4480a0e7ca0ba2 Mon Sep 17 00:00:00 2001
> From: Steven Rostedt <rostedt@goodmis.org>
> Date: Fri, 25 Jul 2014 16:05:29 -0400
> Subject: [PATCH] tracing: Do not do anything special with tracepoint_string
>  when tracing is disabled
> 
> When CONFIG_TRACING is not enabled, there's no reason to save the trace
> strings either by the linker or as a static variable that can be
> referenced later. Simply pass back the string that is given to
> tracepoint_string().
> 
> Had to move the define to include/linux/tracepoint.h so that it is still
> visible when CONFIG_TRACING is not set.
> 
> Link: http://lkml.kernel.org/p/1406318733-26754-2-git-send-email-nicolas.pitre at linaro.org
> 
> Suggested-by: Nicolas Pitre <nico@linaro.org>
> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
> ---
>  include/linux/ftrace_event.h | 34 ----------------------------------
>  include/linux/tracepoint.h   | 44 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 44 insertions(+), 34 deletions(-)
> 
> diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
> index cff3106ffe2c..c9f619a2070f 100644
> --- a/include/linux/ftrace_event.h
> +++ b/include/linux/ftrace_event.h
> @@ -574,40 +574,6 @@ do {									\
>  		__trace_printk(ip, fmt, ##args);			\
>  } while (0)
>  
> -/**
> - * tracepoint_string - register constant persistent string to trace system
> - * @str - a constant persistent string that will be referenced in tracepoints
> - *
> - * If constant strings are being used in tracepoints, it is faster and
> - * more efficient to just save the pointer to the string and reference
> - * that with a printf "%s" instead of saving the string in the ring buffer
> - * and wasting space and time.
> - *
> - * The problem with the above approach is that userspace tools that read
> - * the binary output of the trace buffers do not have access to the string.
> - * Instead they just show the address of the string which is not very
> - * useful to users.
> - *
> - * With tracepoint_string(), the string will be registered to the tracing
> - * system and exported to userspace via the debugfs/tracing/printk_formats
> - * file that maps the string address to the string text. This way userspace
> - * tools that read the binary buffers have a way to map the pointers to
> - * the ASCII strings they represent.
> - *
> - * The @str used must be a constant string and persistent as it would not
> - * make sense to show a string that no longer exists. But it is still fine
> - * to be used with modules, because when modules are unloaded, if they
> - * had tracepoints, the ring buffers are cleared too. As long as the string
> - * does not change during the life of the module, it is fine to use
> - * tracepoint_string() within a module.
> - */
> -#define tracepoint_string(str)						\
> -	({								\
> -		static const char *___tp_str __tracepoint_string = str; \
> -		___tp_str;						\
> -	})
> -#define __tracepoint_string	__attribute__((section("__tracepoint_str")))
> -
>  #ifdef CONFIG_PERF_EVENTS
>  struct perf_event;
>  
> diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
> index 2e2a5f7717e5..b1293f15f592 100644
> --- a/include/linux/tracepoint.h
> +++ b/include/linux/tracepoint.h
> @@ -249,6 +249,50 @@ extern void syscall_unregfunc(void);
>  
>  #endif /* CONFIG_TRACEPOINTS */
>  
> +#ifdef CONFIG_TRACING
> +/**
> + * tracepoint_string - register constant persistent string to trace system
> + * @str - a constant persistent string that will be referenced in tracepoints
> + *
> + * If constant strings are being used in tracepoints, it is faster and
> + * more efficient to just save the pointer to the string and reference
> + * that with a printf "%s" instead of saving the string in the ring buffer
> + * and wasting space and time.
> + *
> + * The problem with the above approach is that userspace tools that read
> + * the binary output of the trace buffers do not have access to the string.
> + * Instead they just show the address of the string which is not very
> + * useful to users.
> + *
> + * With tracepoint_string(), the string will be registered to the tracing
> + * system and exported to userspace via the debugfs/tracing/printk_formats
> + * file that maps the string address to the string text. This way userspace
> + * tools that read the binary buffers have a way to map the pointers to
> + * the ASCII strings they represent.
> + *
> + * The @str used must be a constant string and persistent as it would not
> + * make sense to show a string that no longer exists. But it is still fine
> + * to be used with modules, because when modules are unloaded, if they
> + * had tracepoints, the ring buffers are cleared too. As long as the string
> + * does not change during the life of the module, it is fine to use
> + * tracepoint_string() within a module.
> + */
> +#define tracepoint_string(str)						\
> +	({								\
> +		static const char *___tp_str __tracepoint_string = str; \
> +		___tp_str;						\
> +	})
> +#define __tracepoint_string	__attribute__((section("__tracepoint_str")))
> +#else
> +/*
> + * tracepoint_string() is used to save the string address for userspace
> + * tracing tools. When tracing isn't configured, there's no need to save
> + * anything.
> + */
> +# define tracepoint_string(str) str
> +# define __tracepoint_string
> +#endif
> +
>  /*
>   * The need for the DECLARE_TRACE_NOARGS() is to handle the prototype
>   * (void). "void" is a special value in a function prototype and can
> -- 
> 2.0.1
> 
> 

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

end of thread, other threads:[~2014-08-08  3:05 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-25 20:05 [PATCH v2 0/5] generic IPI tracing Nicolas Pitre
2014-07-25 20:05 ` Nicolas Pitre
2014-07-25 20:05 ` [PATCH v2 1/5] tracing: Do not do anything special with tracepoint_string when tracing is disabled Nicolas Pitre
2014-07-25 20:05   ` Nicolas Pitre
2014-08-08  2:35   ` Steven Rostedt
2014-08-08  2:35     ` Steven Rostedt
2014-08-08  3:05     ` Nicolas Pitre
2014-08-08  3:05       ` Nicolas Pitre
2014-07-25 20:05 ` [PATCH v2 2/5] tracepoint: add generic tracepoint definitions for IPI tracing Nicolas Pitre
2014-07-25 20:05   ` Nicolas Pitre
2014-07-25 20:05 ` [PATCH v2 3/5] ARM: add IPI tracepoints Nicolas Pitre
2014-07-25 20:05   ` Nicolas Pitre
2014-07-28  5:34   ` Daniel Lezcano
2014-07-28  5:34     ` Daniel Lezcano
2014-08-06 19:51   ` Steven Rostedt
2014-08-06 19:51     ` Steven Rostedt
2014-07-25 20:05 ` [PATCH v2 4/5] ARM64: " Nicolas Pitre
2014-07-25 20:05   ` Nicolas Pitre
2014-08-06 19:52   ` Steven Rostedt
2014-08-06 19:52     ` Steven Rostedt
2014-08-06 20:28     ` Nicolas Pitre
2014-08-06 20:28       ` Nicolas Pitre
2014-08-07  9:18     ` Will Deacon
2014-08-07  9:18       ` Will Deacon
2014-08-07 15:18       ` Steven Rostedt
2014-08-07 15:18         ` Steven Rostedt
2014-07-25 20:05 ` [PATCH v2 5/5] X86: " Nicolas Pitre
2014-07-25 20:05   ` Nicolas Pitre
2014-08-07 15:33   ` Steven Rostedt
2014-08-07 15:33     ` Steven Rostedt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.