Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1237349 > unrolled thread

[for-next][PATCH 00/25] tracing: Have instances have their own options + clean ups

Started bySteven Rostedt <rostedt@goodmis.org>
First post2015-10-01 14:10 +0200
Last post2015-10-01 14:10 +0200
Articles 7 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [for-next][PATCH 00/25] tracing: Have instances have their own options + clean ups Steven Rostedt <rostedt@goodmis.org> - 2015-10-01 14:10 +0200
    [for-next][PATCH 03/25] tracing: Remove ftrace_trace_stack_regs() Steven Rostedt <rostedt@goodmis.org> - 2015-10-01 14:10 +0200
    [for-next][PATCH 18/25] tracing: Add build bug if we have more trace_flags than bits Steven Rostedt <rostedt@goodmis.org> - 2015-10-01 14:10 +0200
    [for-next][PATCH 24/25] tracing: Add trace options for core options to instances Steven Rostedt <rostedt@goodmis.org> - 2015-10-01 14:10 +0200
    [for-next][PATCH 04/25] tracing: Remove unused function trace_current_buffer_lock_reserve() Steven Rostedt <rostedt@goodmis.org> - 2015-10-01 14:10 +0200
    [for-next][PATCH 02/25] tracing: Move non perf code out of perf.h Steven Rostedt <rostedt@goodmis.org> - 2015-10-01 14:10 +0200
    [for-next][PATCH 17/25] tracing: Always show all tracer options in the options directory Steven Rostedt <rostedt@goodmis.org> - 2015-10-01 14:10 +0200

#1237349 — [for-next][PATCH 00/25] tracing: Have instances have their own options + clean ups

FromSteven Rostedt <rostedt@goodmis.org>
Date2015-10-01 14:10 +0200
Subject[for-next][PATCH 00/25] tracing: Have instances have their own options + clean ups
Message-ID<qeKGK-383-5@gated-at.bofh.it>
Adds an options directory in the instance directories. Some options
are still global (the tracer specific ones). But formats are not.

  git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
for-next

Head SHA1: 37aea98b84c0ce2ac638510fefeed9f8f920bd34


Steven Rostedt (Red Hat) (24):
      tracing: Move non perf code out of perf.h
      tracing: Remove ftrace_trace_stack_regs()
      tracing: Remove unused function trace_current_buffer_lock_reserve()
      tracing: Pass trace_array into trace_buffer_unlock_commit()
      tracing: Make ftrace_trace_stack() static
      tracing: Inject seq_print_userip_objs() into its only user
      tracing: Turn seq_print_user_ip() into a static function
      tracing: Move "display-graph" option to main options
      tracing: Remove unused tracing option "ftrace_preempt"
      tracing: Use enums instead of hard coded bitmasks for TRACE_ITER flags
      tracing: Use TRACE_FLAGS macro to keep enums and strings matched
      tracing: Only create function graph options when it is compiled in
      tracing: Only create branch tracer options when compiled in
      tracing: Do not create function tracer options when not compiled in
      tracing: Only create stacktrace option when STACKTRACE is configured
      tracing: Always show all tracer options in the options directory
      tracing: Add build bug if we have more trace_flags than bits
      tracing: Remove access to trace_flags in trace_printk.c
      tracing: Move sleep-time and graph-time options out of the core trace_flags
      tracing: Move trace_flags from global to a trace_array field
      tracing: Add a method to pass in trace_array descriptor to option files
      tracing: Make ftrace_trace_stack() depend on general trace_array flag
      tracing: Add trace options for core options to instances
      tracing: Add trace options for tracer options to instances

Yaowei Bai (1):
      kernel/trace_probe: is_good_name can be boolean

----
 include/linux/trace_events.h         |  13 +-
 include/trace/perf.h                 | 258 ----------------------
 include/trace/trace_events.h         | 258 ++++++++++++++++++++++
 kernel/trace/blktrace.c              |  11 +-
 kernel/trace/ftrace.c                |  19 +-
 kernel/trace/trace.c                 | 403 ++++++++++++++++++++++-------------
 kernel/trace/trace.h                 | 154 ++++++++-----
 kernel/trace/trace_events.c          |  12 +-
 kernel/trace/trace_functions_graph.c |  63 ++++--
 kernel/trace/trace_irqsoff.c         |  98 +++++----
 kernel/trace/trace_kdb.c             |   8 +-
 kernel/trace/trace_mmiotrace.c       |   4 +-
 kernel/trace/trace_output.c          |  97 ++++-----
 kernel/trace/trace_output.h          |   4 -
 kernel/trace/trace_printk.c          |  14 +-
 kernel/trace/trace_probe.h           |   8 +-
 kernel/trace/trace_sched_wakeup.c    | 112 +++++-----
 kernel/trace/trace_syscalls.c        |   3 +-
 18 files changed, 869 insertions(+), 670 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1237350 — [for-next][PATCH 03/25] tracing: Remove ftrace_trace_stack_regs()

FromSteven Rostedt <rostedt@goodmis.org>
Date2015-10-01 14:10 +0200
Subject[for-next][PATCH 03/25] tracing: Remove ftrace_trace_stack_regs()
Message-ID<qeKQs-3yE-59@gated-at.bofh.it>
In reply to#1237349
From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

