LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values
@ 2015-03-27 21:37 Steven Rostedt
  2015-03-27 21:37 ` [RFC][PATCH 01/10] tracing: Add TRACE_DEFINE_ENUM() macro to map enums to their values Steven Rostedt
                   ` (11 more replies)
  0 siblings, 12 replies; 27+ messages in thread
From: Steven Rostedt @ 2015-03-27 21:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ingo Molnar, Andrew Morton, Namhyung Kim, Masami Hiramatsu,
	Mathieu Desnoyers


As there are many tracepoints that use __print_symbolic() to translate
numbers into ASCII strings, and several of these translate enums as
well, it causes a problem for user space tools that read the tracepoint
format files and have to translate the binary data to their associated
strings.

For example, with the tlb_flush tracepoint, we have this in the format
file:

print fmt: "pages:%ld reason:%s (%d)", REC->pages,
 __print_symbolic(REC->reason,
   { TLB_FLUSH_ON_TASK_SWITCH, "flush on task switch" },
   { TLB_REMOTE_SHOOTDOWN, "remote shootdown" },
   { TLB_LOCAL_SHOOTDOWN, "local shootdown" },
   { TLB_LOCAL_MM_SHOOTDOWN, "local mm shootdown" }), REC->reason

Now, userspace does not know what the value of TLB_REMOTE_SHOOTDOWN is.
To solve this, a new macro is created as a helper to allow tracepoints
to export enums they use to userspace. This macro is called,
TRACE_DEFINE_ENUM(), such that

 TRACE_DEFINE_ENUM(TLB_REMOTE_SHOOTDOWN);

Will export the TLB_REMOTE_SHOOTDOWN enum to use space.

How that is done is with a new file in the debugfs tracing directory.

 # cat /sys/kernel/debug/tracing/enum_map
TLB_LOCAL_MM_SHOOTDOWN 3
TLB_LOCAL_SHOOTDOWN 2
TLB_REMOTE_SHOOTDOWN 1
TLB_FLUSH_ON_TASK_SWITCH 0

Now userspace, when seeing TLB_REMOTE_SHOOTDOWN in the format, knows
that represents "1", and can do the conversions properly.


Local SHA1: 6115e48a506e738f0f24771b4c87e4ba90d3d1c2


Steven Rostedt (Red Hat) (10):
      tracing: Add TRACE_DEFINE_ENUM() macro to map enums to their values
      tracing: Allow for modules to export their trace enums as well
      x86/tlb/trace: Export enums in used by tlb_flush tracepoint
      net/9p/tracing: Export enums in tracepoints to userspace
      f2fs: Export the enums in the tracepoints to userspace
      irq/tracing: Export enums in tracepoints to user space
      mm: tracing: Export enums in tracepoints to user space
      SUNRPC: Export enums in tracepoints to user space
      v4l: Export enums used by tracepoints to user space
      writeback: Export enums used by tracepoint to user space

----
 include/asm-generic/vmlinux.lds.h |   5 +-
 include/linux/module.h            |   2 +
 include/linux/tracepoint.h        |   7 +
 include/trace/events/9p.h         | 157 +++++++++++++----------
 include/trace/events/f2fs.h       |  21 +++
 include/trace/events/irq.h        |  39 ++++--
 include/trace/events/migrate.h    |  42 ++++--
 include/trace/events/sunrpc.h     |  62 ++++++---
 include/trace/events/tlb.h        |  30 ++++-
 include/trace/events/v4l2.h       |  75 +++++++----
 include/trace/events/writeback.h  |  33 +++--
 include/trace/ftrace.h            |  11 ++
 kernel/module.c                   |   3 +
 kernel/trace/trace.c              | 260 +++++++++++++++++++++++++++++++++++++-
 14 files changed, 598 insertions(+), 149 deletions(-)

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