ftrace_trace_stack_regs() is used in only one place, and because that is
such a simple function, just move its code into the location that it was
used in (trace_buffer_unlock_commit_regs()).

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 kernel/trace/trace.c | 24 ++++++++++++++----------
 kernel/trace/trace.h |  9 ---------
 2 files changed, 14 insertions(+), 19 deletions(-)

diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 6e79408674aa..50820887dce9 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -468,6 +468,18 @@ static inline void trace_access_lock_init(void)
 
 #endif
 
+#ifdef CONFIG_STACKTRACE
+static void __ftrace_trace_stack(struct ring_buffer *buffer,
+				 unsigned long flags,
+				 int skip, int pc, struct pt_regs *regs);
+#else
+static inline void __ftrace_trace_stack(struct ring_buffer *buffer,
+					unsigned long flags,
+					int skip, int pc, struct pt_regs *regs)
+{
+}
+#endif
+
 /* trace_flags holds trace_options default values */
 unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK |
 	TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME |
@@ -1744,7 +1756,8 @@ void trace_buffer_unlock_commit_regs(struct ring_buffer *buffer,
 {
 	__buffer_unlock_commit(buffer, event);
 
-	ftrace_trace_stack_regs(buffer, flags, 0, pc, regs);
+	if (trace_flags & TRACE_ITER_STACKTRACE)
+		__ftrace_trace_stack(buffer, flags, 0, pc, regs);
 	ftrace_trace_userstack(buffer, flags, pc);
 }
 EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit_regs);
@@ -1873,15 +1886,6 @@ static void __ftrace_trace_stack(struct ring_buffer *buffer,
 
 }
 