* [RFC][PATCH 01/10] tracing: Add TRACE_DEFINE_ENUM() macro to map enums to their values
  2015-03-27 21:37 [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Steven Rostedt
@ 2015-03-27 21:37 ` Steven Rostedt
  2015-03-30  2:27   ` Namhyung Kim
  2015-03-27 21:37 ` [RFC][PATCH 02/10] tracing: Allow for modules to export their trace enums as well Steven Rostedt
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Steven Rostedt @ 2015-03-27 21:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ingo Molnar, Andrew Morton, Namhyung Kim, Masami Hiramatsu,
	Mathieu Desnoyers, Guilherme Cox, Tony Luck, Xie XiuQi

[-- Attachment #1: 0001-tracing-Add-TRACE_DEFINE_ENUM-macro-to-map-enums-to-.patch --]
[-- Type: text/plain, Size: 7772 bytes --]

From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

Several tracepoints use the helper functions __print_symbolic() or
__print_flags() and pass in enums that do the mapping between the
binary data stored and the value to print. This works well for reading
the ASCII trace files, but when the data is read via userspace tools
such as perf and trace-cmd, the conversion of the binary value to a
human string format is lost if an enum is used, as userspace does not
have access to what the ENUM is.

For example, the tracepoint trace_tlb_flush() has:

 __print_symbolic(REC->reason,
    { TLB_FLUSH_ON_TASK_SWITCH, "flush on task switch" },
    { TLB_REMOTE_SHOOTDOWN, "remote shootdown" },
    { TLB_LOCAL_SHOOTDOWN, "local shootdown" },
    { TLB_LOCAL_MM_SHOOTDOWN, "local mm shootdown" })

Which maps the enum values to the strings they represent. But perf and
trace-cmd do no know what value TLB_LOCAL_MM_SHOOTDOWN is, and would
not be able to map it.

With TRACE_DEFINE_ENUM(), developers can place these in the event header
files and ftrace will export the value of the enum via the file:

 tracing/enum_map

By adding:

 TRACE_DEFINE_ENUM(TLB_FLUSH_ON_TASK_SWITCH);
 TRACE_DEFINE_ENUM(TLB_REMOTE_SHOOTDOWN);
 TRACE_DEFINE_ENUM(TLB_LOCAL_SHOOTDOWN);
 TRACE_DEFINE_ENUM(TLB_LOCAL_MM_SHOOTDOWN);

 $ cat /sys/kernel/debug/tracing/enum_map
TLB_FLUSH_ON_TASK_SWITCH 0
TLB_REMOTE_SHOOTDOWN 1
TLB_LOCAL_SHOOTDOWN 2
TLB_LOCAL_MM_SHOOTDOWN 3

The above can be easily parsed by userspace and it can be able to
convert the enums to their values and properly parse the enums within
the __print_symbolic() and __print_flags() helper functions.

Cc: Guilherme Cox <cox@computer.org>
Cc: Tony Luck <tony.luck@gmail.com>
Cc: Xie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 include/asm-generic/vmlinux.lds.h |   5 +-
 include/linux/tracepoint.h        |   7 +++
 include/trace/ftrace.h            |  11 ++++
 kernel/trace/trace.c              | 108 +++++++++++++++++++++++++++++++++++++-
 4 files changed, 129 insertions(+), 2 deletions(-)

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index ac78910d7416..f8e8b34dc427 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -124,7 +124,10 @@
 #define FTRACE_EVENTS()	. = ALIGN(8);					\
 			VMLINUX_SYMBOL(__start_ftrace_events) = .;	\
 			*(_ftrace_events)				\
-			VMLINUX_SYMBOL(__stop_ftrace_events) = .;
+			VMLINUX_SYMBOL(__stop_ftrace_events) = .;	\
+			VMLINUX_SYMBOL(__start_ftrace_enum_maps) = .;	\
+			*(_ftrace_enum_map)				\
+			VMLINUX_SYMBOL(__stop_ftrace_enum_maps) = .;
 #else
 #define FTRACE_EVENTS()
 #endif
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index c72851328ca9..587145af3525 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -36,6 +36,11 @@ struct tracepoint {
 	struct tracepoint_func __rcu *funcs;
 };
 
+struct trace_enum_map {
+	const char		*enum_string;
+	unsigned long		enum_value;
+};
+
 extern int
 tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data);
 extern int
@@ -87,6 +92,8 @@ extern void syscall_unregfunc(void);
 
 #define PARAMS(args...) args
 
+#define TRACE_DEFINE_ENUM(x)
+
 #endif /* _LINUX_TRACEPOINT_H */
 
 /*
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index 41bf65f04dd9..befa8d31672c 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -18,6 +18,14 @@
 
 #include <linux/ftrace_event.h>
 
+#undef TRACE_DEFINE_ENUM
+#define TRACE_DEFINE_ENUM(a)				\
+	static struct trace_enum_map __used __initdata	\
+	__##TRACE_SYSTEM##_##a = { #a, a };		\
+	static struct trace_enum_map __used		\
+	__attribute__((section("_ftrace_enum_map")))	\
+	*TRACE_SYSTEM##_##a = &__##TRACE_SYSTEM##_##a
+
 /*
  * DECLARE_EVENT_CLASS can be used to add a generic function
  * handlers for events. That is, if all events have the same
@@ -122,6 +130,9 @@
  * The size of an array is also encoded, in the higher 16 bits of <item>.
  */
 
+#undef TRACE_DEFINE_ENUM
+#define TRACE_DEFINE_ENUM(a)
+
 #undef __field
 #define __field(type, item)
 
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 62c6506d663f..53b449c522a7 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -123,6 +123,9 @@ enum ftrace_dump_mode ftrace_dump_on_oops;
 /* When set, tracing will stop when a WARN*() is hit */
 int __disable_trace_on_warning;
 
+/* Map of enums to their values, for "enum_map" file */
+static struct trace_enum_map *trace_enum_maps;
+
 static int tracing_set_tracer(struct trace_array *tr, const char *buf);
 
 #define MAX_TRACER_SIZE		100
@@ -3908,6 +3911,96 @@ static const struct file_operations tracing_saved_cmdlines_size_fops = {
 	.write		= tracing_saved_cmdlines_size_write,
 };
 
+static void *enum_map_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	struct trace_enum_map *ptr = v;
+
+	if (!ptr->enum_string)
+		return NULL;
+
+	ptr++;
+
+	(*pos)++;
+
+	if (!ptr->enum_string)
+		return NULL;
+
+	return ptr;
+}
+
+static void *enum_map_start(struct seq_file *m, loff_t *pos)
+{
+	struct trace_enum_map *v;
+	loff_t l = 0;
+
+	v = trace_enum_maps;
+	while (v && l < *pos) {
+		v = enum_map_next(m, v, &l);
+	}
+
+	return v;
+}
+
+static void enum_map_stop(struct seq_file *m, void *v)
+{
+}
+
+static int enum_map_show(struct seq_file *m, void *v)
+{
+	struct trace_enum_map *ptr = v;
+
+	seq_printf(m, "%s %ld\n", ptr->enum_string, ptr->enum_value);
+	return 0;
+}
+
+static const struct seq_operations tracing_enum_map_seq_ops = {
+	.start		= enum_map_start,
+	.next		= enum_map_next,
+	.stop		= enum_map_stop,
+	.show		= enum_map_show,
+};
+
+static int tracing_enum_map_open(struct inode *inode, struct file *filp)
+{
+	if (tracing_disabled)
+		return -ENODEV;
+
+	return seq_open(filp, &tracing_enum_map_seq_ops);
+}
+
+static const struct file_operations tracing_enum_map_fops = {
+	.open		= tracing_enum_map_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
+
+static void
+trace_insert_enum_map(struct trace_enum_map **start, struct trace_enum_map **stop)
+{
+	struct trace_enum_map **map;
+	struct trace_enum_map *map_array;
+	int len = stop - start;
+
+	if (len <= 0)
+		return;
+
+	map_array = kmalloc(sizeof(*map_array) * (len + 1), GFP_KERNEL);
+	if (!map_array) {
+		pr_warning("Unable to allocate trace enum mapping\n");
+		return;
+	}
+
+	trace_enum_maps = map_array;
+
+	for (map = start; (unsigned long)map < (unsigned long)stop; map++) {
+		*map_array = **map;
+		map_array++;
+	}
+	memset(map_array, 0, sizeof(*map_array));
+}
+
+
 static ssize_t
 tracing_set_trace_read(struct file *filp, char __user *ubuf,
 		       size_t cnt, loff_t *ppos)
@@ -6542,6 +6635,14 @@ struct dentry *tracing_init_dentry(void)
 	return tr->dir;
 }
 
+extern struct trace_enum_map *__start_ftrace_enum_maps[];
+extern struct trace_enum_map *__stop_ftrace_enum_maps[];
+
+static void __init trace_enum_init(void)
+{
+	trace_insert_enum_map(__start_ftrace_enum_maps, __stop_ftrace_enum_maps);
+}
+
 static __init int tracer_init_debugfs(void)
 {
 	struct dentry *d_tracer;
@@ -6566,6 +6667,11 @@ static __init int tracer_init_debugfs(void)
 	trace_create_file("saved_cmdlines_size", 0644, d_tracer,
 			  NULL, &tracing_saved_cmdlines_size_fops);
 
+	trace_enum_init();
+
+	trace_create_file("enum_map", 0444, d_tracer,
+			  NULL, &tracing_enum_map_fops);
+
 #ifdef CONFIG_DYNAMIC_FTRACE
 	trace_create_file("dyn_ftrace_total_info", 0444, d_tracer,
 			&ftrace_update_tot_cnt, &tracing_dyn_info_fops);
@@ -6888,7 +6994,7 @@ void __init trace_init(void)
 			tracepoint_printk = 0;
 	}
 	tracer_alloc_buffers();
-	trace_event_init();	
+	trace_event_init();
 }
 
 __init static int clear_boot_tracer(void)
-- 
2.1.4



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

* [RFC][PATCH 02/10] tracing: Allow for modules to export their trace enums as well
  2015-03-27 21:37 [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Steven Rostedt
  2015-03-27 21:37 ` [RFC][PATCH 01/10] tracing: Add TRACE_DEFINE_ENUM() macro to map enums to their values Steven Rostedt
@ 2015-03-27 21:37 ` Steven Rostedt
  2015-03-30  2:10   ` Rusty Russell
  2015-03-30  2:41   ` Namhyung Kim
  2015-03-27 21:37 ` [RFC][PATCH 03/10] x86/tlb/trace: Export enums in used by tlb_flush tracepoint Steven Rostedt
                   ` (9 subsequent siblings)
  11 siblings, 2 replies; 27+ messages in thread
From: Steven Rostedt @ 2015-03-27 21:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ingo Molnar, Andrew Morton, Namhyung Kim, Masami Hiramatsu,
	Mathieu Desnoyers, Rusty Russell

[-- Attachment #1: 0002-tracing-Allow-for-modules-to-export-their-trace-enum.patch --]
[-- Type: text/plain, Size: 8122 bytes --]

From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

Update the infrastructure such that modules that declare TRACE_DEFINE_ENUM()
will have those enums shown in the enum_map files in the tracing directory.

Cc: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 include/linux/module.h |   2 +
 kernel/module.c        |   3 +
 kernel/trace/trace.c   | 184 ++++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 173 insertions(+), 16 deletions(-)

diff --git a/include/linux/module.h b/include/linux/module.h
index 42999fe2dbd0..53dc41dd5c62 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -338,6 +338,8 @@ struct module {
 #ifdef CONFIG_EVENT_TRACING
 	struct ftrace_event_call **trace_events;
 	unsigned int num_trace_events;
+	struct trace_enum_map **trace_enums;
+	unsigned int num_trace_enums;
 #endif
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
 	unsigned int num_ftrace_callsites;
diff --git a/kernel/module.c b/kernel/module.c
index b3d634ed06c9..d8f8ab271c2b 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2753,6 +2753,9 @@ static int find_module_sections(struct module *mod, struct load_info *info)
 	mod->trace_events = section_objs(info, "_ftrace_events",
 					 sizeof(*mod->trace_events),
 					 &mod->num_trace_events);
+	mod->trace_enums = section_objs(info, "_ftrace_enum_map",
+					sizeof(*mod->trace_enums),
+					&mod->num_trace_enums);
 #endif
 #ifdef CONFIG_TRACING
 	mod->trace_bprintk_fmt_start = section_objs(info, "__trace_printk_fmt",
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 53b449c522a7..97031878eb3d 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -124,7 +124,38 @@ enum ftrace_dump_mode ftrace_dump_on_oops;
 int __disable_trace_on_warning;
 
 /* Map of enums to their values, for "enum_map" file */
-static struct trace_enum_map *trace_enum_maps;
+struct trace_enum_map_head {
+	struct module			*mod;
+	unsigned long			length;
+};
+
+union trace_enum_map_item;
+
+struct trace_enum_map_tail {
+	/*
+	 * "end" is first and points to NULL as it must be different
+	 * than "mod" or "enum_string"
+	 */
+	const char			*end;	/* points to NULL */
+	union trace_enum_map_item	*next;
+};
+
+static DEFINE_MUTEX(trace_enum_mutex);
+
+/*
+ * The trace_enum_maps are saved in an array whith two extra elements,
+ * one at the beginning, and one at the end. The beginning item contains
+ * the count of the saved maps (head.length), and the module they
+ * belong to if not built in (head.mod). The ending item contains a
+ * pointer to the next array of saved enum_map items.
+ */
+union trace_enum_map_item {
+	struct trace_enum_map		map;
+	struct trace_enum_map_head	head;
+	struct trace_enum_map_tail	tail;
+};
+
+static union trace_enum_map_item *trace_enum_maps;
 
 static int tracing_set_tracer(struct trace_array *tr, const char *buf);
 
@@ -3911,29 +3942,47 @@ static const struct file_operations tracing_saved_cmdlines_size_fops = {
 	.write		= tracing_saved_cmdlines_size_write,
 };
 
+static union trace_enum_map_item *
+update_enum_map(union trace_enum_map_item *ptr)
+{
+	if (!ptr->map.enum_string) {
+		if (ptr->tail.next) {
+			ptr = ptr->tail.next;
+			ptr++;
+		} else
+			return NULL;
+	}
+	return ptr;
+}
+
 static void *enum_map_next(struct seq_file *m, void *v, loff_t *pos)
 {
-	struct trace_enum_map *ptr = v;
+	union trace_enum_map_item *ptr = v;
 
-	if (!ptr->enum_string)
+	ptr = update_enum_map(ptr);
+	if (!ptr)
 		return NULL;
 
 	ptr++;
 
 	(*pos)++;
 
-	if (!ptr->enum_string)
-		return NULL;
+	ptr = update_enum_map(ptr);
 
 	return ptr;
 }
 
 static void *enum_map_start(struct seq_file *m, loff_t *pos)
 {
-	struct trace_enum_map *v;
+	union trace_enum_map_item *v;
 	loff_t l = 0;
 
+	mutex_lock(&trace_enum_mutex);
+
 	v = trace_enum_maps;
+	if (v)
+		v++;
+
 	while (v && l < *pos) {
 		v = enum_map_next(m, v, &l);
 	}
@@ -3943,13 +3992,15 @@ static void *enum_map_start(struct seq_file *m, loff_t *pos)
 
 static void enum_map_stop(struct seq_file *m, void *v)
 {
+	mutex_unlock(&trace_enum_mutex);
 }
 
 static int enum_map_show(struct seq_file *m, void *v)
 {
-	struct trace_enum_map *ptr = v;
+	union trace_enum_map_item *ptr = v;
+
+	seq_printf(m, "%s %ld\n", ptr->map.enum_string, ptr->map.enum_value);
 
-	seq_printf(m, "%s %ld\n", ptr->enum_string, ptr->enum_value);
 	return 0;
 }
 
@@ -3975,29 +4026,56 @@ static const struct file_operations tracing_enum_map_fops = {
 	.release	= seq_release,
 };
 
-static void
-trace_insert_enum_map(struct trace_enum_map **start, struct trace_enum_map **stop)
+static void trace_insert_enum_map(struct module *mod,
+				  struct trace_enum_map **start, int len)
 {
+	struct trace_enum_map **stop;
 	struct trace_enum_map **map;
-	struct trace_enum_map *map_array;
-	int len = stop - start;
+	union trace_enum_map_item *map_array;
+	union trace_enum_map_item *ptr;
 
 	if (len <= 0)
 		return;
 
-	map_array = kmalloc(sizeof(*map_array) * (len + 1), GFP_KERNEL);
+	stop = start + len;
+
+	/*
+	 * The trace_enum_maps contains the map plus a head and tail item,
+	 * where the head holds the module and length of array, and the
+	 * tail holds a pointer to the next list.
+	 */
+	map_array = kmalloc(sizeof(*map_array) * (len + 2), GFP_KERNEL);
 	if (!map_array) {
 		pr_warning("Unable to allocate trace enum mapping\n");
 		return;
 	}
 
-	trace_enum_maps = map_array;
+	mutex_lock(&trace_enum_mutex);
+
+	if (!trace_enum_maps)
+		trace_enum_maps = map_array;
+	else {
+		ptr = trace_enum_maps;
+		for (;;) {
+			ptr = ptr + ptr->head.length + 1;
+			if (!ptr->tail.next)
+				break;
+			ptr = ptr->tail.next;
+
+		}
+		ptr->tail.next = map_array;
+	}
+	map_array->head.mod = mod;
+	map_array->head.length = len;
+	map_array++;
 
 	for (map = start; (unsigned long)map < (unsigned long)stop; map++) {
-		*map_array = **map;
+		map_array->map = **map;
 		map_array++;
 	}
 	memset(map_array, 0, sizeof(*map_array));
+
+	mutex_unlock(&trace_enum_mutex);
 }
 
 
@@ -6640,9 +6718,79 @@ extern struct trace_enum_map *__stop_ftrace_enum_maps[];
 
 static void __init trace_enum_init(void)
 {
-	trace_insert_enum_map(__start_ftrace_enum_maps, __stop_ftrace_enum_maps);
+	int len;
+
+	len = __stop_ftrace_enum_maps - __start_ftrace_enum_maps;
+	trace_insert_enum_map(NULL, __start_ftrace_enum_maps, len);
 }
 
+#ifdef CONFIG_MODULES
+static void trace_module_add_enums(struct module *mod)
+{
+	if (!mod->num_trace_enums)
+		return;
+
+	/*
+	 * Modules with bad taint do not have events created, do
+	 * not bother with enums either.
+	 */
+	if (trace_module_has_bad_taint(mod))
+		return;
+
+	trace_insert_enum_map(mod, mod->trace_enums, mod->num_trace_enums);
+}
+
+static void trace_module_remove_enums(struct module *mod)
+{
+	union trace_enum_map_item *map;
+	union trace_enum_map_item **last = &trace_enum_maps;
+
+	if (!mod->num_trace_enums)
+		return;
+
+	mutex_lock(&trace_enum_mutex);
+
+	map = trace_enum_maps;
+
+	while (map) {
+		if (map->head.mod == mod)
+			break;
+		map += map->head.length + 1;
+		last = &map->tail.next;
+		map = map->tail.next;
+	}
+	if (!map)
+		goto out;
+
+	*last = map[map->head.length + 1].tail.next;
+	kfree(map);
+ out:
+	mutex_unlock(&trace_enum_mutex);
+}
+
+static int trace_module_notify(struct notifier_block *self,
+			       unsigned long val, void *data)
+{
+	struct module *mod = data;
+
+	switch (val) {
+	case MODULE_STATE_COMING:
+		trace_module_add_enums(mod);
+		break;
+	case MODULE_STATE_GOING:
+		trace_module_remove_enums(mod);
+		break;
+	}
+
+	return 0;
+}
+
+static struct notifier_block trace_module_nb = {
+	.notifier_call = trace_module_notify,
+	.priority = 0,
+};
+#endif
+
 static __init int tracer_init_debugfs(void)
 {
 	struct dentry *d_tracer;
@@ -6672,6 +6820,10 @@ static __init int tracer_init_debugfs(void)
 	trace_create_file("enum_map", 0444, d_tracer,
 			  NULL, &tracing_enum_map_fops);
 
+#ifdef CONFIG_MODULES
+	register_module_notifier(&trace_module_nb);
+#endif
+
 #ifdef CONFIG_DYNAMIC_FTRACE
 	trace_create_file("dyn_ftrace_total_info", 0444, d_tracer,
 			&ftrace_update_tot_cnt, &tracing_dyn_info_fops);
-- 
2.1.4



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

* [RFC][PATCH 03/10] x86/tlb/trace: Export enums in used by tlb_flush tracepoint
  2015-03-27 21:37 [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Steven Rostedt
  2015-03-27 21:37 ` [RFC][PATCH 01/10] tracing: Add TRACE_DEFINE_ENUM() macro to map enums to their values Steven Rostedt
  2015-03-27 21:37 ` [RFC][PATCH 02/10] tracing: Allow for modules to export their trace enums as well Steven Rostedt
@ 2015-03-27 21:37 ` Steven Rostedt
  2015-03-27 21:37 ` [RFC][PATCH 04/10] net/9p/tracing: Export enums in tracepoints to userspace Steven Rostedt
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Steven Rostedt @ 2015-03-27 21:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ingo Molnar, Andrew Morton, Namhyung Kim, Masami Hiramatsu,
	Mathieu Desnoyers, Dave Hansen

[-- Attachment #1: 0003-x86-tlb-trace-Export-enums-in-used-by-tlb_flush-trac.patch --]
[-- Type: text/plain, Size: 1644 bytes --]

From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

Have the enums used in __print_symbolic() by the trace_tlb_flush()
tracepoint exported to userpace such that they can be parsed by
userspace tools.

Cc: Dave Hansen <dave@sr71.net>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 include/trace/events/tlb.h | 30 +++++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/include/trace/events/tlb.h b/include/trace/events/tlb.h
index 0e7635765153..bee7e2cd97e7 100644
--- a/include/trace/events/tlb.h
+++ b/include/trace/events/tlb.h
@@ -7,11 +7,31 @@
 #include <linux/mm_types.h>
 #include <linux/tracepoint.h>
 
-#define TLB_FLUSH_REASON	\
-	{ TLB_FLUSH_ON_TASK_SWITCH,	"flush on task switch" },	\
-	{ TLB_REMOTE_SHOOTDOWN,		"remote shootdown" },		\
-	{ TLB_LOCAL_SHOOTDOWN,		"local shootdown" },		\
-	{ TLB_LOCAL_MM_SHOOTDOWN,	"local mm shootdown" }
+#define TLB_FLUSH_REASON						\
+	EM(  TLB_FLUSH_ON_TASK_SWITCH,	"flush on task switch" )	\
+	EM(  TLB_REMOTE_SHOOTDOWN,	"remote shootdown" )		\
+	EM(  TLB_LOCAL_SHOOTDOWN,	"local shootdown" )		\
+	EMe( TLB_LOCAL_MM_SHOOTDOWN,	"local mm shootdown" )
+
+/*
+ * First define the enums in TLB_FLUSH_REASON to be exported to userspace
+ * via TRACE_DEFINE_ENUM().
+ */
+#undef EM
+#undef EMe
+#define EM(a,b) TRACE_DEFINE_ENUM(a);
+#define EMe(a,b)	TRACE_DEFINE_ENUM(a);
+
+TLB_FLUSH_REASON
+
+/*
+ * Now redefine the EM() and EMe() macros to map the enums to the strings
+ * that will be printed in the output.
+ */
+#undef EM
+#undef EMe
+#define EM(a,b)		{ a, b },
+#define EMe(a,b)	{ a, b }
 
 TRACE_EVENT_CONDITION(tlb_flush,
 
-- 
2.1.4



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

* [RFC][PATCH 04/10] net/9p/tracing: Export enums in tracepoints to userspace
  2015-03-27 21:37 [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Steven Rostedt
                   ` (2 preceding siblings ...)
  2015-03-27 21:37 ` [RFC][PATCH 03/10] x86/tlb/trace: Export enums in used by tlb_flush tracepoint Steven Rostedt
@ 2015-03-27 21:37 ` Steven Rostedt
  2015-03-27 21:37 ` [RFC][PATCH 05/10] f2fs: Export the enums in the " Steven Rostedt
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Steven Rostedt @ 2015-03-27 21:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ingo Molnar, Andrew Morton, Namhyung Kim, Masami Hiramatsu,
	Mathieu Desnoyers, Aneesh Kumar K.V, Eric Van Hensbergen

[-- Attachment #1: 0004-net-9p-tracing-Export-enums-in-tracepoints-to-usersp.patch --]
[-- Type: text/plain, Size: 6698 bytes --]

From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

The tracepoints in the 9p code use a lot of enums for the __print_symbolic()
function. These enums are shown in the tracepoint format files, and user
space tools such as trace-cmd does not have the information to parse it.
Add helper macros to export the enums with TRACE_DEFINE_ENUM().

Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Cc: Eric Van Hensbergen <ericvh@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 include/trace/events/9p.h | 157 ++++++++++++++++++++++++++--------------------
 1 file changed, 88 insertions(+), 69 deletions(-)

diff --git a/include/trace/events/9p.h b/include/trace/events/9p.h
index a0666362c111..633ee9ee9778 100644
--- a/include/trace/events/9p.h
+++ b/include/trace/events/9p.h
@@ -6,76 +6,95 @@
 
 #include <linux/tracepoint.h>
 
+#define P9_MSG_T							\
+		EM( P9_TLERROR,		"P9_TLERROR" )			\
+		EM( P9_RLERROR,		"P9_RLERROR" )			\
+		EM( P9_TSTATFS,		"P9_TSTATFS" )			\
+		EM( P9_RSTATFS,		"P9_RSTATFS" )			\
+		EM( P9_TLOPEN,		"P9_TLOPEN" )			\
+		EM( P9_RLOPEN,		"P9_RLOPEN" )			\
+		EM( P9_TLCREATE,	"P9_TLCREATE" )			\
+		EM( P9_RLCREATE,	"P9_RLCREATE" )			\
+		EM( P9_TSYMLINK,	"P9_TSYMLINK" )			\
+		EM( P9_RSYMLINK,	"P9_RSYMLINK" )			\
+		EM( P9_TMKNOD,		"P9_TMKNOD" )			\
+		EM( P9_RMKNOD,		"P9_RMKNOD" )			\
+		EM( P9_TRENAME,		"P9_TRENAME" )			\
+		EM( P9_RRENAME,		"P9_RRENAME" )			\
+		EM( P9_TREADLINK,	"P9_TREADLINK" )		\
+		EM( P9_RREADLINK,	"P9_RREADLINK" )		\
+		EM( P9_TGETATTR,	"P9_TGETATTR" )			\
+		EM( P9_RGETATTR,	"P9_RGETATTR" )			\
+		EM( P9_TSETATTR,	"P9_TSETATTR" )			\
+		EM( P9_RSETATTR,	"P9_RSETATTR" )			\
+		EM( P9_TXATTRWALK,	"P9_TXATTRWALK" )		\
+		EM( P9_RXATTRWALK,	"P9_RXATTRWALK" )		\
+		EM( P9_TXATTRCREATE,	"P9_TXATTRCREATE" )		\
+		EM( P9_RXATTRCREATE,	"P9_RXATTRCREATE" )		\
+		EM( P9_TREADDIR,	"P9_TREADDIR" )			\
+		EM( P9_RREADDIR,	"P9_RREADDIR" )			\
+		EM( P9_TFSYNC,		"P9_TFSYNC" )			\
+		EM( P9_RFSYNC,		"P9_RFSYNC" )			\
+		EM( P9_TLOCK,		"P9_TLOCK" )			\
+		EM( P9_RLOCK,		"P9_RLOCK" )			\
+		EM( P9_TGETLOCK,	"P9_TGETLOCK" )			\
+		EM( P9_RGETLOCK,	"P9_RGETLOCK" )			\
+		EM( P9_TLINK,		"P9_TLINK" )			\
+		EM( P9_RLINK,		"P9_RLINK" )			\
+		EM( P9_TMKDIR,		"P9_TMKDIR" )			\
+		EM( P9_RMKDIR,		"P9_RMKDIR" )			\
+		EM( P9_TRENAMEAT,	"P9_TRENAMEAT" )		\
+		EM( P9_RRENAMEAT,	"P9_RRENAMEAT" )		\
+		EM( P9_TUNLINKAT,	"P9_TUNLINKAT" )		\
+		EM( P9_RUNLINKAT,	"P9_RUNLINKAT" )		\
+		EM( P9_TVERSION,	"P9_TVERSION" )			\
+		EM( P9_RVERSION,	"P9_RVERSION" )			\
+		EM( P9_TAUTH,		"P9_TAUTH" )			\
+		EM( P9_RAUTH,		"P9_RAUTH" )			\
+		EM( P9_TATTACH,		"P9_TATTACH" )			\
+		EM( P9_RATTACH,		"P9_RATTACH" )			\
+		EM( P9_TERROR,		"P9_TERROR" )			\
+		EM( P9_RERROR,		"P9_RERROR" )			\
+		EM( P9_TFLUSH,		"P9_TFLUSH" )			\
+		EM( P9_RFLUSH,		"P9_RFLUSH" )			\
+		EM( P9_TWALK,		"P9_TWALK" )			\
+		EM( P9_RWALK,		"P9_RWALK" )			\
+		EM( P9_TOPEN,		"P9_TOPEN" )			\
+		EM( P9_ROPEN,		"P9_ROPEN" )			\
+		EM( P9_TCREATE,		"P9_TCREATE" )			\
+		EM( P9_RCREATE,		"P9_RCREATE" )			\
+		EM( P9_TREAD,		"P9_TREAD" )			\
+		EM( P9_RREAD,		"P9_RREAD" )			\
+		EM( P9_TWRITE,		"P9_TWRITE" )			\
+		EM( P9_RWRITE,		"P9_RWRITE" )			\
+		EM( P9_TCLUNK,		"P9_TCLUNK" )			\
+		EM( P9_RCLUNK,		"P9_RCLUNK" )			\
+		EM( P9_TREMOVE,		"P9_TREMOVE" )			\
+		EM( P9_RREMOVE,		"P9_RREMOVE" )			\
+		EM( P9_TSTAT,		"P9_TSTAT" )			\
+		EM( P9_RSTAT,		"P9_RSTAT" )			\
+		EM( P9_TWSTAT,		"P9_TWSTAT" )			\
+		EMe(P9_RWSTAT,		"P9_RWSTAT" )
+
+/* Define EM() to export the enums to userspace via TRACE_DEFINE_ENUM() */
+#undef EM
+#undef EMe
+#define EM(a, b)	TRACE_DEFINE_ENUM(a);
+#define EMe(a, b)	TRACE_DEFINE_ENUM(a);
+
+P9_MSG_T
+
+/*
+ * Now redefine the EM() and EMe() macros to map the enums to the strings
+ * that will be printed in the output.
+ */
+#undef EM
+#undef EMe
+#define EM(a, b)	{ a, b },
+#define EMe(a, b)	{ a, b }
+
 #define show_9p_op(type)						\
-	__print_symbolic(type,						\
-			 { P9_TLERROR,		"P9_TLERROR" },		\
-			 { P9_RLERROR,		"P9_RLERROR" },		\
-			 { P9_TSTATFS,		"P9_TSTATFS" },		\
-			 { P9_RSTATFS,		"P9_RSTATFS" },		\
-			 { P9_TLOPEN,		"P9_TLOPEN" },		\
-			 { P9_RLOPEN,		"P9_RLOPEN" },		\
-			 { P9_TLCREATE,		"P9_TLCREATE" },	\
-			 { P9_RLCREATE,		"P9_RLCREATE" },	\
-			 { P9_TSYMLINK,		"P9_TSYMLINK" },	\
-			 { P9_RSYMLINK,		"P9_RSYMLINK" },	\
-			 { P9_TMKNOD,		"P9_TMKNOD" },		\
-			 { P9_RMKNOD,		"P9_RMKNOD" },		\
-			 { P9_TRENAME,		"P9_TRENAME" },		\
-			 { P9_RRENAME,		"P9_RRENAME" },		\
-			 { P9_TREADLINK,	"P9_TREADLINK" },	\
-			 { P9_RREADLINK,	"P9_RREADLINK" },	\
-			 { P9_TGETATTR,		"P9_TGETATTR" },	\
-			 { P9_RGETATTR,		"P9_RGETATTR" },	\
-			 { P9_TSETATTR,		"P9_TSETATTR" },	\
-			 { P9_RSETATTR,		"P9_RSETATTR" },	\
-			 { P9_TXATTRWALK,	"P9_TXATTRWALK" },	\
-			 { P9_RXATTRWALK,	"P9_RXATTRWALK" },	\
-			 { P9_TXATTRCREATE,	"P9_TXATTRCREATE" },	\
-			 { P9_RXATTRCREATE,	"P9_RXATTRCREATE" },	\
-			 { P9_TREADDIR,		"P9_TREADDIR" },	\
-			 { P9_RREADDIR,		"P9_RREADDIR" },	\
-			 { P9_TFSYNC,		"P9_TFSYNC" },		\
-			 { P9_RFSYNC,		"P9_RFSYNC" },		\
-			 { P9_TLOCK,		"P9_TLOCK" },		\
-			 { P9_RLOCK,		"P9_RLOCK" },		\
-			 { P9_TGETLOCK,		"P9_TGETLOCK" },	\
-			 { P9_RGETLOCK,		"P9_RGETLOCK" },	\
-			 { P9_TLINK,		"P9_TLINK" },		\
-			 { P9_RLINK,		"P9_RLINK" },		\
-			 { P9_TMKDIR,		"P9_TMKDIR" },		\
-			 { P9_RMKDIR,		"P9_RMKDIR" },		\
-			 { P9_TRENAMEAT,	"P9_TRENAMEAT" },	\
-			 { P9_RRENAMEAT,	"P9_RRENAMEAT" },	\
-			 { P9_TUNLINKAT,	"P9_TUNLINKAT" },	\
-			 { P9_RUNLINKAT,	"P9_RUNLINKAT" },	\
-			 { P9_TVERSION,		"P9_TVERSION" },	\
-			 { P9_RVERSION,		"P9_RVERSION" },	\
-			 { P9_TAUTH,		"P9_TAUTH" },		\
-			 { P9_RAUTH,		"P9_RAUTH" },		\
-			 { P9_TATTACH,		"P9_TATTACH" },		\
-			 { P9_RATTACH,		"P9_RATTACH" },		\
-			 { P9_TERROR,		"P9_TERROR" },		\
-			 { P9_RERROR,		"P9_RERROR" },		\
-			 { P9_TFLUSH,		"P9_TFLUSH" },		\
-			 { P9_RFLUSH,		"P9_RFLUSH" },		\
-			 { P9_TWALK,		"P9_TWALK" },		\
-			 { P9_RWALK,		"P9_RWALK" },		\
-			 { P9_TOPEN,		"P9_TOPEN" },		\
-			 { P9_ROPEN,		"P9_ROPEN" },		\
-			 { P9_TCREATE,		"P9_TCREATE" },		\
-			 { P9_RCREATE,		"P9_RCREATE" },		\
-			 { P9_TREAD,		"P9_TREAD" },		\
-			 { P9_RREAD,		"P9_RREAD" },		\
-			 { P9_TWRITE,		"P9_TWRITE" },		\
-			 { P9_RWRITE,		"P9_RWRITE" },		\
-			 { P9_TCLUNK,		"P9_TCLUNK" },		\
-			 { P9_RCLUNK,		"P9_RCLUNK" },		\
-			 { P9_TREMOVE,		"P9_TREMOVE" },		\
-			 { P9_RREMOVE,		"P9_RREMOVE" },		\
-			 { P9_TSTAT,		"P9_TSTAT" },		\
-			 { P9_RSTAT,		"P9_RSTAT" },		\
-			 { P9_TWSTAT,		"P9_TWSTAT" },		\
-			 { P9_RWSTAT,		"P9_RWSTAT" })
+	__print_symbolic(type, P9_MSG_T)
 
 TRACE_EVENT(9p_client_req,
 	    TP_PROTO(struct p9_client *clnt, int8_t type, int tag),
-- 
2.1.4



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

* [RFC][PATCH 05/10] f2fs: Export the enums in the tracepoints to userspace
  2015-03-27 21:37 [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Steven Rostedt
                   ` (3 preceding siblings ...)
  2015-03-27 21:37 ` [RFC][PATCH 04/10] net/9p/tracing: Export enums in tracepoints to userspace Steven Rostedt
@ 2015-03-27 21:37 ` Steven Rostedt
  2015-03-30  2:47   ` Namhyung Kim
  2015-03-27 21:37 ` [RFC][PATCH 06/10] irq/tracing: Export enums in tracepoints to user space Steven Rostedt
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Steven Rostedt @ 2015-03-27 21:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ingo Molnar, Andrew Morton, Namhyung Kim, Masami Hiramatsu,
	Mathieu Desnoyers, Namjae Jeon, Pankaj Kumar, Jaegeuk Kim

[-- Attachment #1: 0005-f2fs-Export-the-enums-in-the-tracepoints-to-userspac.patch --]
[-- Type: text/plain, Size: 1840 bytes --]

From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

The tracepoints that use __print_symbolic() use enums as the value
to convert to strings. Unfortunately, the format files for these
tracepoints show the enum name and not their value. This causes some
userspace tools not to know how to convert __print_symbolic() to
their strings.

Add TRACE_DEFINE_ENUM() macros to export the enums used to userspace
to let those tools know what those enum values are.

Cc: Namjae Jeon <namjae.jeon@samsung.com>
Cc: Pankaj Kumar <pankaj.km@samsung.com>
Cc: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 include/trace/events/f2fs.h | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h
index 5422dbfaf97d..a0074dd8d140 100644
--- a/include/trace/events/f2fs.h
+++ b/include/trace/events/f2fs.h
@@ -9,6 +9,27 @@
 #define show_dev(entry)		MAJOR(entry->dev), MINOR(entry->dev)
 #define show_dev_ino(entry)	show_dev(entry), (unsigned long)entry->ino
 
+TRACE_DEFINE_ENUM(NODE);
+TRACE_DEFINE_ENUM(DATA);
+TRACE_DEFINE_ENUM(META_FLUSH);
+TRACE_DEFINE_ENUM(CURSEG_HOT_DATA);
+TRACE_DEFINE_ENUM(CURSEG_WARM_DATA);
+TRACE_DEFINE_ENUM(CURSEG_COLD_DATA);
+TRACE_DEFINE_ENUM(CURSEG_HOT_NODE);
+TRACE_DEFINE_ENUM(CURSEG_WARM_NODE);
+TRACE_DEFINE_ENUM(CURSEG_COLD_NODE);
+TRACE_DEFINE_ENUM(NO_CHECK_TYPE);
+TRACE_DEFINE_ENUM(GC_GREEDY);
+TRACE_DEFINE_ENUM(GC_CB);
+TRACE_DEFINE_ENUM(__REQ_RAHEAD);
+TRACE_DEFINE_ENUM(__REQ_WRITE);
+TRACE_DEFINE_ENUM(__REQ_SYNC);
+TRACE_DEFINE_ENUM(__REQ_NOIDLE);
+TRACE_DEFINE_ENUM(__REQ_FLUSH);
+TRACE_DEFINE_ENUM(__REQ_FUA);
+TRACE_DEFINE_ENUM(__REQ_PRIO);
+TRACE_DEFINE_ENUM(__REQ_META);
+
 #define show_block_type(type)						\
 	__print_symbolic(type,						\
 		{ NODE,		"NODE" },				\
-- 
2.1.4



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

* [RFC][PATCH 06/10] irq/tracing: Export enums in tracepoints to user space
  2015-03-27 21:37 [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Steven Rostedt
                   ` (4 preceding siblings ...)
  2015-03-27 21:37 ` [RFC][PATCH 05/10] f2fs: Export the enums in the " Steven Rostedt
@ 2015-03-27 21:37 ` Steven Rostedt
  2015-03-27 21:46   ` Steven Rostedt
  2015-03-27 21:37 ` [RFC][PATCH 07/10] mm: tracing: " Steven Rostedt
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Steven Rostedt @ 2015-03-27 21:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ingo Molnar, Andrew Morton, Namhyung Kim, Masami Hiramatsu,
	Mathieu Desnoyers, Peter Zijlstra, Ingo Molnar

[-- Attachment #1: 0006-irq-tracing-Export-enums-in-tracepoints-to-user-spac.patch --]
[-- Type: text/plain, Size: 2075 bytes --]

From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

The enums used by the softirq mapping is what is shown in the output
of the __print_symbolic() and not their values, that are needed
to map them to their strings. Export them to userspace with the
TRACE_DEFINE_ENUM() macro so that user space tools can map the enums
with their values.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <molnar@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 include/trace/events/irq.h | 39 +++++++++++++++++++++++++++------------
 1 file changed, 27 insertions(+), 12 deletions(-)

diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h
index 3608bebd3d9c..ff8f6c091a15 100644
--- a/include/trace/events/irq.h
+++ b/include/trace/events/irq.h
@@ -9,19 +9,34 @@
 struct irqaction;
 struct softirq_action;
 
-#define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq }
+#define SOFTIRQ_NAME_LIST				\
+			 softirq_name(HI)		\
+			 softirq_name(TIMER)		\
+			 softirq_name(NET_TX)		\
+			 softirq_name(NET_RX)		\
+			 softirq_name(BLOCK)		\
+			 softirq_name(BLOCK_IOPOLL)	\
+			 softirq_name(TASKLET)		\
+			 softirq_name(SCHED)		\
+			 softirq_name(HRTIMER)		\
+			 softirq_name_end(RCU)
+
+#undef softirq_name
+#undef softirq_name_end
+
+#define softirq_name(sirq) TRACE_DEFINE_ENUM(sirq##_SOFTIRQ);
+#define softirq_name_end(sirq)  TRACE_DEFINE_ENUM(sirq##_SOFTIRQ);
+
+SOFTIRQ_NAME_LIST
+
+#undef softirq_name
+#undef softirq_name_end
+
+#define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq },
+#define softirq_name_end(sirq) { sirq##_SOFTIRQ, #sirq }
+
 #define show_softirq_name(val)				\
-	__print_symbolic(val,				\
-			 softirq_name(HI),		\
-			 softirq_name(TIMER),		\
-			 softirq_name(NET_TX),		\
-			 softirq_name(NET_RX),		\
-			 softirq_name(BLOCK),		\
-			 softirq_name(BLOCK_IOPOLL),	\
-			 softirq_name(TASKLET),		\
-			 softirq_name(SCHED),		\
-			 softirq_name(HRTIMER),		\
-			 softirq_name(RCU))
+	__print_symbolic(val, SOFTIRQ_NAME_LIST)
 
 /**
  * irq_handler_entry - called immediately before the irq action handler
-- 
2.1.4



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

* [RFC][PATCH 07/10] mm: tracing: Export enums in tracepoints to user space
  2015-03-27 21:37 [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Steven Rostedt
                   ` (5 preceding siblings ...)
  2015-03-27 21:37 ` [RFC][PATCH 06/10] irq/tracing: Export enums in tracepoints to user space Steven Rostedt
@ 2015-03-27 21:37 ` Steven Rostedt
  2015-03-27 21:37 ` [RFC][PATCH 08/10] SUNRPC: " Steven Rostedt
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Steven Rostedt @ 2015-03-27 21:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ingo Molnar, Andrew Morton, Namhyung Kim, Masami Hiramatsu,
	Mathieu Desnoyers

[-- Attachment #1: 0007-mm-tracing-Export-enums-in-tracepoints-to-user-space.patch --]
[-- Type: text/plain, Size: 2260 bytes --]

From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

The enums used in tracepoints with __print_symbolic() have their
names shown in the tracepoint format files and not their values.
This makes it difficult for user space tools to convert the binary
data to the strings as user space does not know what those enums
are about.

By having them use TRACE_DEFINE_ENUM(), the names of the enums will
be mapped to the values and shown to user space.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 include/trace/events/migrate.h | 42 ++++++++++++++++++++++++++++++++----------
 1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/include/trace/events/migrate.h b/include/trace/events/migrate.h
index dd2b5467d905..539b25a76111 100644
--- a/include/trace/events/migrate.h
+++ b/include/trace/events/migrate.h
@@ -7,18 +7,40 @@
 #include <linux/tracepoint.h>
 
 #define MIGRATE_MODE						\
-	{MIGRATE_ASYNC,		"MIGRATE_ASYNC"},		\
-	{MIGRATE_SYNC_LIGHT,	"MIGRATE_SYNC_LIGHT"},		\
-	{MIGRATE_SYNC,		"MIGRATE_SYNC"}		
+	EM( MIGRATE_ASYNC,	"MIGRATE_ASYNC")		\
+	EM( MIGRATE_SYNC_LIGHT,	"MIGRATE_SYNC_LIGHT")		\
+	EMe(MIGRATE_SYNC,	"MIGRATE_SYNC")
+
 
 #define MIGRATE_REASON						\
-	{MR_COMPACTION,		"compaction"},			\
-	{MR_MEMORY_FAILURE,	"memory_failure"},		\
-	{MR_MEMORY_HOTPLUG,	"memory_hotplug"},		\
-	{MR_SYSCALL,		"syscall_or_cpuset"},		\
-	{MR_MEMPOLICY_MBIND,	"mempolicy_mbind"},		\
-	{MR_NUMA_MISPLACED,	"numa_misplaced"},		\
-	{MR_CMA,		"cma"}
+	EM( MR_COMPACTION,	"compaction")			\
+	EM( MR_MEMORY_FAILURE,	"memory_failure")		\
+	EM( MR_MEMORY_HOTPLUG,	"memory_hotplug")		\
+	EM( MR_SYSCALL,		"syscall_or_cpuset")		\
+	EM( MR_MEMPOLICY_MBIND,	"mempolicy_mbind")		\
+	EM( MR_NUMA_MISPLACED,	"numa_misplaced")		\
+	EMe(MR_CMA,		"cma")
+
+/*
+ * First define the enums in the above macros to be exported to userspace
+ * via TRACE_DEFINE_ENUM().
+ */
+#undef EM
+#undef EMe
+#define EM(a, b)	TRACE_DEFINE_ENUM(a);
+#define EMe(a, b)	TRACE_DEFINE_ENUM(a);
+
+MIGRATE_MODE
+MIGRATE_REASON
+
+/*
+ * Now redefine the EM() and EMe() macros to map the enums to the strings
+ * that will be printed in the output.
+ */
+#undef EM
+#undef EMe
+#define EM(a, b)	{a, b},
+#define EMe(a, b)	{a, b}
 
 TRACE_EVENT(mm_migrate_pages,
 
-- 
2.1.4



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

* [RFC][PATCH 08/10] SUNRPC: Export enums in tracepoints to user space
  2015-03-27 21:37 [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Steven Rostedt
                   ` (6 preceding siblings ...)
  2015-03-27 21:37 ` [RFC][PATCH 07/10] mm: tracing: " Steven Rostedt
@ 2015-03-27 21:37 ` Steven Rostedt
  2015-03-27 21:37 ` [RFC][PATCH 09/10] v4l: Export enums used by " Steven Rostedt
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Steven Rostedt @ 2015-03-27 21:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ingo Molnar, Andrew Morton, Namhyung Kim, Masami Hiramatsu,
	Mathieu Desnoyers, Trond Myklebust

[-- Attachment #1: 0008-SUNRPC-Export-enums-in-tracepoints-to-user-space.patch --]
[-- Type: text/plain, Size: 2834 bytes --]

From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

The enums used in the tracepoints for __print_symbolic() have their
names shown in the tracepoint format files. User space tools do not know
how to convert those names into their values to be able to convert the
binary data.

Use TRACE_DEFINE_ENUM() to export the enum names to their values for
userspace to do the parsing correctly.

Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 include/trace/events/sunrpc.h | 62 ++++++++++++++++++++++++++++++-------------
 1 file changed, 44 insertions(+), 18 deletions(-)

diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h
index b9c1dc6c825a..fd1a02cb3c82 100644
--- a/include/trace/events/sunrpc.h
+++ b/include/trace/events/sunrpc.h
@@ -179,27 +179,53 @@ DEFINE_EVENT(rpc_task_queued, rpc_task_wakeup,
 
 );
 
+/*
+ * First define the enums in the below macros to be exported to userspace
+ * via TRACE_DEFINE_ENUM().
+ */
+#undef EM
+#undef EMe
+#define EM(a, b)	TRACE_DEFINE_ENUM(a);
+#define EMe(a, b)	TRACE_DEFINE_ENUM(a);
+
+#define RPC_SHOW_SOCKET				\
+	EM( SS_FREE, "FREE" )			\
+	EM( SS_UNCONNECTED, "UNCONNECTED" )	\
+	EM( SS_CONNECTING, "CONNECTING," )	\
+	EM( SS_CONNECTED, "CONNECTED," )	\
+	EMe(SS_DISCONNECTING, "DISCONNECTING" )
+
 #define rpc_show_socket_state(state) \
-	__print_symbolic(state, \
-		{ SS_FREE, "FREE" }, \
-		{ SS_UNCONNECTED, "UNCONNECTED" }, \
-		{ SS_CONNECTING, "CONNECTING," }, \
-		{ SS_CONNECTED, "CONNECTED," }, \
-		{ SS_DISCONNECTING, "DISCONNECTING" })
+	__print_symbolic(state, RPC_SHOW_SOCKET)
+
+RPC_SHOW_SOCKET
+
+#define RPC_SHOW_SOCK				\
+	EM( TCP_ESTABLISHED, "ESTABLISHED" )	\
+	EM( TCP_SYN_SENT, "SYN_SENT" )		\
+	EM( TCP_SYN_RECV, "SYN_RECV" )		\
+	EM( TCP_FIN_WAIT1, "FIN_WAIT1" )	\
+	EM( TCP_FIN_WAIT2, "FIN_WAIT2" )	\
+	EM( TCP_TIME_WAIT, "TIME_WAIT" )	\
+	EM( TCP_CLOSE, "CLOSE" )		\
+	EM( TCP_CLOSE_WAIT, "CLOSE_WAIT" )	\
+	EM( TCP_LAST_ACK, "LAST_ACK" )		\
+	EM( TCP_LISTEN, "LISTEN" )		\
+	EMe( TCP_CLOSING, "CLOSING" )
 
 #define rpc_show_sock_state(state) \
-	__print_symbolic(state, \
-		{ TCP_ESTABLISHED, "ESTABLISHED" }, \
-		{ TCP_SYN_SENT, "SYN_SENT" }, \
-		{ TCP_SYN_RECV, "SYN_RECV" }, \
-		{ TCP_FIN_WAIT1, "FIN_WAIT1" }, \
-		{ TCP_FIN_WAIT2, "FIN_WAIT2" }, \
-		{ TCP_TIME_WAIT, "TIME_WAIT" }, \
-		{ TCP_CLOSE, "CLOSE" }, \
-		{ TCP_CLOSE_WAIT, "CLOSE_WAIT" }, \
-		{ TCP_LAST_ACK, "LAST_ACK" }, \
-		{ TCP_LISTEN, "LISTEN" }, \
-		{ TCP_CLOSING, "CLOSING" })
+	__print_symbolic(state, RPC_SHOW_SOCK)
+
+RPC_SHOW_SOCK
+
+/*
+ * Now redefine the EM() and EMe() macros to map the enums to the strings
+ * that will be printed in the output.
+ */
+#undef EM
+#undef EMe
+#define EM(a, b)	{a, b},
+#define EMe(a, b)	{a, b}
 
 DECLARE_EVENT_CLASS(xs_socket_event,
 
-- 
2.1.4



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

* [RFC][PATCH 09/10] v4l: Export enums used by tracepoints to user space
  2015-03-27 21:37 [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Steven Rostedt
                   ` (7 preceding siblings ...)
  2015-03-27 21:37 ` [RFC][PATCH 08/10] SUNRPC: " Steven Rostedt
@ 2015-03-27 21:37 ` Steven Rostedt
  2015-03-28 13:00   ` Xie XiuQi
  2015-03-27 21:37 ` [RFC][PATCH 10/10] writeback: Export enums used by tracepoint " Steven Rostedt
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Steven Rostedt @ 2015-03-27 21:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ingo Molnar, Andrew Morton, Namhyung Kim, Masami Hiramatsu,
	Mathieu Desnoyers, Mauro Carvalho Chehab

[-- Attachment #1: 0009-v4l-Export-enums-used-by-tracepoints-to-user-space.patch --]
[-- Type: text/plain, Size: 4176 bytes --]

From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

Enums used by tracepoints for __print_symbolic() are shown in the
tracepoint format files with just their names and not their values.
This makes it difficult for user space tools to know how to convert the
binary data into their string representations.

By adding the use of TRACE_DEFINE_ENUM(), the enum names will be mapped
to their values and shown in the tracing file system to let tools
convert the data as necessary.

Cc: Mauro Carvalho Chehab <m.chehab@samsung.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 include/trace/events/v4l2.h | 75 ++++++++++++++++++++++++++++++---------------
 1 file changed, 50 insertions(+), 25 deletions(-)

diff --git a/include/trace/events/v4l2.h b/include/trace/events/v4l2.h
index b9bb1f204693..d96a0eadcb1d 100644
--- a/include/trace/events/v4l2.h
+++ b/include/trace/events/v4l2.h
@@ -6,33 +6,58 @@
 
 #include <linux/tracepoint.h>
 
-#define show_type(type)							       \
-	__print_symbolic(type,						       \
-		{ V4L2_BUF_TYPE_VIDEO_CAPTURE,	      "VIDEO_CAPTURE" },       \
-		{ V4L2_BUF_TYPE_VIDEO_OUTPUT,	      "VIDEO_OUTPUT" },	       \
-		{ V4L2_BUF_TYPE_VIDEO_OVERLAY,	      "VIDEO_OVERLAY" },       \
-		{ V4L2_BUF_TYPE_VBI_CAPTURE,	      "VBI_CAPTURE" },	       \
-		{ V4L2_BUF_TYPE_VBI_OUTPUT,	      "VBI_OUTPUT" },	       \
-		{ V4L2_BUF_TYPE_SLICED_VBI_CAPTURE,   "SLICED_VBI_CAPTURE" },  \
-		{ V4L2_BUF_TYPE_SLICED_VBI_OUTPUT,    "SLICED_VBI_OUTPUT" },   \
-		{ V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY, "VIDEO_OUTPUT_OVERLAY" },\
-		{ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, "VIDEO_CAPTURE_MPLANE" },\
-		{ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,  "VIDEO_OUTPUT_MPLANE" }, \
-		{ V4L2_BUF_TYPE_SDR_CAPTURE,          "SDR_CAPTURE" },         \
-		{ V4L2_BUF_TYPE_PRIVATE,	      "PRIVATE" })
+/* Enums require being exported to userspace, for user tool parsing */
+#undef EM
+#undef EMe
+#define EM(a, b)	TRACE_DEFINE_ENUM(a);
+#define EMe(a, b)	TRACE_DEFINE_ENUM(a);
+
+#define show_type(type)							\
+	__print_symbolic(type, SHOW_TYPE)
+
+#define SHOW_TYPE							\
+	EM( V4L2_BUF_TYPE_VIDEO_CAPTURE,	"VIDEO_CAPTURE" )	\
+	EM( V4L2_BUF_TYPE_VIDEO_OUTPUT,		"VIDEO_OUTPUT" )	\
+	EM( V4L2_BUF_TYPE_VIDEO_OVERLAY,	"VIDEO_OVERLAY" )	\
+	EM( V4L2_BUF_TYPE_VBI_CAPTURE,		"VBI_CAPTURE" )		\
+	EM( V4L2_BUF_TYPE_VBI_OUTPUT,		"VBI_OUTPUT" )		\
+	EM( V4L2_BUF_TYPE_SLICED_VBI_CAPTURE,   "SLICED_VBI_CAPTURE" )	\
+	EM( V4L2_BUF_TYPE_SLICED_VBI_OUTPUT,    "SLICED_VBI_OUTPUT" )	\
+	EM( V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY, "VIDEO_OUTPUT_OVERLAY" ) \
+	EM( V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, "VIDEO_CAPTURE_MPLANE" ) \
+	EM( V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,  "VIDEO_OUTPUT_MPLANE" )	\
+	EM( V4L2_BUF_TYPE_SDR_CAPTURE,          "SDR_CAPTURE" )		\
+	EMe(V4L2_BUF_TYPE_PRIVATE,		"PRIVATE" )
+
+SHOW_TYPE
 
 #define show_field(field)						\
-	__print_symbolic(field,						\
-		{ V4L2_FIELD_ANY,		"ANY" },		\
-		{ V4L2_FIELD_NONE,		"NONE" },		\
-		{ V4L2_FIELD_TOP,		"TOP" },		\
-		{ V4L2_FIELD_BOTTOM,		"BOTTOM" },		\
-		{ V4L2_FIELD_INTERLACED,	"INTERLACED" },		\
-		{ V4L2_FIELD_SEQ_TB,		"SEQ_TB" },		\
-		{ V4L2_FIELD_SEQ_BT,		"SEQ_BT" },		\
-		{ V4L2_FIELD_ALTERNATE,		"ALTERNATE" },		\
-		{ V4L2_FIELD_INTERLACED_TB,	"INTERLACED_TB" },      \
-		{ V4L2_FIELD_INTERLACED_BT,	"INTERLACED_BT" })
+	__print_symbolic(field, SHOW_FIELD
+
+#define SHOW_FIELD							\
+	EM( V4L2_FIELD_ANY,		"ANY" )				\
+	EM( V4L2_FIELD_NONE,		"NONE" )			\
+	EM( V4L2_FIELD_TOP,		"TOP" )				\
+	EM( V4L2_FIELD_BOTTOM,		"BOTTOM" )			\
+	EM( V4L2_FIELD_INTERLACED,	"INTERLACED" )			\
+	EM( V4L2_FIELD_SEQ_TB,		"SEQ_TB" )			\
+	EM( V4L2_FIELD_SEQ_BT,		"SEQ_BT" )			\
+	EM( V4L2_FIELD_ALTERNATE,	"ALTERNATE" )			\
+	EM( V4L2_FIELD_INTERLACED_TB,	"INTERLACED_TB" )		\
+	EMe( V4L2_FIELD_INTERLACED_BT,	"INTERLACED_BT" )
+
+SHOW_FIELD
+
+/*
+ * Now redefine the EM() and EMe() macros to map the enums to the strings
+ * that will be printed in the output.
+ */
+#undef EM
+#undef EMe
+#define EM(a, b)	{a, b},
+#define EMe(a, b)	{a, b}
+
+/* V4L2_TC_TYPE_* are macros, not defines, they do not need processing */
 
 #define show_timecode_type(type)					\
 	__print_symbolic(type,						\
-- 
2.1.4



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

* [RFC][PATCH 10/10] writeback: Export enums used by tracepoint to user space
  2015-03-27 21:37 [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Steven Rostedt
                   ` (8 preceding siblings ...)
  2015-03-27 21:37 ` [RFC][PATCH 09/10] v4l: Export enums used by " Steven Rostedt
@ 2015-03-27 21:37 ` Steven Rostedt
  2015-03-30  3:38 ` [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Masami Hiramatsu
  2015-03-31 21:30 ` Dave Chinner
  11 siblings, 0 replies; 27+ messages in thread
From: Steven Rostedt @ 2015-03-27 21:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ingo Molnar, Andrew Morton, Namhyung Kim, Masami Hiramatsu,
	Mathieu Desnoyers, Dave Chinner, Jens Axboe

[-- Attachment #1: 0010-writeback-Export-enums-used-by-tracepoint-to-user-sp.patch --]
[-- Type: text/plain, Size: 2149 bytes --]

From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>

The enums used in tracepoints for __print_symbolic() do not have their
values shown in the tracepoint format files and this makes it difficult
for user space tools to convert the binary values to the strings they
are to represent.

Add TRACE_DEFINE_ENUM(x) macros to export the enum names to their values
to make the tracing output from user space tools more robust.

Cc: Dave Chinner <dchinner@redhat.com>
Cc: Jens Axboe <jaxboe@fusionio.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 include/trace/events/writeback.h | 33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h
index 5a14ead59696..880dd7437172 100644
--- a/include/trace/events/writeback.h
+++ b/include/trace/events/writeback.h
@@ -23,15 +23,32 @@
 		{I_REFERENCED,		"I_REFERENCED"}		\
 	)
 
+/* enums need to be exported to user space */
+#undef EM
+#undef EMe
+#define EM(a,b) 	TRACE_DEFINE_ENUM(a);
+#define EMe(a,b)	TRACE_DEFINE_ENUM(a);
+
 #define WB_WORK_REASON							\
-		{WB_REASON_BACKGROUND,		"background"},		\
-		{WB_REASON_TRY_TO_FREE_PAGES,	"try_to_free_pages"},	\
-		{WB_REASON_SYNC,		"sync"},		\
-		{WB_REASON_PERIODIC,		"periodic"},		\
-		{WB_REASON_LAPTOP_TIMER,	"laptop_timer"},	\
-		{WB_REASON_FREE_MORE_MEM,	"free_more_memory"},	\
-		{WB_REASON_FS_FREE_SPACE,	"fs_free_space"},	\
-		{WB_REASON_FORKER_THREAD,	"forker_thread"}
+	EM( WB_REASON_BACKGROUND,		"background")		\
+	EM( WB_REASON_TRY_TO_FREE_PAGES,	"try_to_free_pages")	\
+	EM( WB_REASON_SYNC,			"sync")			\
+	EM( WB_REASON_PERIODIC,			"periodic")		\
+	EM( WB_REASON_LAPTOP_TIMER,		"laptop_timer")		\
+	EM( WB_REASON_FREE_MORE_MEM,		"free_more_memory")	\
+	EM( WB_REASON_FS_FREE_SPACE,		"fs_free_space")	\
+	EMe(WB_REASON_FORKER_THREAD,		"forker_thread")
+
+WB_WORK_REASON
+
+/*
+ * Now redefine the EM() and EMe() macros to map the enums to the strings
+ * that will be printed in the output.
+ */
+#undef EM
+#undef EMe
+#define EM(a,b)		{ a, b },
+#define EMe(a,b)	{ a, b }
 
 struct wb_writeback_work;
 
-- 
2.1.4



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

* Re: [RFC][PATCH 06/10] irq/tracing: Export enums in tracepoints to user space
  2015-03-27 21:37 ` [RFC][PATCH 06/10] irq/tracing: Export enums in tracepoints to user space Steven Rostedt
@ 2015-03-27 21:46   ` Steven Rostedt
  0 siblings, 0 replies; 27+ messages in thread
From: Steven Rostedt @ 2015-03-27 21:46 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ingo Molnar, Andrew Morton, Namhyung Kim, Masami Hiramatsu,
	Mathieu Desnoyers, Peter Zijlstra, Ingo Molnar

On Fri, 27 Mar 2015 17:37:10 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:

> From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
> 
> The enums used by the softirq mapping is what is shown in the output
> of the __print_symbolic() and not their values, that are needed
> to map them to their strings. Export them to userspace with the
> TRACE_DEFINE_ENUM() macro so that user space tools can map the enums
> with their values.
> 
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Ingo Molnar <molnar@kernel.org>

Sorry Ingo,

That was suppose to be "mingo@kernel.org", that's what I get for hand
typing and not doing a cut and paste.

I'll fix it up in my repo.

-- Steve


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

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

* Re: [RFC][PATCH 09/10] v4l: Export enums used by tracepoints to user space
  2015-03-27 21:37 ` [RFC][PATCH 09/10] v4l: Export enums used by " Steven Rostedt
@ 2015-03-28 13:00   ` Xie XiuQi
  2015-03-28 16:20     ` Steven Rostedt
  0 siblings, 1 reply; 27+ messages in thread
From: Xie XiuQi @ 2015-03-28 13:00 UTC (permalink / raw)
  To: Steven Rostedt, linux-kernel
  Cc: Ingo Molnar, Andrew Morton, Namhyung Kim, Masami Hiramatsu,
	Mathieu Desnoyers, Mauro Carvalho Chehab

On 2015/3/28 5:37, Steven Rostedt wrote:

>  #define show_field(field)						\
> -	__print_symbolic(field,						\
> -		{ V4L2_FIELD_ANY,		"ANY" },		\
> -		{ V4L2_FIELD_NONE,		"NONE" },		\
> -		{ V4L2_FIELD_TOP,		"TOP" },		\
> -		{ V4L2_FIELD_BOTTOM,		"BOTTOM" },		\
> -		{ V4L2_FIELD_INTERLACED,	"INTERLACED" },		\
> -		{ V4L2_FIELD_SEQ_TB,		"SEQ_TB" },		\
> -		{ V4L2_FIELD_SEQ_BT,		"SEQ_BT" },		\
> -		{ V4L2_FIELD_ALTERNATE,		"ALTERNATE" },		\
> -		{ V4L2_FIELD_INTERLACED_TB,	"INTERLACED_TB" },      \
> -		{ V4L2_FIELD_INTERLACED_BT,	"INTERLACED_BT" })
> +	__print_symbolic(field, SHOW_FIELD

Hi Steve,

It is missing a right bracket ')' here.

Thanks,
	Xie XiuQi

> +
> +#define SHOW_FIELD							\
> +	EM( V4L2_FIELD_ANY,		"ANY" )				\
> +	EM( V4L2_FIELD_NONE,		"NONE" )			\
> +	EM( V4L2_FIELD_TOP,		"TOP" )				\


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

* Re: [RFC][PATCH 09/10] v4l: Export enums used by tracepoints to user space
  2015-03-28 13:00   ` Xie XiuQi
@ 2015-03-28 16:20     ` Steven Rostedt
  0 siblings, 0 replies; 27+ messages in thread
From: Steven Rostedt @ 2015-03-28 16:20 UTC (permalink / raw)
  To: Xie XiuQi
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Namhyung Kim,
	Masami Hiramatsu, Mathieu Desnoyers, Mauro Carvalho Chehab

On Sat, 28 Mar 2015 21:00:29 +0800
Xie XiuQi <xiexiuqi@huawei.com> wrote:

> On 2015/3/28 5:37, Steven Rostedt wrote:
> 
> >  #define show_field(field)						\
> > -	__print_symbolic(field,						\
> > -		{ V4L2_FIELD_ANY,		"ANY" },		\
> > -		{ V4L2_FIELD_NONE,		"NONE" },		\
> > -		{ V4L2_FIELD_TOP,		"TOP" },		\
> > -		{ V4L2_FIELD_BOTTOM,		"BOTTOM" },		\
> > -		{ V4L2_FIELD_INTERLACED,	"INTERLACED" },		\
> > -		{ V4L2_FIELD_SEQ_TB,		"SEQ_TB" },		\
> > -		{ V4L2_FIELD_SEQ_BT,		"SEQ_BT" },		\
> > -		{ V4L2_FIELD_ALTERNATE,		"ALTERNATE" },		\
> > -		{ V4L2_FIELD_INTERLACED_TB,	"INTERLACED_TB" },      \
> > -		{ V4L2_FIELD_INTERLACED_BT,	"INTERLACED_BT" })
> > +	__print_symbolic(field, SHOW_FIELD
> 
> Hi Steve,
> 
> It is missing a right bracket ')' here.
> 

Yep, I haven't run these through my full test suite yet. I only did
some basic tests (and haven't compiled all the modules yet). Wu's
autobot picked up this error.

-- Steve

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

* Re: [RFC][PATCH 02/10] tracing: Allow for modules to export their trace enums as well
  2015-03-27 21:37 ` [RFC][PATCH 02/10] tracing: Allow for modules to export their trace enums as well Steven Rostedt
@ 2015-03-30  2:10   ` Rusty Russell
  2015-03-30  2:41   ` Namhyung Kim
  1 sibling, 0 replies; 27+ messages in thread
From: Rusty Russell @ 2015-03-30  2:10 UTC (permalink / raw)
  To: Steven Rostedt, linux-kernel
  Cc: Ingo Molnar, Andrew Morton, Namhyung Kim, Masami Hiramatsu,
	Mathieu Desnoyers

Steven Rostedt <rostedt@goodmis.org> writes:

> From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
>
> Update the infrastructure such that modules that declare TRACE_DEFINE_ENUM()
> will have those enums shown in the enum_map files in the tracing directory.
>
> Cc: Rusty Russell <rusty@rustcorp.com.au>
> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>

Acked-by: Rusty Russell <rusty@rustcorp.com.au>

Cheers,
Rusty.

> ---
>  include/linux/module.h |   2 +
>  kernel/module.c        |   3 +
>  kernel/trace/trace.c   | 184 ++++++++++++++++++++++++++++++++++++++++++++-----
>  3 files changed, 173 insertions(+), 16 deletions(-)
>
> diff --git a/include/linux/module.h b/include/linux/module.h
> index 42999fe2dbd0..53dc41dd5c62 100644
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -338,6 +338,8 @@ struct module {
>  #ifdef CONFIG_EVENT_TRACING
>  	struct ftrace_event_call **trace_events;
>  	unsigned int num_trace_events;
> +	struct trace_enum_map **trace_enums;
> +	unsigned int num_trace_enums;
>  #endif
>  #ifdef CONFIG_FTRACE_MCOUNT_RECORD
>  	unsigned int num_ftrace_callsites;
> diff --git a/kernel/module.c b/kernel/module.c
> index b3d634ed06c9..d8f8ab271c2b 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -2753,6 +2753,9 @@ static int find_module_sections(struct module *mod, struct load_info *info)
>  	mod->trace_events = section_objs(info, "_ftrace_events",
>  					 sizeof(*mod->trace_events),
>  					 &mod->num_trace_events);
> +	mod->trace_enums = section_objs(info, "_ftrace_enum_map",
> +					sizeof(*mod->trace_enums),
> +					&mod->num_trace_enums);
>  #endif
>  #ifdef CONFIG_TRACING
>  	mod->trace_bprintk_fmt_start = section_objs(info, "__trace_printk_fmt",
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index 53b449c522a7..97031878eb3d 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -124,7 +124,38 @@ enum ftrace_dump_mode ftrace_dump_on_oops;
>  int __disable_trace_on_warning;
>  
>  /* Map of enums to their values, for "enum_map" file */
> -static struct trace_enum_map *trace_enum_maps;
> +struct trace_enum_map_head {
> +	struct module			*mod;
> +	unsigned long			length;
> +};
> +
> +union trace_enum_map_item;
> +
> +struct trace_enum_map_tail {
> +	/*
> +	 * "end" is first and points to NULL as it must be different
> +	 * than "mod" or "enum_string"
> +	 */
> +	const char			*end;	/* points to NULL */
> +	union trace_enum_map_item	*next;
> +};
> +
> +static DEFINE_MUTEX(trace_enum_mutex);
> +
> +/*
> + * The trace_enum_maps are saved in an array whith two extra elements,
> + * one at the beginning, and one at the end. The beginning item contains
> + * the count of the saved maps (head.length), and the module they
> + * belong to if not built in (head.mod). The ending item contains a
> + * pointer to the next array of saved enum_map items.
> + */
> +union trace_enum_map_item {
> +	struct trace_enum_map		map;
> +	struct trace_enum_map_head	head;
> +	struct trace_enum_map_tail	tail;
> +};
> +
> +static union trace_enum_map_item *trace_enum_maps;
>  
>  static int tracing_set_tracer(struct trace_array *tr, const char *buf);
>  
> @@ -3911,29 +3942,47 @@ static const struct file_operations tracing_saved_cmdlines_size_fops = {
>  	.write		= tracing_saved_cmdlines_size_write,
>  };
>  
> +static union trace_enum_map_item *
> +update_enum_map(union trace_enum_map_item *ptr)
> +{
> +	if (!ptr->map.enum_string) {
> +		if (ptr->tail.next) {
> +			ptr = ptr->tail.next;
> +			ptr++;
> +		} else
> +			return NULL;
> +	}
> +	return ptr;
> +}
> +
>  static void *enum_map_next(struct seq_file *m, void *v, loff_t *pos)
>  {
> -	struct trace_enum_map *ptr = v;
> +	union trace_enum_map_item *ptr = v;
>  
> -	if (!ptr->enum_string)
> +	ptr = update_enum_map(ptr);
> +	if (!ptr)
>  		return NULL;
>  
>  	ptr++;
>  
>  	(*pos)++;
>  
> -	if (!ptr->enum_string)
> -		return NULL;
> +	ptr = update_enum_map(ptr);
>  
>  	return ptr;
>  }
>  
>  static void *enum_map_start(struct seq_file *m, loff_t *pos)
>  {
> -	struct trace_enum_map *v;
> +	union trace_enum_map_item *v;
>  	loff_t l = 0;
>  
> +	mutex_lock(&trace_enum_mutex);
> +
>  	v = trace_enum_maps;
> +	if (v)
> +		v++;
> +
>  	while (v && l < *pos) {
>  		v = enum_map_next(m, v, &l);
>  	}
> @@ -3943,13 +3992,15 @@ static void *enum_map_start(struct seq_file *m, loff_t *pos)
>  
>  static void enum_map_stop(struct seq_file *m, void *v)
>  {
> +	mutex_unlock(&trace_enum_mutex);
>  }
>  
>  static int enum_map_show(struct seq_file *m, void *v)
>  {
> -	struct trace_enum_map *ptr = v;
> +	union trace_enum_map_item *ptr = v;
> +
> +	seq_printf(m, "%s %ld\n", ptr->map.enum_string, ptr->map.enum_value);
>  
> -	seq_printf(m, "%s %ld\n", ptr->enum_string, ptr->enum_value);
>  	return 0;
>  }
>  
> @@ -3975,29 +4026,56 @@ static const struct file_operations tracing_enum_map_fops = {
>  	.release	= seq_release,
>  };
>  
> -static void
> -trace_insert_enum_map(struct trace_enum_map **start, struct trace_enum_map **stop)
> +static void trace_insert_enum_map(struct module *mod,
> +				  struct trace_enum_map **start, int len)
>  {
> +	struct trace_enum_map **stop;
>  	struct trace_enum_map **map;
> -	struct trace_enum_map *map_array;
> -	int len = stop - start;
> +	union trace_enum_map_item *map_array;
> +	union trace_enum_map_item *ptr;
>  
>  	if (len <= 0)
>  		return;
>  
> -	map_array = kmalloc(sizeof(*map_array) * (len + 1), GFP_KERNEL);
> +	stop = start + len;
> +
> +	/*
> +	 * The trace_enum_maps contains the map plus a head and tail item,
> +	 * where the head holds the module and length of array, and the
> +	 * tail holds a pointer to the next list.
> +	 */
> +	map_array = kmalloc(sizeof(*map_array) * (len + 2), GFP_KERNEL);
>  	if (!map_array) {
>  		pr_warning("Unable to allocate trace enum mapping\n");
>  		return;
>  	}
>  
> -	trace_enum_maps = map_array;
> +	mutex_lock(&trace_enum_mutex);
> +
> +	if (!trace_enum_maps)
> +		trace_enum_maps = map_array;
> +	else {
> +		ptr = trace_enum_maps;
> +		for (;;) {
> +			ptr = ptr + ptr->head.length + 1;
> +			if (!ptr->tail.next)
> +				break;
> +			ptr = ptr->tail.next;
> +
> +		}
> +		ptr->tail.next = map_array;
> +	}
> +	map_array->head.mod = mod;
> +	map_array->head.length = len;
> +	map_array++;
>  
>  	for (map = start; (unsigned long)map < (unsigned long)stop; map++) {
> -		*map_array = **map;
> +		map_array->map = **map;
>  		map_array++;
>  	}
>  	memset(map_array, 0, sizeof(*map_array));
> +
> +	mutex_unlock(&trace_enum_mutex);
>  }
>  
>  
> @@ -6640,9 +6718,79 @@ extern struct trace_enum_map *__stop_ftrace_enum_maps[];
>  
>  static void __init trace_enum_init(void)
>  {
> -	trace_insert_enum_map(__start_ftrace_enum_maps, __stop_ftrace_enum_maps);
> +	int len;
> +
> +	len = __stop_ftrace_enum_maps - __start_ftrace_enum_maps;
> +	trace_insert_enum_map(NULL, __start_ftrace_enum_maps, len);
>  }
>  
> +#ifdef CONFIG_MODULES
> +static void trace_module_add_enums(struct module *mod)
> +{
> +	if (!mod->num_trace_enums)
> +		return;
> +
> +	/*
> +	 * Modules with bad taint do not have events created, do
> +	 * not bother with enums either.
> +	 */
> +	if (trace_module_has_bad_taint(mod))
> +		return;
> +
> +	trace_insert_enum_map(mod, mod->trace_enums, mod->num_trace_enums);
> +}
> +
> +static void trace_module_remove_enums(struct module *mod)
> +{
> +	union trace_enum_map_item *map;
> +	union trace_enum_map_item **last = &trace_enum_maps;
> +
> +	if (!mod->num_trace_enums)
> +		return;
> +
> +	mutex_lock(&trace_enum_mutex);
> +
> +	map = trace_enum_maps;
> +
> +	while (map) {
> +		if (map->head.mod == mod)
> +			break;
> +		map += map->head.length + 1;
> +		last = &map->tail.next;
> +		map = map->tail.next;
> +	}
> +	if (!map)
> +		goto out;
> +
> +	*last = map[map->head.length + 1].tail.next;
> +	kfree(map);
> + out:
> +	mutex_unlock(&trace_enum_mutex);
> +}
> +
> +static int trace_module_notify(struct notifier_block *self,
> +			       unsigned long val, void *data)
> +{
> +	struct module *mod = data;
> +
> +	switch (val) {
> +	case MODULE_STATE_COMING:
> +		trace_module_add_enums(mod);
> +		break;
> +	case MODULE_STATE_GOING:
> +		trace_module_remove_enums(mod);
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
> +static struct notifier_block trace_module_nb = {
> +	.notifier_call = trace_module_notify,
> +	.priority = 0,
> +};
> +#endif
> +
>  static __init int tracer_init_debugfs(void)
>  {
>  	struct dentry *d_tracer;
> @@ -6672,6 +6820,10 @@ static __init int tracer_init_debugfs(void)
>  	trace_create_file("enum_map", 0444, d_tracer,
>  			  NULL, &tracing_enum_map_fops);
>  
> +#ifdef CONFIG_MODULES
> +	register_module_notifier(&trace_module_nb);
> +#endif
> +
>  #ifdef CONFIG_DYNAMIC_FTRACE
>  	trace_create_file("dyn_ftrace_total_info", 0444, d_tracer,
>  			&ftrace_update_tot_cnt, &tracing_dyn_info_fops);
> -- 
> 2.1.4

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

* Re: [RFC][PATCH 01/10] tracing: Add TRACE_DEFINE_ENUM() macro to map enums to their values
  2015-03-27 21:37 ` [RFC][PATCH 01/10] tracing: Add TRACE_DEFINE_ENUM() macro to map enums to their values Steven Rostedt
@ 2015-03-30  2:27   ` Namhyung Kim
  0 siblings, 0 replies; 27+ messages in thread
From: Namhyung Kim @ 2015-03-30  2:27 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Masami Hiramatsu,
	Mathieu Desnoyers, Guilherme Cox, Tony Luck, Xie XiuQi

Hi Steve,

On Fri, Mar 27, 2015 at 05:37:05PM -0400, Steven Rostedt wrote:
> From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
> 
> Several tracepoints use the helper functions __print_symbolic() or
> __print_flags() and pass in enums that do the mapping between the
> binary data stored and the value to print. This works well for reading
> the ASCII trace files, but when the data is read via userspace tools
> such as perf and trace-cmd, the conversion of the binary value to a
> human string format is lost if an enum is used, as userspace does not
> have access to what the ENUM is.
> 
> For example, the tracepoint trace_tlb_flush() has:
> 
>  __print_symbolic(REC->reason,
>     { TLB_FLUSH_ON_TASK_SWITCH, "flush on task switch" },
>     { TLB_REMOTE_SHOOTDOWN, "remote shootdown" },
>     { TLB_LOCAL_SHOOTDOWN, "local shootdown" },
>     { TLB_LOCAL_MM_SHOOTDOWN, "local mm shootdown" })
> 
> Which maps the enum values to the strings they represent. But perf and
> trace-cmd do no know what value TLB_LOCAL_MM_SHOOTDOWN is, and would
> not be able to map it.
> 
> With TRACE_DEFINE_ENUM(), developers can place these in the event header
> files and ftrace will export the value of the enum via the file:
> 
>  tracing/enum_map
> 
> By adding:
> 
>  TRACE_DEFINE_ENUM(TLB_FLUSH_ON_TASK_SWITCH);
>  TRACE_DEFINE_ENUM(TLB_REMOTE_SHOOTDOWN);
>  TRACE_DEFINE_ENUM(TLB_LOCAL_SHOOTDOWN);
>  TRACE_DEFINE_ENUM(TLB_LOCAL_MM_SHOOTDOWN);
> 
>  $ cat /sys/kernel/debug/tracing/enum_map
> TLB_FLUSH_ON_TASK_SWITCH 0
> TLB_REMOTE_SHOOTDOWN 1
> TLB_LOCAL_SHOOTDOWN 2
> TLB_LOCAL_MM_SHOOTDOWN 3
> 
> The above can be easily parsed by userspace and it can be able to
> convert the enums to their values and properly parse the enums within
> the __print_symbolic() and __print_flags() helper functions.
> 
> Cc: Guilherme Cox <cox@computer.org>
> Cc: Tony Luck <tony.luck@gmail.com>
> Cc: Xie XiuQi <xiexiuqi@huawei.com>
> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
> ---

[SNIP]
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index 62c6506d663f..53b449c522a7 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -123,6 +123,9 @@ enum ftrace_dump_mode ftrace_dump_on_oops;
>  /* When set, tracing will stop when a WARN*() is hit */
>  int __disable_trace_on_warning;
>  
> +/* Map of enums to their values, for "enum_map" file */
> +static struct trace_enum_map *trace_enum_maps;
> +
>  static int tracing_set_tracer(struct trace_array *tr, const char *buf);
>  
>  #define MAX_TRACER_SIZE		100
> @@ -3908,6 +3911,96 @@ static const struct file_operations tracing_saved_cmdlines_size_fops = {
>  	.write		= tracing_saved_cmdlines_size_write,
>  };
>  
> +static void *enum_map_next(struct seq_file *m, void *v, loff_t *pos)
> +{
> +	struct trace_enum_map *ptr = v;
> +
> +	if (!ptr->enum_string)
> +		return NULL;

Do we really need to check NULL string here?  Seems like duplicated..

Thanks,
Namhyung


> +
> +	ptr++;
> +
> +	(*pos)++;
> +
> +	if (!ptr->enum_string)
> +		return NULL;
> +
> +	return ptr;
> +}
> +
> +static void *enum_map_start(struct seq_file *m, loff_t *pos)
> +{
> +	struct trace_enum_map *v;
> +	loff_t l = 0;
> +
> +	v = trace_enum_maps;
> +	while (v && l < *pos) {
> +		v = enum_map_next(m, v, &l);
> +	}
> +
> +	return v;
> +}
> +
> +static void enum_map_stop(struct seq_file *m, void *v)
> +{
> +}
> +
> +static int enum_map_show(struct seq_file *m, void *v)
> +{
> +	struct trace_enum_map *ptr = v;
> +
> +	seq_printf(m, "%s %ld\n", ptr->enum_string, ptr->enum_value);
> +	return 0;
> +}
> +
> +static const struct seq_operations tracing_enum_map_seq_ops = {
> +	.start		= enum_map_start,
> +	.next		= enum_map_next,
> +	.stop		= enum_map_stop,
> +	.show		= enum_map_show,
> +};
> +
> +static int tracing_enum_map_open(struct inode *inode, struct file *filp)
> +{
> +	if (tracing_disabled)
> +		return -ENODEV;
> +
> +	return seq_open(filp, &tracing_enum_map_seq_ops);
> +}
> +
> +static const struct file_operations tracing_enum_map_fops = {
> +	.open		= tracing_enum_map_open,
> +	.read		= seq_read,
> +	.llseek		= seq_lseek,
> +	.release	= seq_release,
> +};
> +
> +static void
> +trace_insert_enum_map(struct trace_enum_map **start, struct trace_enum_map **stop)
> +{
> +	struct trace_enum_map **map;
> +	struct trace_enum_map *map_array;
> +	int len = stop - start;
> +
> +	if (len <= 0)
> +		return;
> +
> +	map_array = kmalloc(sizeof(*map_array) * (len + 1), GFP_KERNEL);
> +	if (!map_array) {
> +		pr_warning("Unable to allocate trace enum mapping\n");
> +		return;
> +	}
> +
> +	trace_enum_maps = map_array;
> +
> +	for (map = start; (unsigned long)map < (unsigned long)stop; map++) {
> +		*map_array = **map;
> +		map_array++;
> +	}
> +	memset(map_array, 0, sizeof(*map_array));
> +}
> +
> +
>  static ssize_t
>  tracing_set_trace_read(struct file *filp, char __user *ubuf,
>  		       size_t cnt, loff_t *ppos)
> @@ -6542,6 +6635,14 @@ struct dentry *tracing_init_dentry(void)
>  	return tr->dir;
>  }
>  
> +extern struct trace_enum_map *__start_ftrace_enum_maps[];
> +extern struct trace_enum_map *__stop_ftrace_enum_maps[];
> +
> +static void __init trace_enum_init(void)
> +{
> +	trace_insert_enum_map(__start_ftrace_enum_maps, __stop_ftrace_enum_maps);
> +}
> +
>  static __init int tracer_init_debugfs(void)
>  {
>  	struct dentry *d_tracer;
> @@ -6566,6 +6667,11 @@ static __init int tracer_init_debugfs(void)
>  	trace_create_file("saved_cmdlines_size", 0644, d_tracer,
>  			  NULL, &tracing_saved_cmdlines_size_fops);
>  
> +	trace_enum_init();
> +
> +	trace_create_file("enum_map", 0444, d_tracer,
> +			  NULL, &tracing_enum_map_fops);
> +
>  #ifdef CONFIG_DYNAMIC_FTRACE
>  	trace_create_file("dyn_ftrace_total_info", 0444, d_tracer,
>  			&ftrace_update_tot_cnt, &tracing_dyn_info_fops);
> @@ -6888,7 +6994,7 @@ void __init trace_init(void)
>  			tracepoint_printk = 0;
>  	}
>  	tracer_alloc_buffers();
> -	trace_event_init();	
> +	trace_event_init();
>  }
>  
>  __init static int clear_boot_tracer(void)
> -- 
> 2.1.4
> 
> 
> --
> 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/

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

* Re: [RFC][PATCH 02/10] tracing: Allow for modules to export their trace enums as well
  2015-03-27 21:37 ` [RFC][PATCH 02/10] tracing: Allow for modules to export their trace enums as well Steven Rostedt
  2015-03-30  2:10   ` Rusty Russell
@ 2015-03-30  2:41   ` Namhyung Kim
  2015-03-30 13:48     ` Steven Rostedt
  1 sibling, 1 reply; 27+ messages in thread
From: Namhyung Kim @ 2015-03-30  2:41 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Masami Hiramatsu,
	Mathieu Desnoyers, Rusty Russell

On Fri, Mar 27, 2015 at 05:37:06PM -0400, Steven Rostedt wrote:
> From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
> 
> Update the infrastructure such that modules that declare TRACE_DEFINE_ENUM()
> will have those enums shown in the enum_map files in the tracing directory.
> 
> Cc: Rusty Russell <rusty@rustcorp.com.au>
> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
> ---
>  include/linux/module.h |   2 +
>  kernel/module.c        |   3 +
>  kernel/trace/trace.c   | 184 ++++++++++++++++++++++++++++++++++++++++++++-----
>  3 files changed, 173 insertions(+), 16 deletions(-)
> 
> diff --git a/include/linux/module.h b/include/linux/module.h
> index 42999fe2dbd0..53dc41dd5c62 100644
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -338,6 +338,8 @@ struct module {
>  #ifdef CONFIG_EVENT_TRACING
>  	struct ftrace_event_call **trace_events;
>  	unsigned int num_trace_events;
> +	struct trace_enum_map **trace_enums;
> +	unsigned int num_trace_enums;
>  #endif
>  #ifdef CONFIG_FTRACE_MCOUNT_RECORD
>  	unsigned int num_ftrace_callsites;
> diff --git a/kernel/module.c b/kernel/module.c
> index b3d634ed06c9..d8f8ab271c2b 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -2753,6 +2753,9 @@ static int find_module_sections(struct module *mod, struct load_info *info)
>  	mod->trace_events = section_objs(info, "_ftrace_events",
>  					 sizeof(*mod->trace_events),
>  					 &mod->num_trace_events);
> +	mod->trace_enums = section_objs(info, "_ftrace_enum_map",
> +					sizeof(*mod->trace_enums),
> +					&mod->num_trace_enums);
>  #endif
>  #ifdef CONFIG_TRACING
>  	mod->trace_bprintk_fmt_start = section_objs(info, "__trace_printk_fmt",
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index 53b449c522a7..97031878eb3d 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -124,7 +124,38 @@ enum ftrace_dump_mode ftrace_dump_on_oops;
>  int __disable_trace_on_warning;
>  
>  /* Map of enums to their values, for "enum_map" file */
> -static struct trace_enum_map *trace_enum_maps;
> +struct trace_enum_map_head {
> +	struct module			*mod;
> +	unsigned long			length;
> +};
> +
> +union trace_enum_map_item;
> +
> +struct trace_enum_map_tail {
> +	/*
> +	 * "end" is first and points to NULL as it must be different
> +	 * than "mod" or "enum_string"
> +	 */
> +	const char			*end;	/* points to NULL */
> +	union trace_enum_map_item	*next;
> +};
> +
> +static DEFINE_MUTEX(trace_enum_mutex);
> +
> +/*
> + * The trace_enum_maps are saved in an array whith two extra elements,

s/whith/with/

> + * one at the beginning, and one at the end. The beginning item contains
> + * the count of the saved maps (head.length), and the module they
> + * belong to if not built in (head.mod). The ending item contains a
> + * pointer to the next array of saved enum_map items.
> + */
> +union trace_enum_map_item {
> +	struct trace_enum_map		map;
> +	struct trace_enum_map_head	head;
> +	struct trace_enum_map_tail	tail;
> +};
> +
> +static union trace_enum_map_item *trace_enum_maps;
>  
>  static int tracing_set_tracer(struct trace_array *tr, const char *buf);
>  
> @@ -3911,29 +3942,47 @@ static const struct file_operations tracing_saved_cmdlines_size_fops = {
>  	.write		= tracing_saved_cmdlines_size_write,
>  };
>  
> +static union trace_enum_map_item *
> +update_enum_map(union trace_enum_map_item *ptr)
> +{
> +	if (!ptr->map.enum_string) {
> +		if (ptr->tail.next) {
> +			ptr = ptr->tail.next;
> +			ptr++;

I guess this additional increment is to skip head item.  Maybe it
deserves a comment. :)


> +		} else
> +			return NULL;
> +	}
> +	return ptr;
> +}
> +
>  static void *enum_map_next(struct seq_file *m, void *v, loff_t *pos)
>  {
> -	struct trace_enum_map *ptr = v;
> +	union trace_enum_map_item *ptr = v;
>  
> -	if (!ptr->enum_string)
> +	ptr = update_enum_map(ptr);

Again, is this necessary?


> +	if (!ptr)
>  		return NULL;
>  
>  	ptr++;
>  
>  	(*pos)++;
>  
> -	if (!ptr->enum_string)
> -		return NULL;
> +	ptr = update_enum_map(ptr);
>  
>  	return ptr;
>  }
>  
>  static void *enum_map_start(struct seq_file *m, loff_t *pos)
>  {
> -	struct trace_enum_map *v;
> +	union trace_enum_map_item *v;
>  	loff_t l = 0;
>  
> +	mutex_lock(&trace_enum_mutex);
> +
>  	v = trace_enum_maps;
> +	if (v)
> +		v++;
> +
>  	while (v && l < *pos) {
>  		v = enum_map_next(m, v, &l);
>  	}
> @@ -3943,13 +3992,15 @@ static void *enum_map_start(struct seq_file *m, loff_t *pos)
>  
>  static void enum_map_stop(struct seq_file *m, void *v)
>  {
> +	mutex_unlock(&trace_enum_mutex);
>  }
>  
>  static int enum_map_show(struct seq_file *m, void *v)
>  {
> -	struct trace_enum_map *ptr = v;
> +	union trace_enum_map_item *ptr = v;
> +
> +	seq_printf(m, "%s %ld\n", ptr->map.enum_string, ptr->map.enum_value);
>  
> -	seq_printf(m, "%s %ld\n", ptr->enum_string, ptr->enum_value);
>  	return 0;
>  }
>  
> @@ -3975,29 +4026,56 @@ static const struct file_operations tracing_enum_map_fops = {
>  	.release	= seq_release,
>  };
>  
> -static void
> -trace_insert_enum_map(struct trace_enum_map **start, struct trace_enum_map **stop)
> +static void trace_insert_enum_map(struct module *mod,
> +				  struct trace_enum_map **start, int len)
>  {
> +	struct trace_enum_map **stop;
>  	struct trace_enum_map **map;
> -	struct trace_enum_map *map_array;
> -	int len = stop - start;
> +	union trace_enum_map_item *map_array;
> +	union trace_enum_map_item *ptr;
>  
>  	if (len <= 0)
>  		return;
>  
> -	map_array = kmalloc(sizeof(*map_array) * (len + 1), GFP_KERNEL);
> +	stop = start + len;
> +
> +	/*
> +	 * The trace_enum_maps contains the map plus a head and tail item,
> +	 * where the head holds the module and length of array, and the
> +	 * tail holds a pointer to the next list.
> +	 */
> +	map_array = kmalloc(sizeof(*map_array) * (len + 2), GFP_KERNEL);
>  	if (!map_array) {
>  		pr_warning("Unable to allocate trace enum mapping\n");
>  		return;
>  	}
>  
> -	trace_enum_maps = map_array;
> +	mutex_lock(&trace_enum_mutex);
> +
> +	if (!trace_enum_maps)
> +		trace_enum_maps = map_array;
> +	else {
> +		ptr = trace_enum_maps;
> +		for (;;) {
> +			ptr = ptr + ptr->head.length + 1;

Looks like access to tail item is used frequently.  How about adding a
helper function like enum_maps_tail_item()?

Thanks,
Namhyung

> +			if (!ptr->tail.next)
> +				break;
> +			ptr = ptr->tail.next;
> +
> +		}
> +		ptr->tail.next = map_array;
> +	}
> +	map_array->head.mod = mod;
> +	map_array->head.length = len;
> +	map_array++;
>  
>  	for (map = start; (unsigned long)map < (unsigned long)stop; map++) {
> -		*map_array = **map;
> +		map_array->map = **map;
>  		map_array++;
>  	}
>  	memset(map_array, 0, sizeof(*map_array));
> +
> +	mutex_unlock(&trace_enum_mutex);
>  }
>  
>  
> @@ -6640,9 +6718,79 @@ extern struct trace_enum_map *__stop_ftrace_enum_maps[];
>  
>  static void __init trace_enum_init(void)
>  {
> -	trace_insert_enum_map(__start_ftrace_enum_maps, __stop_ftrace_enum_maps);
> +	int len;
> +
> +	len = __stop_ftrace_enum_maps - __start_ftrace_enum_maps;
> +	trace_insert_enum_map(NULL, __start_ftrace_enum_maps, len);
>  }
>  
> +#ifdef CONFIG_MODULES
> +static void trace_module_add_enums(struct module *mod)
> +{
> +	if (!mod->num_trace_enums)
> +		return;
> +
> +	/*
> +	 * Modules with bad taint do not have events created, do
> +	 * not bother with enums either.
> +	 */
> +	if (trace_module_has_bad_taint(mod))
> +		return;
> +
> +	trace_insert_enum_map(mod, mod->trace_enums, mod->num_trace_enums);
> +}
> +
> +static void trace_module_remove_enums(struct module *mod)
> +{
> +	union trace_enum_map_item *map;
> +	union trace_enum_map_item **last = &trace_enum_maps;
> +
> +	if (!mod->num_trace_enums)
> +		return;
> +
> +	mutex_lock(&trace_enum_mutex);
> +
> +	map = trace_enum_maps;
> +
> +	while (map) {
> +		if (map->head.mod == mod)
> +			break;
> +		map += map->head.length + 1;
> +		last = &map->tail.next;
> +		map = map->tail.next;
> +	}
> +	if (!map)
> +		goto out;
> +
> +	*last = map[map->head.length + 1].tail.next;
> +	kfree(map);
> + out:
> +	mutex_unlock(&trace_enum_mutex);
> +}
> +
> +static int trace_module_notify(struct notifier_block *self,
> +			       unsigned long val, void *data)
> +{
> +	struct module *mod = data;
> +
> +	switch (val) {
> +	case MODULE_STATE_COMING:
> +		trace_module_add_enums(mod);
> +		break;
> +	case MODULE_STATE_GOING:
> +		trace_module_remove_enums(mod);
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
> +static struct notifier_block trace_module_nb = {
> +	.notifier_call = trace_module_notify,
> +	.priority = 0,
> +};
> +#endif
> +
>  static __init int tracer_init_debugfs(void)
>  {
>  	struct dentry *d_tracer;
> @@ -6672,6 +6820,10 @@ static __init int tracer_init_debugfs(void)
>  	trace_create_file("enum_map", 0444, d_tracer,
>  			  NULL, &tracing_enum_map_fops);
>  
> +#ifdef CONFIG_MODULES
> +	register_module_notifier(&trace_module_nb);
> +#endif
> +
>  #ifdef CONFIG_DYNAMIC_FTRACE
>  	trace_create_file("dyn_ftrace_total_info", 0444, d_tracer,
>  			&ftrace_update_tot_cnt, &tracing_dyn_info_fops);
> -- 
> 2.1.4
> 
> 
> --
> 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/

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

* Re: [RFC][PATCH 05/10] f2fs: Export the enums in the tracepoints to userspace
  2015-03-27 21:37 ` [RFC][PATCH 05/10] f2fs: Export the enums in the " Steven Rostedt
@ 2015-03-30  2:47   ` Namhyung Kim
  2015-03-30 13:49     ` Steven Rostedt
  0 siblings, 1 reply; 27+ messages in thread
From: Namhyung Kim @ 2015-03-30  2:47 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Masami Hiramatsu,
	Mathieu Desnoyers, Namjae Jeon, Pankaj Kumar, Jaegeuk Kim

On Fri, Mar 27, 2015 at 05:37:09PM -0400, Steven Rostedt wrote:
> From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
> 
> The tracepoints that use __print_symbolic() use enums as the value
> to convert to strings. Unfortunately, the format files for these
> tracepoints show the enum name and not their value. This causes some
> userspace tools not to know how to convert __print_symbolic() to
> their strings.
> 
> Add TRACE_DEFINE_ENUM() macros to export the enums used to userspace
> to let those tools know what those enum values are.
> 
> Cc: Namjae Jeon <namjae.jeon@samsung.com>
> Cc: Pankaj Kumar <pankaj.km@samsung.com>
> Cc: Jaegeuk Kim <jaegeuk.kim@samsung.com>

AFAIK Jaegeuk's samsung email is not valid anymore..

  $ grep -a Jaegeuk MAINTAINERS
  M:  Jaegeuk Kim <jaegeuk@kernel.org>


Thanks,
Namhyung


> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
> ---
>  include/trace/events/f2fs.h | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h
> index 5422dbfaf97d..a0074dd8d140 100644
> --- a/include/trace/events/f2fs.h
> +++ b/include/trace/events/f2fs.h
> @@ -9,6 +9,27 @@
>  #define show_dev(entry)		MAJOR(entry->dev), MINOR(entry->dev)
>  #define show_dev_ino(entry)	show_dev(entry), (unsigned long)entry->ino
>  
> +TRACE_DEFINE_ENUM(NODE);
> +TRACE_DEFINE_ENUM(DATA);
> +TRACE_DEFINE_ENUM(META_FLUSH);
> +TRACE_DEFINE_ENUM(CURSEG_HOT_DATA);
> +TRACE_DEFINE_ENUM(CURSEG_WARM_DATA);
> +TRACE_DEFINE_ENUM(CURSEG_COLD_DATA);
> +TRACE_DEFINE_ENUM(CURSEG_HOT_NODE);
> +TRACE_DEFINE_ENUM(CURSEG_WARM_NODE);
> +TRACE_DEFINE_ENUM(CURSEG_COLD_NODE);
> +TRACE_DEFINE_ENUM(NO_CHECK_TYPE);
> +TRACE_DEFINE_ENUM(GC_GREEDY);
> +TRACE_DEFINE_ENUM(GC_CB);
> +TRACE_DEFINE_ENUM(__REQ_RAHEAD);
> +TRACE_DEFINE_ENUM(__REQ_WRITE);
> +TRACE_DEFINE_ENUM(__REQ_SYNC);
> +TRACE_DEFINE_ENUM(__REQ_NOIDLE);
> +TRACE_DEFINE_ENUM(__REQ_FLUSH);
> +TRACE_DEFINE_ENUM(__REQ_FUA);
> +TRACE_DEFINE_ENUM(__REQ_PRIO);
> +TRACE_DEFINE_ENUM(__REQ_META);
> +
>  #define show_block_type(type)						\
>  	__print_symbolic(type,						\
>  		{ NODE,		"NODE" },				\
> -- 
> 2.1.4
> 
> 
> --
> 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/

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

* Re: [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values
  2015-03-27 21:37 [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Steven Rostedt
                   ` (9 preceding siblings ...)
  2015-03-27 21:37 ` [RFC][PATCH 10/10] writeback: Export enums used by tracepoint " Steven Rostedt
@ 2015-03-30  3:38 ` Masami Hiramatsu
  2015-03-30 14:07   ` Steven Rostedt
  2015-03-31 21:30 ` Dave Chinner
  11 siblings, 1 reply; 27+ messages in thread
From: Masami Hiramatsu @ 2015-03-30  3:38 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Namhyung Kim,
	Mathieu Desnoyers

(2015/03/28 6:37), Steven Rostedt wrote:
> As there are many tracepoints that use __print_symbolic() to translate
> numbers into ASCII strings, and several of these translate enums as
> well, it causes a problem for user space tools that read the tracepoint
> format files and have to translate the binary data to their associated
> strings.
> 
> For example, with the tlb_flush tracepoint, we have this in the format
> file:
> 
> print fmt: "pages:%ld reason:%s (%d)", REC->pages,
>  __print_symbolic(REC->reason,
>    { TLB_FLUSH_ON_TASK_SWITCH, "flush on task switch" },
>    { TLB_REMOTE_SHOOTDOWN, "remote shootdown" },
>    { TLB_LOCAL_SHOOTDOWN, "local shootdown" },
>    { TLB_LOCAL_MM_SHOOTDOWN, "local mm shootdown" }), REC->reason

Hmm, would user-space application really need to know the symbol name of enums?
If not, the event format files would better export the number(value) instead of
the enum name, like below.

 print fmt: "pages:%ld reason:%s (%d)", REC->pages,
  __print_symbolic(REC->reason,
    { 0, "flush on task switch" },
    { 1, "remote shootdown" },
    { 2, "local shootdown" },
    { 3, "local mm shootdown" }), REC->reason

I'm still not sure how we can code it :( (It seems that some trick we need when
showing the print fmt.)

> 
> Now, userspace does not know what the value of TLB_REMOTE_SHOOTDOWN is.
> To solve this, a new macro is created as a helper to allow tracepoints
> to export enums they use to userspace. This macro is called,
> TRACE_DEFINE_ENUM(), such that
> 
>  TRACE_DEFINE_ENUM(TLB_REMOTE_SHOOTDOWN);
> 
> Will export the TLB_REMOTE_SHOOTDOWN enum to use space.
> 
> How that is done is with a new file in the debugfs tracing directory.
> 
>  # cat /sys/kernel/debug/tracing/enum_map
> TLB_LOCAL_MM_SHOOTDOWN 3
> TLB_LOCAL_SHOOTDOWN 2
> TLB_REMOTE_SHOOTDOWN 1
> TLB_FLUSH_ON_TASK_SWITCH 0

BTW, if we can show the enum_map, can we also show the "symbolic" map
instead of using the __print_symbolic() ? :)

Thank you,

> 
> Now userspace, when seeing TLB_REMOTE_SHOOTDOWN in the format, knows
> that represents "1", and can do the conversions properly.
> 
> 
> Local SHA1: 6115e48a506e738f0f24771b4c87e4ba90d3d1c2
> 
> 
> Steven Rostedt (Red Hat) (10):
>       tracing: Add TRACE_DEFINE_ENUM() macro to map enums to their values
>       tracing: Allow for modules to export their trace enums as well
>       x86/tlb/trace: Export enums in used by tlb_flush tracepoint
>       net/9p/tracing: Export enums in tracepoints to userspace
>       f2fs: Export the enums in the tracepoints to userspace
>       irq/tracing: Export enums in tracepoints to user space
>       mm: tracing: Export enums in tracepoints to user space
>       SUNRPC: Export enums in tracepoints to user space
>       v4l: Export enums used by tracepoints to user space
>       writeback: Export enums used by tracepoint to user space
> 
> ----
>  include/asm-generic/vmlinux.lds.h |   5 +-
>  include/linux/module.h            |   2 +
>  include/linux/tracepoint.h        |   7 +
>  include/trace/events/9p.h         | 157 +++++++++++++----------
>  include/trace/events/f2fs.h       |  21 +++
>  include/trace/events/irq.h        |  39 ++++--
>  include/trace/events/migrate.h    |  42 ++++--
>  include/trace/events/sunrpc.h     |  62 ++++++---
>  include/trace/events/tlb.h        |  30 ++++-
>  include/trace/events/v4l2.h       |  75 +++++++----
>  include/trace/events/writeback.h  |  33 +++--
>  include/trace/ftrace.h            |  11 ++
>  kernel/module.c                   |   3 +
>  kernel/trace/trace.c              | 260 +++++++++++++++++++++++++++++++++++++-
>  14 files changed, 598 insertions(+), 149 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/
> 
> 


-- 
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Research Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt@hitachi.com



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

* Re: [RFC][PATCH 02/10] tracing: Allow for modules to export their trace enums as well
  2015-03-30  2:41   ` Namhyung Kim
@ 2015-03-30 13:48     ` Steven Rostedt
  0 siblings, 0 replies; 27+ messages in thread
From: Steven Rostedt @ 2015-03-30 13:48 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Masami Hiramatsu,
	Mathieu Desnoyers, Rusty Russell

On Mon, 30 Mar 2015 11:41:00 +0900
Namhyung Kim <namhyung@kernel.org> wrote:


> > + * The trace_enum_maps are saved in an array whith two extra elements,
> 
> s/whith/with/

Heh, thanks for catching that.

> 
> > + * one at the beginning, and one at the end. The beginning item contains
> > + * the count of the saved maps (head.length), and the module they
> > + * belong to if not built in (head.mod). The ending item contains a
> > + * pointer to the next array of saved enum_map items.
> > + */
> > +union trace_enum_map_item {
> > +	struct trace_enum_map		map;
> > +	struct trace_enum_map_head	head;
> > +	struct trace_enum_map_tail	tail;
> > +};
> > +
> > +static union trace_enum_map_item *trace_enum_maps;
> >  
> >  static int tracing_set_tracer(struct trace_array *tr, const char *buf);
> >  
> > @@ -3911,29 +3942,47 @@ static const struct file_operations tracing_saved_cmdlines_size_fops = {
> >  	.write		= tracing_saved_cmdlines_size_write,
> >  };
> >  
> > +static union trace_enum_map_item *
> > +update_enum_map(union trace_enum_map_item *ptr)
> > +{
> > +	if (!ptr->map.enum_string) {
> > +		if (ptr->tail.next) {
> > +			ptr = ptr->tail.next;
> > +			ptr++;
> 
> I guess this additional increment is to skip head item.  Maybe it
> deserves a comment. :)

Yep it does. I'll add one.

> 
> 
> > +		} else
> > +			return NULL;
> > +	}
> > +	return ptr;
> > +}
> > +
> >  static void *enum_map_next(struct seq_file *m, void *v, loff_t *pos)
> >  {
> > -	struct trace_enum_map *ptr = v;
> > +	union trace_enum_map_item *ptr = v;
> >  
> > -	if (!ptr->enum_string)
> > +	ptr = update_enum_map(ptr);
> 
> Again, is this necessary?

Not really, but I'm doing it to be paranoid. If for some reason 'ptr'
is at the tail end (which it should never happen), then the increment
below will cause an invalid pointer dereference.

I should at least add a comment here saying I'm being paranoid. It's
far from a fast path so I don't really care about slowing things down
here to be extra safe.

> 
> 
> > +	if (!ptr)
> >  		return NULL;
> >  
> >  	ptr++;
> >  
> >  	(*pos)++;
> >  
> > -	if (!ptr->enum_string)
> > -		return NULL;
> > +	ptr = update_enum_map(ptr);
> >  
> >  	return ptr;
> >  }
> >  



> > +	/*
> > +	 * The trace_enum_maps contains the map plus a head and tail item,
> > +	 * where the head holds the module and length of array, and the
> > +	 * tail holds a pointer to the next list.
> > +	 */
> > +	map_array = kmalloc(sizeof(*map_array) * (len + 2), GFP_KERNEL);
> >  	if (!map_array) {
> >  		pr_warning("Unable to allocate trace enum mapping\n");
> >  		return;
> >  	}
> >  
> > -	trace_enum_maps = map_array;
> > +	mutex_lock(&trace_enum_mutex);
> > +
> > +	if (!trace_enum_maps)
> > +		trace_enum_maps = map_array;
> > +	else {
> > +		ptr = trace_enum_maps;
> > +		for (;;) {
> > +			ptr = ptr + ptr->head.length + 1;
> 
> Looks like access to tail item is used frequently.  How about adding a
> helper function like enum_maps_tail_item()?

I'll look into it. Thanks for the review.

-- Steve


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

* Re: [RFC][PATCH 05/10] f2fs: Export the enums in the tracepoints to userspace
  2015-03-30  2:47   ` Namhyung Kim
@ 2015-03-30 13:49     ` Steven Rostedt
  0 siblings, 0 replies; 27+ messages in thread
From: Steven Rostedt @ 2015-03-30 13:49 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Masami Hiramatsu,
	Mathieu Desnoyers, Namjae Jeon, Pankaj Kumar, Jaegeuk Kim

On Mon, 30 Mar 2015 11:47:01 +0900
Namhyung Kim <namhyung@kernel.org> wrote:


> > Cc: Namjae Jeon <namjae.jeon@samsung.com>
> > Cc: Pankaj Kumar <pankaj.km@samsung.com>
> > Cc: Jaegeuk Kim <jaegeuk.kim@samsung.com>
> 
> AFAIK Jaegeuk's samsung email is not valid anymore..
> 
>   $ grep -a Jaegeuk MAINTAINERS
>   M:  Jaegeuk Kim <jaegeuk@kernel.org>
> 

Thanks. That's what I get for using git blame instead of looking at the
MAINTAINERS file.

-- Steve

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

* Re: [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values
  2015-03-30  3:38 ` [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Masami Hiramatsu
@ 2015-03-30 14:07   ` Steven Rostedt
  2015-03-31  7:36     ` Masami Hiramatsu
  0 siblings, 1 reply; 27+ messages in thread
From: Steven Rostedt @ 2015-03-30 14:07 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Namhyung Kim,
	Mathieu Desnoyers

On Mon, 30 Mar 2015 12:38:15 +0900
Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> wrote:

> (2015/03/28 6:37), Steven Rostedt wrote:
> > As there are many tracepoints that use __print_symbolic() to translate
> > numbers into ASCII strings, and several of these translate enums as
> > well, it causes a problem for user space tools that read the tracepoint
> > format files and have to translate the binary data to their associated
> > strings.
> > 
> > For example, with the tlb_flush tracepoint, we have this in the format
> > file:
> > 
> > print fmt: "pages:%ld reason:%s (%d)", REC->pages,
> >  __print_symbolic(REC->reason,
> >    { TLB_FLUSH_ON_TASK_SWITCH, "flush on task switch" },
> >    { TLB_REMOTE_SHOOTDOWN, "remote shootdown" },
> >    { TLB_LOCAL_SHOOTDOWN, "local shootdown" },
> >    { TLB_LOCAL_MM_SHOOTDOWN, "local mm shootdown" }), REC->reason
> 
> Hmm, would user-space application really need to know the symbol name of enums?
> If not, the event format files would better export the number(value) instead of
> the enum name, like below.
> 
>  print fmt: "pages:%ld reason:%s (%d)", REC->pages,
>   __print_symbolic(REC->reason,
>     { 0, "flush on task switch" },
>     { 1, "remote shootdown" },
>     { 2, "local shootdown" },
>     { 3, "local mm shootdown" }), REC->reason
> 
> I'm still not sure how we can code it :( (It seems that some trick we need when
> showing the print fmt.)


Believe me, I've tried tons of tricks. I even pulled out my "Elder MACRO
Wand", and it too could not execute the enum illuminous valueous (to
show both the enum name and value in the same output).

The problem is that an enum name is only known by the compiler itself.
The preprocessor does not know what an enum is. And after the compiler
is done, the enum name no longer exists, just its value.

Thus, I found no way to have print_fmt display the numbers instead of
the names.

Instead of adding an enum mapping file, I could add a way to look at
all the events in the system that defined a mapping, and do a
"s/ENUM_NAME/ENUM_VALUE/g" do the saved print formats? I'm not sure how
much we want to do that in the kernel though.

> 
> > 
> > Now, userspace does not know what the value of TLB_REMOTE_SHOOTDOWN is.
> > To solve this, a new macro is created as a helper to allow tracepoints
> > to export enums they use to userspace. This macro is called,
> > TRACE_DEFINE_ENUM(), such that
> > 
> >  TRACE_DEFINE_ENUM(TLB_REMOTE_SHOOTDOWN);
> > 
> > Will export the TLB_REMOTE_SHOOTDOWN enum to use space.
> > 
> > How that is done is with a new file in the debugfs tracing directory.
> > 
> >  # cat /sys/kernel/debug/tracing/enum_map
> > TLB_LOCAL_MM_SHOOTDOWN 3
> > TLB_LOCAL_SHOOTDOWN 2
> > TLB_REMOTE_SHOOTDOWN 1
> > TLB_FLUSH_ON_TASK_SWITCH 0
> 
> BTW, if we can show the enum_map, can we also show the "symbolic" map
> instead of using the __print_symbolic() ? :)

There's nothing mapping the two in the kernel. And worse yet, some
enums are used in operations. Just look at f2fs_submit_read_bio, where
in the __print_symbolic() it has:

	(1ULL << __REQ_NOIDLE) | ...

the __REQ_NOIDLE is an enum.

But, if I do just a substitution, then we wont even have to update
userspace tools. They should still work.

-- Steve

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

* Re: Re: [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values
  2015-03-30 14:07   ` Steven Rostedt
@ 2015-03-31  7:36     ` Masami Hiramatsu
  2015-03-31 13:26       ` Steven Rostedt
  0 siblings, 1 reply; 27+ messages in thread
From: Masami Hiramatsu @ 2015-03-31  7:36 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Namhyung Kim,
	Mathieu Desnoyers

(2015/03/30 23:07), Steven Rostedt wrote:
> On Mon, 30 Mar 2015 12:38:15 +0900
> Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> wrote:
> 
>> (2015/03/28 6:37), Steven Rostedt wrote:
>>> As there are many tracepoints that use __print_symbolic() to translate
>>> numbers into ASCII strings, and several of these translate enums as
>>> well, it causes a problem for user space tools that read the tracepoint
>>> format files and have to translate the binary data to their associated
>>> strings.
>>>
>>> For example, with the tlb_flush tracepoint, we have this in the format
>>> file:
>>>
>>> print fmt: "pages:%ld reason:%s (%d)", REC->pages,
>>>  __print_symbolic(REC->reason,
>>>    { TLB_FLUSH_ON_TASK_SWITCH, "flush on task switch" },
>>>    { TLB_REMOTE_SHOOTDOWN, "remote shootdown" },
>>>    { TLB_LOCAL_SHOOTDOWN, "local shootdown" },
>>>    { TLB_LOCAL_MM_SHOOTDOWN, "local mm shootdown" }), REC->reason
>>
>> Hmm, would user-space application really need to know the symbol name of enums?
>> If not, the event format files would better export the number(value) instead of
>> the enum name, like below.
>>
>>  print fmt: "pages:%ld reason:%s (%d)", REC->pages,
>>   __print_symbolic(REC->reason,
>>     { 0, "flush on task switch" },
>>     { 1, "remote shootdown" },
>>     { 2, "local shootdown" },
>>     { 3, "local mm shootdown" }), REC->reason
>>
>> I'm still not sure how we can code it :( (It seems that some trick we need when
>> showing the print fmt.)
> 
> 
> Believe me, I've tried tons of tricks. I even pulled out my "Elder MACRO
> Wand", and it too could not execute the enum illuminous valueous (to
> show both the enum name and value in the same output).
> 
> The problem is that an enum name is only known by the compiler itself.
> The preprocessor does not know what an enum is. And after the compiler
> is done, the enum name no longer exists, just its value.

Yeah, I see. Handling enums in macro is not possible.

> 
> Thus, I found no way to have print_fmt display the numbers instead of
> the names.
> 
> Instead of adding an enum mapping file, I could add a way to look at
> all the events in the system that defined a mapping, and do a
> "s/ENUM_NAME/ENUM_VALUE/g" do the saved print formats? I'm not sure how
> much we want to do that in the kernel though.

No, it's not what I expected...

What I thought was expanding __print_symbolic() macro in TP_printk
with a special hash string(start with #), and when showing it via
event/format, replace the hash string with the strings generated
by the map of symbols. This will introduce a small overhead to show
the format as a side effect.

Actually I even have not tried, so it's just an idea yet.

Thank you,

>>> Now, userspace does not know what the value of TLB_REMOTE_SHOOTDOWN is.
>>> To solve this, a new macro is created as a helper to allow tracepoints
>>> to export enums they use to userspace. This macro is called,
>>> TRACE_DEFINE_ENUM(), such that
>>>
>>>  TRACE_DEFINE_ENUM(TLB_REMOTE_SHOOTDOWN);
>>>
>>> Will export the TLB_REMOTE_SHOOTDOWN enum to use space.
>>>
>>> How that is done is with a new file in the debugfs tracing directory.
>>>
>>>  # cat /sys/kernel/debug/tracing/enum_map
>>> TLB_LOCAL_MM_SHOOTDOWN 3
>>> TLB_LOCAL_SHOOTDOWN 2
>>> TLB_REMOTE_SHOOTDOWN 1
>>> TLB_FLUSH_ON_TASK_SWITCH 0
>>
>> BTW, if we can show the enum_map, can we also show the "symbolic" map
>> instead of using the __print_symbolic() ? :)
> 
> There's nothing mapping the two in the kernel. And worse yet, some
> enums are used in operations. Just look at f2fs_submit_read_bio, where
> in the __print_symbolic() it has:
> 
> 	(1ULL << __REQ_NOIDLE) | ...
> 
> the __REQ_NOIDLE is an enum.
> 
> But, if I do just a substitution, then we wont even have to update
> userspace tools. They should still work.
> 
> -- Steve
> --
> 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/
> 


-- 
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Research Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt@hitachi.com



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

* Re: [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values
  2015-03-31  7:36     ` Masami Hiramatsu
@ 2015-03-31 13:26       ` Steven Rostedt
  2015-04-01  7:23         ` Masami Hiramatsu
  0 siblings, 1 reply; 27+ messages in thread
From: Steven Rostedt @ 2015-03-31 13:26 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Namhyung Kim,
	Mathieu Desnoyers

On Tue, 31 Mar 2015 16:36:51 +0900
Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> wrote:

> > Instead of adding an enum mapping file, I could add a way to look at
> > all the events in the system that defined a mapping, and do a
> > "s/ENUM_NAME/ENUM_VALUE/g" do the saved print formats? I'm not sure how
> > much we want to do that in the kernel though.
> 
> No, it's not what I expected...

Actually, I'm going to play with this idea and see how crazy it is or
isn't. Converting the ENUMS in TP_printk() might actually be doable.

I'll write up some code and we can see if it seems sane or not. OK?


> 
> What I thought was expanding __print_symbolic() macro in TP_printk
> with a special hash string(start with #), and when showing it via
> event/format, replace the hash string with the strings generated
> by the map of symbols. This will introduce a small overhead to show
> the format as a side effect.
> 
> Actually I even have not tried, so it's just an idea yet.
> 

If you can figure something out, please let me know!

Thanks,

-- Steve

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

* Re: [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values
  2015-03-27 21:37 [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Steven Rostedt
                   ` (10 preceding siblings ...)
  2015-03-30  3:38 ` [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Masami Hiramatsu
@ 2015-03-31 21:30 ` Dave Chinner
  2015-03-31 22:56   ` Steven Rostedt
  11 siblings, 1 reply; 27+ messages in thread
From: Dave Chinner @ 2015-03-31 21:30 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Namhyung Kim,
	Masami Hiramatsu, Mathieu Desnoyers

On Fri, Mar 27, 2015 at 05:37:04PM -0400, Steven Rostedt wrote:
> 
> As there are many tracepoints that use __print_symbolic() to translate
> numbers into ASCII strings, and several of these translate enums as
> well, it causes a problem for user space tools that read the tracepoint
> format files and have to translate the binary data to their associated
> strings.
.....
> Steven Rostedt (Red Hat) (10):
>       tracing: Add TRACE_DEFINE_ENUM() macro to map enums to their values
>       tracing: Allow for modules to export their trace enums as well
>       x86/tlb/trace: Export enums in used by tlb_flush tracepoint
>       net/9p/tracing: Export enums in tracepoints to userspace
>       f2fs: Export the enums in the tracepoints to userspace
>       irq/tracing: Export enums in tracepoints to user space
>       mm: tracing: Export enums in tracepoints to user space
>       SUNRPC: Export enums in tracepoints to user space
>       v4l: Export enums used by tracepoints to user space
>       writeback: Export enums used by tracepoint to user space

So are you expecting subsystem maintainers to modify their tracing
code to do this, or is this just the first round of changes you are
making? e.g:

$ grep print_symbolic fs/xfs/xfs_trace.h
                  __print_symbolic(__entry->trans_type, XFS_TRANS_TYPES),
                  __print_symbolic(__entry->type, XFS_LI_TYPE_DESC),
                  __print_symbolic(__entry->type, XFS_LI_TYPE_DESC),
                  __print_symbolic(__entry->type, XFS_IO_TYPES),
                  __print_symbolic(__entry->type, XFS_ALLOC_TYPES),
                  __print_symbolic(__entry->otype, XFS_ALLOC_TYPES),
                  __print_symbolic(__entry->which, XFS_SWAPEXT_INODES),
                  __print_symbolic(__entry->format, XFS_INODE_FORMAT_STR),
                  __print_symbolic(__entry->type, XFS_LI_TYPE_DESC),
$

And a quick git grep indicates there are a lot that you haven't
converted in this patchset...

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

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

* Re: [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values
  2015-03-31 21:30 ` Dave Chinner
@ 2015-03-31 22:56   ` Steven Rostedt
  0 siblings, 0 replies; 27+ messages in thread
From: Steven Rostedt @ 2015-03-31 22:56 UTC (permalink / raw)
  To: Dave Chinner
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Namhyung Kim,
	Masami Hiramatsu, Mathieu Desnoyers

On Wed, 1 Apr 2015 08:30:05 +1100
Dave Chinner <david@fromorbit.com> wrote:

> On Fri, Mar 27, 2015 at 05:37:04PM -0400, Steven Rostedt wrote:
> > 
> > As there are many tracepoints that use __print_symbolic() to translate
> > numbers into ASCII strings, and several of these translate enums as
> > well, it causes a problem for user space tools that read the tracepoint
> > format files and have to translate the binary data to their associated
> > strings.
> .....
> > Steven Rostedt (Red Hat) (10):
> >       tracing: Add TRACE_DEFINE_ENUM() macro to map enums to their values
> >       tracing: Allow for modules to export their trace enums as well
> >       x86/tlb/trace: Export enums in used by tlb_flush tracepoint
> >       net/9p/tracing: Export enums in tracepoints to userspace
> >       f2fs: Export the enums in the tracepoints to userspace
> >       irq/tracing: Export enums in tracepoints to user space
> >       mm: tracing: Export enums in tracepoints to user space
> >       SUNRPC: Export enums in tracepoints to user space
> >       v4l: Export enums used by tracepoints to user space
> >       writeback: Export enums used by tracepoint to user space
> 
> So are you expecting subsystem maintainers to modify their tracing
> code to do this, or is this just the first round of changes you are
> making? e.g:
> 
> $ grep print_symbolic fs/xfs/xfs_trace.h
>                   __print_symbolic(__entry->trans_type, XFS_TRANS_TYPES),
>                   __print_symbolic(__entry->type, XFS_LI_TYPE_DESC),
>                   __print_symbolic(__entry->type, XFS_LI_TYPE_DESC),
>                   __print_symbolic(__entry->type, XFS_IO_TYPES),
>                   __print_symbolic(__entry->type, XFS_ALLOC_TYPES),
>                   __print_symbolic(__entry->otype, XFS_ALLOC_TYPES),
>                   __print_symbolic(__entry->which, XFS_SWAPEXT_INODES),
>                   __print_symbolic(__entry->format, XFS_INODE_FORMAT_STR),
>                   __print_symbolic(__entry->type, XFS_LI_TYPE_DESC),

Note, it only is needed for enums. Those look to be macros (#define),
which does not have a problem (the value is shown to userspace, not the
name).

> $
> 
> And a quick git grep indicates there are a lot that you haven't
> converted in this patchset...

But yes, I only covered the include/trace/events/*.h files. I'm sure
there's others I would need to update. But this can be done
incrementally.

-- Steve

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

* Re: [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values
  2015-03-31 13:26       ` Steven Rostedt
@ 2015-04-01  7:23         ` Masami Hiramatsu
  0 siblings, 0 replies; 27+ messages in thread
From: Masami Hiramatsu @ 2015-04-01  7:23 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Namhyung Kim,
	Mathieu Desnoyers

(2015/03/31 22:26), Steven Rostedt wrote:
> On Tue, 31 Mar 2015 16:36:51 +0900
> Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> wrote:
> 
>>> Instead of adding an enum mapping file, I could add a way to look at
>>> all the events in the system that defined a mapping, and do a
>>> "s/ENUM_NAME/ENUM_VALUE/g" do the saved print formats? I'm not sure how
>>> much we want to do that in the kernel though.
>>
>> No, it's not what I expected...
> 
> Actually, I'm going to play with this idea and see how crazy it is or
> isn't. Converting the ENUMS in TP_printk() might actually be doable.
> 
> I'll write up some code and we can see if it seems sane or not. OK?

Yeah, I see. Thanks.

>> What I thought was expanding __print_symbolic() macro in TP_printk
>> with a special hash string(start with #), and when showing it via
>> event/format, replace the hash string with the strings generated
>> by the map of symbols. This will introduce a small overhead to show
>> the format as a side effect.
>>
>> Actually I even have not tried, so it's just an idea yet.
>>
> 
> If you can figure something out, please let me know!

OK, I'll try to find the other way.

Thank you!


> 
> Thanks,
> 
> -- Steve
> 

-- 
Masami HIRAMATSU
Linux Technology Research Center, System Productivity Research Dept.
Center for Technology Innovation - Systems Engineering
Hitachi, Ltd., Research & Development Group
E-mail: masami.hiramatsu.pt@hitachi.com


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

end of thread, other threads:[~2015-04-01  7:26 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-27 21:37 [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Steven Rostedt
2015-03-27 21:37 ` [RFC][PATCH 01/10] tracing: Add TRACE_DEFINE_ENUM() macro to map enums to their values Steven Rostedt
2015-03-30  2:27   ` Namhyung Kim
2015-03-27 21:37 ` [RFC][PATCH 02/10] tracing: Allow for modules to export their trace enums as well Steven Rostedt
2015-03-30  2:10   ` Rusty Russell
2015-03-30  2:41   ` Namhyung Kim
2015-03-30 13:48     ` Steven Rostedt
2015-03-27 21:37 ` [RFC][PATCH 03/10] x86/tlb/trace: Export enums in used by tlb_flush tracepoint Steven Rostedt
2015-03-27 21:37 ` [RFC][PATCH 04/10] net/9p/tracing: Export enums in tracepoints to userspace Steven Rostedt
2015-03-27 21:37 ` [RFC][PATCH 05/10] f2fs: Export the enums in the " Steven Rostedt
2015-03-30  2:47   ` Namhyung Kim
2015-03-30 13:49     ` Steven Rostedt
2015-03-27 21:37 ` [RFC][PATCH 06/10] irq/tracing: Export enums in tracepoints to user space Steven Rostedt
2015-03-27 21:46   ` Steven Rostedt
2015-03-27 21:37 ` [RFC][PATCH 07/10] mm: tracing: " Steven Rostedt
2015-03-27 21:37 ` [RFC][PATCH 08/10] SUNRPC: " Steven Rostedt
2015-03-27 21:37 ` [RFC][PATCH 09/10] v4l: Export enums used by " Steven Rostedt
2015-03-28 13:00   ` Xie XiuQi
2015-03-28 16:20     ` Steven Rostedt
2015-03-27 21:37 ` [RFC][PATCH 10/10] writeback: Export enums used by tracepoint " Steven Rostedt
2015-03-30  3:38 ` [RFC][PATCH 00/10] tracing: Use TRACE_DEFINE_ENUM() to show enum values Masami Hiramatsu
2015-03-30 14:07   ` Steven Rostedt
2015-03-31  7:36     ` Masami Hiramatsu
2015-03-31 13:26       ` Steven Rostedt
2015-04-01  7:23         ` Masami Hiramatsu
2015-03-31 21:30 ` Dave Chinner
2015-03-31 22:56   ` Steven Rostedt

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