-void ftrace_trace_stack_regs(struct ring_buffer *buffer, unsigned long flags,
-			     int skip, int pc, struct pt_regs *regs)
-{
-	if (!(trace_flags & TRACE_ITER_STACKTRACE))
-		return;
-
-	__ftrace_trace_stack(buffer, flags, skip, pc, regs);
-}
-
 void ftrace_trace_stack(struct ring_buffer *buffer, unsigned long flags,
 			int skip, int pc)
 {
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 74bde81601a9..3b2a950a6291 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -614,9 +614,6 @@ void update_max_tr_single(struct trace_array *tr,
 void ftrace_trace_stack(struct ring_buffer *buffer, unsigned long flags,
 			int skip, int pc);
 
-void ftrace_trace_stack_regs(struct ring_buffer *buffer, unsigned long flags,
-			     int skip, int pc, struct pt_regs *regs);
-
 void ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags,
 			    int pc);
 
@@ -628,12 +625,6 @@ static inline void ftrace_trace_stack(struct ring_buffer *buffer,
 {
 }
 
-static inline void ftrace_trace_stack_regs(struct ring_buffer *buffer,
-					   unsigned long flags, int skip,
-					   int pc, struct pt_regs *regs)
-{
-}
-
 static inline void ftrace_trace_userstack(struct ring_buffer *buffer,
 					  unsigned long flags, int pc)
 {
-- 
2.5.1


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1237351 — [for-next][PATCH 18/25] tracing: Add build bug if we have more trace_flags than bits

FromSteven Rostedt <rostedt@goodmis.org>
Date2015-10-01 14:10 +0200
Subject[for-next][PATCH 18/25] tracing: Add build bug if we have more trace_flags than bits
Message-ID<qeKQs-3yE-63@gated-at.bofh.it>
In reply to#1237349
From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

Add a enum that denotes the last bit of the trace_flags and have a
BUILD_BUG_ON(last_bit > 32).

If we add more bits than we have in trace_flags, the kernel wont build.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 kernel/trace/trace.c | 6 ++++++
 kernel/trace/trace.h | 6 +++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 7446d4238f87..991bab9b79d2 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -7046,6 +7046,12 @@ __init static int tracer_alloc_buffers(void)
 	int ring_buf_size;
 	int ret = -ENOMEM;
 
+	/*
+	 * Make sure we don't accidently add more trace options
+	 * than we have bits for.
+	 */
+	BUILD_BUG_ON(TRACE_ITER_LAST_BIT > 32);
+
 	if (!alloc_cpumask_var(&tracing_buffer_mask, GFP_KERNEL))
 		goto out;
 
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 8ed97872b65b..07155652254d 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -966,7 +966,11 @@ extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf,
 #undef C
 #define C(a, b) TRACE_ITER_##a##_BIT
 
-enum trace_iterator_bits { TRACE_FLAGS };
+enum trace_iterator_bits {
+	TRACE_FLAGS
+	/* Make sure we don't go more than we have bits for */
+	TRACE_ITER_LAST_BIT
+};
 
 /*
  * By redefining C, we can make TRACE_FLAGS a list of masks that
-- 
2.5.1


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1237352 — [for-next][PATCH 24/25] tracing: Add trace options for core options to instances

FromSteven Rostedt <rostedt@goodmis.org>
Date2015-10-01 14:10 +0200
Subject[for-next][PATCH 24/25] tracing: Add trace options for core options to instances
Message-ID<qeKQr-3yE-49@gated-at.bofh.it>
In reply to#1237349
From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

Allow instances to have their own options, at least for the core options
(non tracer specific ones). There are a few global options that should not
be added to instances, like enabling of trace_printk, and the sched comm
recording, which do not have a specific trace instance associated to them.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 kernel/trace/trace.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 51697b41f5d4..7b99e36b8973 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -258,6 +258,11 @@ unsigned long long ns2usecs(cycle_t nsec)
 	 TRACE_ITER_RECORD_CMD | TRACE_ITER_OVERWRITE |			\
 	 TRACE_ITER_IRQ_INFO | TRACE_ITER_MARKERS)
 
+/* trace_options that are only supported by global_trace */
+#define TOP_LEVEL_TRACE_FLAGS (TRACE_ITER_PRINTK |			\
+	       TRACE_ITER_PRINTK_MSGONLY | TRACE_ITER_RECORD_CMD)
+
+
 /*
  * The global_trace is the descriptor that holds the tracing
  * buffers for the live tracing. For each CPU, it contains
@@ -6387,17 +6392,21 @@ create_trace_option_core_file(struct trace_array *tr,
 				 &trace_options_core_fops);
 }
 
-static __init void create_trace_options_dir(struct trace_array *tr)
+static void create_trace_options_dir(struct trace_array *tr)
 {
 	struct dentry *t_options;
+	bool top_level = tr == &global_trace;
 	int i;
 
 	t_options = trace_options_init_dentry(tr);
 	if (!t_options)
 		return;
 
-	for (i = 0; trace_options[i]; i++)
-		create_trace_option_core_file(tr, trace_options[i], i);
+	for (i = 0; trace_options[i]; i++) {
+		if (top_level ||
+		    !((1 << i) & TOP_LEVEL_TRACE_FLAGS))
+			create_trace_option_core_file(tr, trace_options[i], i);
+	}
 }
 
 static ssize_t
@@ -6707,6 +6716,8 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)
 	trace_create_file("tracing_on", 0644, d_tracer,
 			  tr, &rb_simple_fops);
 
+	create_trace_options_dir(tr);
+
 #ifdef CONFIG_TRACER_MAX_TRACE
 	trace_create_file("tracing_max_latency", 0644, d_tracer,
 			&tr->max_latency, &tracing_max_lat_fops);
@@ -6903,8 +6914,6 @@ static __init int tracer_init_tracefs(void)
 
 	create_trace_instances(d_tracer);
 
-	create_trace_options_dir(&global_trace);
-
 	mutex_lock(&trace_types_lock);
 	for (t = trace_types; t; t = t->next)
 		add_tracer_options(&global_trace, t);
-- 
2.5.1


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1237354 — [for-next][PATCH 04/25] tracing: Remove unused function trace_current_buffer_lock_reserve()

FromSteven Rostedt <rostedt@goodmis.org>
Date2015-10-01 14:10 +0200
Subject[for-next][PATCH 04/25] tracing: Remove unused function trace_current_buffer_lock_reserve()
Message-ID<qeKQs-3yE-55@gated-at.bofh.it>
In reply to#1237349
From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

trace_current_buffer_lock_reserve() is not used by anything. Might as well
get rid of it.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 include/linux/trace_events.h | 3 ---
 kernel/trace/trace.c         | 8 --------
 2 files changed, 11 deletions(-)

diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index ed27917cabc9..71c1191b9954 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -168,9 +168,6 @@ struct ring_buffer_event *
 trace_current_buffer_lock_reserve(struct ring_buffer **current_buffer,
 				  int type, unsigned long len,
 				  unsigned long flags, int pc);
-void trace_current_buffer_unlock_commit(struct ring_buffer *buffer,
-					struct ring_buffer_event *event,
-					unsigned long flags, int pc);
 void trace_buffer_unlock_commit(struct ring_buffer *buffer,
 				struct ring_buffer_event *event,
 				unsigned long flags, int pc);
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 50820887dce9..a499ec95fc61 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1741,14 +1741,6 @@ trace_current_buffer_lock_reserve(struct ring_buffer **current_rb,
 }
 EXPORT_SYMBOL_GPL(trace_current_buffer_lock_reserve);
 
-void trace_current_buffer_unlock_commit(struct ring_buffer *buffer,
-					struct ring_buffer_event *event,
-					unsigned long flags, int pc)
-{
-	__trace_buffer_unlock_commit(buffer, event, flags, pc);
-}
-EXPORT_SYMBOL_GPL(trace_current_buffer_unlock_commit);
-
 void trace_buffer_unlock_commit_regs(struct ring_buffer *buffer,
 				     struct ring_buffer_event *event,
 				     unsigned long flags, int pc,
-- 
2.5.1


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1237355 — [for-next][PATCH 02/25] tracing: Move non perf code out of perf.h

FromSteven Rostedt <rostedt@goodmis.org>
Date2015-10-01 14:10 +0200
Subject[for-next][PATCH 02/25] tracing: Move non perf code out of perf.h
Message-ID<qeKQr-3yE-47@gated-at.bofh.it>
In reply to#1237349
From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

Commit ee53bbd17257 "tracing: Move the perf code out of trace_event.h" moved
more than just the perf code out of trace_event.h, but also removed a bit of
the tracing code too. Move it back.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 include/trace/perf.h         | 258 -------------------------------------------
 include/trace/trace_events.h | 258 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 258 insertions(+), 258 deletions(-)

diff --git a/include/trace/perf.h b/include/trace/perf.h
index 1b5443cebedc..26486fcd74ce 100644
--- a/include/trace/perf.h
+++ b/include/trace/perf.h
@@ -1,261 +1,3 @@
-/*
- * Stage 4 of the trace events.
- *
- * Override the macros in <trace/trace_events.h> to include the following:
- *
- * For those macros defined with TRACE_EVENT:
- *
- * static struct trace_event_call event_<call>;
- *
- * static void trace_event_raw_event_<call>(void *__data, proto)
- * {
- *	struct trace_event_file *trace_file = __data;
- *	struct trace_event_call *event_call = trace_file->event_call;
- *	struct trace_event_data_offsets_<call> __maybe_unused __data_offsets;
- *	unsigned long eflags = trace_file->flags;
- *	enum event_trigger_type __tt = ETT_NONE;
- *	struct ring_buffer_event *event;
- *	struct trace_event_raw_<call> *entry; <-- defined in stage 1
- *	struct ring_buffer *buffer;
- *	unsigned long irq_flags;
- *	int __data_size;
- *	int pc;
- *
- *	if (!(eflags & EVENT_FILE_FL_TRIGGER_COND)) {
- *		if (eflags & EVENT_FILE_FL_TRIGGER_MODE)
- *			event_triggers_call(trace_file, NULL);
- *		if (eflags & EVENT_FILE_FL_SOFT_DISABLED)
- *			return;
- *	}
- *
- *	local_save_flags(irq_flags);
- *	pc = preempt_count();
- *
- *	__data_size = trace_event_get_offsets_<call>(&__data_offsets, args);
- *
- *	event = trace_event_buffer_lock_reserve(&buffer, trace_file,
- *				  event_<call>->event.type,
- *				  sizeof(*entry) + __data_size,
- *				  irq_flags, pc);
- *	if (!event)
- *		return;
- *	entry	= ring_buffer_event_data(event);
- *
- *	{ <assign>; }  <-- Here we assign the entries by the __field and
- *			   __array macros.
- *
- *	if (eflags & EVENT_FILE_FL_TRIGGER_COND)
- *		__tt = event_triggers_call(trace_file, entry);
- *
- *	if (test_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT,
- *		     &trace_file->flags))
- *		ring_buffer_discard_commit(buffer, event);
- *	else if (!filter_check_discard(trace_file, entry, buffer, event))
- *		trace_buffer_unlock_commit(buffer, event, irq_flags, pc);
- *
- *	if (__tt)
- *		event_triggers_post_call(trace_file, __tt);
- * }
- *
- * static struct trace_event ftrace_event_type_<call> = {
- *	.trace			= trace_raw_output_<call>, <-- stage 2
- * };
- *
- * static char print_fmt_<call>[] = <TP_printk>;
- *
- * static struct trace_event_class __used event_class_<template> = {
- *	.system			= "<system>",
- *	.define_fields		= trace_event_define_fields_<call>,
- *	.fields			= LIST_HEAD_INIT(event_class_##call.fields),
- *	.raw_init		= trace_event_raw_init,
- *	.probe			= trace_event_raw_event_##call,
- *	.reg			= trace_event_reg,
- * };
- *
- * static struct trace_event_call event_<call> = {
- *	.class			= event_class_<template>,
- *	{
- *		.tp			= &__tracepoint_<call>,
- *	},
- *	.event			= &ftrace_event_type_<call>,
- *	.print_fmt		= print_fmt_<call>,
- *	.flags			= TRACE_EVENT_FL_TRACEPOINT,
- * };
- * // its only safe to use pointers when doing linker tricks to
- * // create an array.
- * static struct trace_event_call __used
- * __attribute__((section("_ftrace_events"))) *__event_<call> = &event_<call>;
- *
- */
-
-#ifdef CONFIG_PERF_EVENTS
-
-#define _TRACE_PERF_PROTO(call, proto)					\
-	static notrace void						\
-	perf_trace_##call(void *__data, proto);
-
-#define _TRACE_PERF_INIT(call)						\
-	.perf_probe		= perf_trace_##call,
-
-#else
-#define _TRACE_PERF_PROTO(call, proto)
-#define _TRACE_PERF_INIT(call)
-#endif /* CONFIG_PERF_EVENTS */
-
-#undef __entry
-#define __entry entry
-
-#undef __field
-#define __field(type, item)
-
-#undef __field_struct
-#define __field_struct(type, item)
-
-#undef __array
-#define __array(type, item, len)
-
-#undef __dynamic_array
-#define __dynamic_array(type, item, len)				\
-	__entry->__data_loc_##item = __data_offsets.item;
-
-#undef __string
-#define __string(item, src) __dynamic_array(char, item, -1)
-
-#undef __assign_str
-#define __assign_str(dst, src)						\
-	strcpy(__get_str(dst), (src) ? (const char *)(src) : "(null)");
-
-#undef __bitmask
-#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
-
-#undef __get_bitmask
-#define __get_bitmask(field) (char *)__get_dynamic_array(field)
-
-#undef __assign_bitmask
-#define __assign_bitmask(dst, src, nr_bits)					\
-	memcpy(__get_bitmask(dst), (src), __bitmask_size_in_bytes(nr_bits))
-
-#undef TP_fast_assign
-#define TP_fast_assign(args...) args
-
-#undef __perf_addr
-#define __perf_addr(a)	(a)
-
-#undef __perf_count
-#define __perf_count(c)	(c)
-
-#undef __perf_task
-#define __perf_task(t)	(t)
-
-#undef DECLARE_EVENT_CLASS
-#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)	\
-									\
-static notrace void							\
-trace_event_raw_event_##call(void *__data, proto)			\
-{									\
-	struct trace_event_file *trace_file = __data;			\
-	struct trace_event_data_offsets_##call __maybe_unused __data_offsets;\
-	struct trace_event_buffer fbuffer;				\
-	struct trace_event_raw_##call *entry;				\
-	int __data_size;						\
-									\
-	if (trace_trigger_soft_disabled(trace_file))			\
-		return;							\
-									\
-	__data_size = trace_event_get_offsets_##call(&__data_offsets, args); \
-									\
-	entry = trace_event_buffer_reserve(&fbuffer, trace_file,	\
-				 sizeof(*entry) + __data_size);		\
-									\
-	if (!entry)							\
-		return;							\
-									\
-	tstruct								\
-									\
-	{ assign; }							\
-									\
-	trace_event_buffer_commit(&fbuffer);				\
-}
-/*
- * The ftrace_test_probe is compiled out, it is only here as a build time check
- * to make sure that if the tracepoint handling changes, the ftrace probe will
- * fail to compile unless it too is updated.
- */
-
-#undef DEFINE_EVENT
-#define DEFINE_EVENT(template, call, proto, args)			\
-static inline void ftrace_test_probe_##call(void)			\
-{									\
-	check_trace_callback_type_##call(trace_event_raw_event_##template); \
-}
-
-#undef DEFINE_EVENT_PRINT
-#define DEFINE_EVENT_PRINT(template, name, proto, args, print)
-
-#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
-
-#undef __entry
-#define __entry REC
-
-#undef __print_flags
-#undef __print_symbolic
-#undef __print_hex
-#undef __get_dynamic_array
-#undef __get_dynamic_array_len
-#undef __get_str
-#undef __get_bitmask
-#undef __print_array
-
-#undef TP_printk
-#define TP_printk(fmt, args...) "\"" fmt "\", "  __stringify(args)
-
-#undef DECLARE_EVENT_CLASS
-#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)	\
-_TRACE_PERF_PROTO(call, PARAMS(proto));					\
-static char print_fmt_##call[] = print;					\
-static struct trace_event_class __used __refdata event_class_##call = { \
-	.system			= TRACE_SYSTEM_STRING,			\
-	.define_fields		= trace_event_define_fields_##call,	\
-	.fields			= LIST_HEAD_INIT(event_class_##call.fields),\
-	.raw_init		= trace_event_raw_init,			\
-	.probe			= trace_event_raw_event_##call,		\
-	.reg			= trace_event_reg,			\
-	_TRACE_PERF_INIT(call)						\
-};
-
-#undef DEFINE_EVENT
-#define DEFINE_EVENT(template, call, proto, args)			\
-									\
-static struct trace_event_call __used event_##call = {			\
-	.class			= &event_class_##template,		\
-	{								\
-		.tp			= &__tracepoint_##call,		\
-	},								\
-	.event.funcs		= &trace_event_type_funcs_##template,	\
-	.print_fmt		= print_fmt_##template,			\
-	.flags			= TRACE_EVENT_FL_TRACEPOINT,		\
-};									\
-static struct trace_event_call __used					\
-__attribute__((section("_ftrace_events"))) *__event_##call = &event_##call
-
-#undef DEFINE_EVENT_PRINT
-#define DEFINE_EVENT_PRINT(template, call, proto, args, print)		\
-									\
-static char print_fmt_##call[] = print;					\
-									\
-static struct trace_event_call __used event_##call = {			\
-	.class			= &event_class_##template,		\
-	{								\
-		.tp			= &__tracepoint_##call,		\
-	},								\
-	.event.funcs		= &trace_event_type_funcs_##call,	\
-	.print_fmt		= print_fmt_##call,			\
-	.flags			= TRACE_EVENT_FL_TRACEPOINT,		\
-};									\
-static struct trace_event_call __used					\
-__attribute__((section("_ftrace_events"))) *__event_##call = &event_##call
-
-#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
 
 #undef TRACE_SYSTEM_VAR
 
diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h
index 43be3b0e44d3..de996cf61053 100644
--- a/include/trace/trace_events.h
+++ b/include/trace/trace_events.h
@@ -506,3 +506,261 @@ static inline notrace int trace_event_get_offsets_##call(		\
 
 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
 
+/*
+ * Stage 4 of the trace events.
+ *
+ * Override the macros in <trace/trace_events.h> to include the following:
+ *
+ * For those macros defined with TRACE_EVENT:
+ *
+ * static struct trace_event_call event_<call>;
+ *
+ * static void trace_event_raw_event_<call>(void *__data, proto)
+ * {
+ *	struct trace_event_file *trace_file = __data;
+ *	struct trace_event_call *event_call = trace_file->event_call;
+ *	struct trace_event_data_offsets_<call> __maybe_unused __data_offsets;
+ *	unsigned long eflags = trace_file->flags;
+ *	enum event_trigger_type __tt = ETT_NONE;
+ *	struct ring_buffer_event *event;
+ *	struct trace_event_raw_<call> *entry; <-- defined in stage 1
+ *	struct ring_buffer *buffer;
+ *	unsigned long irq_flags;
+ *	int __data_size;
+ *	int pc;
+ *
+ *	if (!(eflags & EVENT_FILE_FL_TRIGGER_COND)) {
+ *		if (eflags & EVENT_FILE_FL_TRIGGER_MODE)
+ *			event_triggers_call(trace_file, NULL);
+ *		if (eflags & EVENT_FILE_FL_SOFT_DISABLED)
+ *			return;
+ *	}
+ *
+ *	local_save_flags(irq_flags);
+ *	pc = preempt_count();
+ *
+ *	__data_size = trace_event_get_offsets_<call>(&__data_offsets, args);
+ *
+ *	event = trace_event_buffer_lock_reserve(&buffer, trace_file,
+ *				  event_<call>->event.type,
+ *				  sizeof(*entry) + __data_size,
+ *				  irq_flags, pc);
+ *	if (!event)
+ *		return;
+ *	entry	= ring_buffer_event_data(event);
+ *
+ *	{ <assign>; }  <-- Here we assign the entries by the __field and
+ *			   __array macros.
+ *
+ *	if (eflags & EVENT_FILE_FL_TRIGGER_COND)
+ *		__tt = event_triggers_call(trace_file, entry);
+ *
+ *	if (test_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT,
+ *		     &trace_file->flags))
+ *		ring_buffer_discard_commit(buffer, event);
+ *	else if (!filter_check_discard(trace_file, entry, buffer, event))
+ *		trace_buffer_unlock_commit(buffer, event, irq_flags, pc);
+ *
+ *	if (__tt)
+ *		event_triggers_post_call(trace_file, __tt);
+ * }
+ *
+ * static struct trace_event ftrace_event_type_<call> = {
+ *	.trace			= trace_raw_output_<call>, <-- stage 2
+ * };
+ *
+ * static char print_fmt_<call>[] = <TP_printk>;
+ *
+ * static struct trace_event_class __used event_class_<template> = {
+ *	.system			= "<system>",
+ *	.define_fields		= trace_event_define_fields_<call>,
+ *	.fields			= LIST_HEAD_INIT(event_class_##call.fields),
+ *	.raw_init		= trace_event_raw_init,
+ *	.probe			= trace_event_raw_event_##call,
+ *	.reg			= trace_event_reg,
+ * };
+ *
+ * static struct trace_event_call event_<call> = {
+ *	.class			= event_class_<template>,
+ *	{
+ *		.tp			= &__tracepoint_<call>,
+ *	},
+ *	.event			= &ftrace_event_type_<call>,
+ *	.print_fmt		= print_fmt_<call>,
+ *	.flags			= TRACE_EVENT_FL_TRACEPOINT,
+ * };
+ * // its only safe to use pointers when doing linker tricks to
+ * // create an array.
+ * static struct trace_event_call __used
+ * __attribute__((section("_ftrace_events"))) *__event_<call> = &event_<call>;
+ *
+ */
+
+#ifdef CONFIG_PERF_EVENTS
+
+#define _TRACE_PERF_PROTO(call, proto)					\
+	static notrace void						\
+	perf_trace_##call(void *__data, proto);
+
+#define _TRACE_PERF_INIT(call)						\
+	.perf_probe		= perf_trace_##call,
+
+#else
+#define _TRACE_PERF_PROTO(call, proto)
+#define _TRACE_PERF_INIT(call)
+#endif /* CONFIG_PERF_EVENTS */
+
+#undef __entry
+#define __entry entry
+
+#undef __field
+#define __field(type, item)
+
+#undef __field_struct
+#define __field_struct(type, item)
+
+#undef __array
+#define __array(type, item, len)
+
+#undef __dynamic_array
+#define __dynamic_array(type, item, len)				\
+	__entry->__data_loc_##item = __data_offsets.item;
+
+#undef __string
+#define __string(item, src) __dynamic_array(char, item, -1)
+
+#undef __assign_str
+#define __assign_str(dst, src)						\
+	strcpy(__get_str(dst), (src) ? (const char *)(src) : "(null)");
+
+#undef __bitmask
+#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
+
+#undef __get_bitmask
+#define __get_bitmask(field) (char *)__get_dynamic_array(field)
+
+#undef __assign_bitmask
+#define __assign_bitmask(dst, src, nr_bits)					\
+	memcpy(__get_bitmask(dst), (src), __bitmask_size_in_bytes(nr_bits))
+
+#undef TP_fast_assign
+#define TP_fast_assign(args...) args
+
+#undef __perf_addr
+#define __perf_addr(a)	(a)
+
+#undef __perf_count
+#define __perf_count(c)	(c)
+
+#undef __perf_task
+#define __perf_task(t)	(t)
+
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)	\
+									\
+static notrace void							\
+trace_event_raw_event_##call(void *__data, proto)			\
+{									\
+	struct trace_event_file *trace_file = __data;			\
+	struct trace_event_data_offsets_##call __maybe_unused __data_offsets;\
+	struct trace_event_buffer fbuffer;				\
+	struct trace_event_raw_##call *entry;				\
+	int __data_size;						\
+									\
+	if (trace_trigger_soft_disabled(trace_file))			\
+		return;							\
+									\
+	__data_size = trace_event_get_offsets_##call(&__data_offsets, args); \
+									\
+	entry = trace_event_buffer_reserve(&fbuffer, trace_file,	\
+				 sizeof(*entry) + __data_size);		\
+									\
+	if (!entry)							\
+		return;							\
+									\
+	tstruct								\
+									\
+	{ assign; }							\
+									\
+	trace_event_buffer_commit(&fbuffer);				\
+}
+/*
+ * The ftrace_test_probe is compiled out, it is only here as a build time check
+ * to make sure that if the tracepoint handling changes, the ftrace probe will
+ * fail to compile unless it too is updated.
+ */
+
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(template, call, proto, args)			\
+static inline void ftrace_test_probe_##call(void)			\
+{									\
+	check_trace_callback_type_##call(trace_event_raw_event_##template); \
+}
+
+#undef DEFINE_EVENT_PRINT
+#define DEFINE_EVENT_PRINT(template, name, proto, args, print)
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
+
+#undef __entry
+#define __entry REC
+
+#undef __print_flags
+#undef __print_symbolic
+#undef __print_hex
+#undef __get_dynamic_array
+#undef __get_dynamic_array_len
+#undef __get_str
+#undef __get_bitmask
+#undef __print_array
+
+#undef TP_printk
+#define TP_printk(fmt, args...) "\"" fmt "\", "  __stringify(args)
+
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print)	\
+_TRACE_PERF_PROTO(call, PARAMS(proto));					\
+static char print_fmt_##call[] = print;					\
+static struct trace_event_class __used __refdata event_class_##call = { \
+	.system			= TRACE_SYSTEM_STRING,			\
+	.define_fields		= trace_event_define_fields_##call,	\
+	.fields			= LIST_HEAD_INIT(event_class_##call.fields),\
+	.raw_init		= trace_event_raw_init,			\
+	.probe			= trace_event_raw_event_##call,		\
+	.reg			= trace_event_reg,			\
+	_TRACE_PERF_INIT(call)						\
+};
+
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(template, call, proto, args)			\
+									\
+static struct trace_event_call __used event_##call = {			\
+	.class			= &event_class_##template,		\
+	{								\
+		.tp			= &__tracepoint_##call,		\
+	},								\
+	.event.funcs		= &trace_event_type_funcs_##template,	\
+	.print_fmt		= print_fmt_##template,			\
+	.flags			= TRACE_EVENT_FL_TRACEPOINT,		\
+};									\
+static struct trace_event_call __used					\
+__attribute__((section("_ftrace_events"))) *__event_##call = &event_##call
+
+#undef DEFINE_EVENT_PRINT
+#define DEFINE_EVENT_PRINT(template, call, proto, args, print)		\
+									\
+static char print_fmt_##call[] = print;					\
+									\
+static struct trace_event_call __used event_##call = {			\
+	.class			= &event_class_##template,		\
+	{								\
+		.tp			= &__tracepoint_##call,		\
+	},								\
+	.event.funcs		= &trace_event_type_funcs_##call,	\
+	.print_fmt		= print_fmt_##call,			\
+	.flags			= TRACE_EVENT_FL_TRACEPOINT,		\
+};									\
+static struct trace_event_call __used					\
+__attribute__((section("_ftrace_events"))) *__event_##call = &event_##call
+
+#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
-- 
2.5.1


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1237356 — [for-next][PATCH 17/25] tracing: Always show all tracer options in the options directory

FromSteven Rostedt <rostedt@goodmis.org>
Date2015-10-01 14:10 +0200
Subject[for-next][PATCH 17/25] tracing: Always show all tracer options in the options directory
Message-ID<qeKQs-3yE-61@gated-at.bofh.it>
In reply to#1237349
From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

There are options that are unique to a specific tracer (like function and
function graph). Currently, these options are only visible in the options
directory when the tracer is enabled.

This has been a pain, especially for something like the func_stack_trace
option that if used inappropriately, could bring the system to a crawl. But
the only way to see it, is to enable the function tracer.

For example, if one had done:

 # cd /sys/kernel/tracing
 # echo __schedule > set_ftrace_filter
 # echo 1 > options/func_stack_trace
 # echo function > current_tracer

The __schedule call will be traced and a stack trace will also be recorded
there. Now when you were done, you may do...

 # echo nop > current_tracer
 # echo > set_ftrace_filter

But you forgot to disable the func_stack_trace. The only way to disable it
is to re-enable function tracing first. If you do not add a filter to
set_ftrace_filter and just do:

 # echo function > current_tracer

Now you would be performing a stack trace on *every* function! On some
systems, that causes a live lock. Others may take a few minutes to fix your
mistake.

Having the func_stack_trace option visible allows you to check it and
disable it before enabling the funtion tracer.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 kernel/trace/trace.c | 53 +++++++++++++++++++---------------------------------
 kernel/trace/trace.h |  8 ++++++++
 2 files changed, 27 insertions(+), 34 deletions(-)

diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 865f3fad9ff0..7446d4238f87 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1213,6 +1213,8 @@ static inline int run_tracer_selftest(struct tracer *type)
 }
 #endif /* CONFIG_FTRACE_STARTUP_TEST */
 
+static void add_tracer_options(struct trace_array *tr, struct tracer *t);
+
 /**
  * register_tracer - register a tracer with the ftrace system.
  * @type - the plugin for the tracer
@@ -1262,6 +1264,7 @@ int register_tracer(struct tracer *type)
 
 	type->next = trace_types;
 	trace_types = type;
+	add_tracer_options(&global_trace, type);
 
  out:
 	tracing_selftest_running = false;
@@ -4287,9 +4290,6 @@ struct trace_option_dentry;
 static struct trace_option_dentry *
 create_trace_option_files(struct trace_array *tr, struct tracer *tracer);
 
-static void
-destroy_trace_option_files(struct trace_option_dentry *topts);
-
 /*
  * Used to clear out the tracer before deletion of an instance.
  * Must have trace_types_lock held.
@@ -4307,10 +4307,8 @@ static void tracing_set_nop(struct trace_array *tr)
 	tr->current_trace = &nop_trace;
 }
 
-static void update_tracer_options(struct trace_array *tr, struct tracer *t)
+static void add_tracer_options(struct trace_array *tr, struct tracer *t)
 {
-	static struct trace_option_dentry *topts;
-
 	/* Only enable if the directory has been created already. */
 	if (!tr->dir)
 		return;
@@ -4319,8 +4317,11 @@ static void update_tracer_options(struct trace_array *tr, struct tracer *t)
 	if (!(tr->flags & TRACE_ARRAY_FL_GLOBAL))
 		return;
 
-	destroy_trace_option_files(topts);
-	topts = create_trace_option_files(tr, t);
+	/* Ignore if they were already created */
+	if (t->topts)
+		return;
+
+	t->topts = create_trace_option_files(tr, t);
 }
 
 static int tracing_set_tracer(struct trace_array *tr, const char *buf)
@@ -4389,7 +4390,6 @@ static int tracing_set_tracer(struct trace_array *tr, const char *buf)
 		free_snapshot(tr);
 	}
 #endif
-	update_tracer_options(tr, t);
 
 #ifdef CONFIG_TRACER_MAX_TRACE
 	if (t->use_max_tr && !had_max_tr) {
@@ -6119,13 +6119,6 @@ tracing_init_tracefs_percpu(struct trace_array *tr, long cpu)
 #include "trace_selftest.c"
 #endif
 
-struct trace_option_dentry {
-	struct tracer_opt		*opt;
-	struct tracer_flags		*flags;
-	struct trace_array		*tr;
-	struct dentry			*entry;
-};
-
 static ssize_t
 trace_options_read(struct file *filp, char __user *ubuf, size_t cnt,
 			loff_t *ppos)
@@ -6310,27 +6303,17 @@ create_trace_option_files(struct trace_array *tr, struct tracer *tracer)
 	if (!topts)
 		return NULL;
 
-	for (cnt = 0; opts[cnt].name; cnt++)
+	for (cnt = 0; opts[cnt].name; cnt++) {
 		create_trace_option_file(tr, &topts[cnt], flags,
 					 &opts[cnt]);
+		WARN_ONCE(topts[cnt].entry == NULL,
+			  "Failed to create trace option: %s",
+			  opts[cnt].name);
+	}
 
 	return topts;
 }
 
-static void
-destroy_trace_option_files(struct trace_option_dentry *topts)
-{
-	int cnt;
-
-	if (!topts)
-		return;
-
-	for (cnt = 0; topts[cnt].opt; cnt++)
-		tracefs_remove(topts[cnt].entry);
-
-	kfree(topts);
-}
-
 static struct dentry *
 create_trace_option_core_file(struct trace_array *tr,
 			      const char *option, long index)
@@ -6812,6 +6795,7 @@ static struct notifier_block trace_module_nb = {
 static __init int tracer_init_tracefs(void)
 {
 	struct dentry *d_tracer;
+	struct tracer *t;
 
 	trace_access_lock_init();
 
@@ -6850,9 +6834,10 @@ static __init int tracer_init_tracefs(void)
 
 	create_trace_options_dir(&global_trace);
 
-	/* If the tracer was started via cmdline, create options for it here */
-	if (global_trace.current_trace != &nop_trace)
-		update_tracer_options(&global_trace, global_trace.current_trace);
+	mutex_lock(&trace_types_lock);
+	for (t = trace_types; t; t = t->next)
+		add_tracer_options(&global_trace, t);
+	mutex_unlock(&trace_types_lock);
 
 	return 0;
 }
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index af34e1822dad..8ed97872b65b 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -333,6 +333,13 @@ struct tracer_flags {
 #define TRACER_OPT(s, b)	.name = #s, .bit = b
 
 
+struct trace_option_dentry {
+	struct tracer_opt		*opt;
+	struct tracer_flags		*flags;
+	struct trace_array		*tr;
+	struct dentry			*entry;
+};
+
 /**
  * struct tracer - a specific tracer and its callbacks to interact with tracefs
  * @name: the name chosen to select it on the available_tracers file
@@ -387,6 +394,7 @@ struct tracer {
 						u32 mask, int set);
 	struct tracer		*next;
 	struct tracer_flags	*flags;
+	struct trace_option_dentry *topts;
 	int			enabled;
 	int			ref;
 	bool			print_max;
-- 
2.5.1


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web