On Fri, 16 Dec 2016 16:22:25 +0000
David Howells <[email protected]> wrote:

> Steven Rostedt <[email protected]> wrote:
> 
> > > Another feature that would be very nice to have is the ability to turn a
> > > number into a string by direct array index rather than by table search or
> > > serial ?: ternary operators.  
> > 
> > Which function are you talking about?  
> 
> See the attached patch that converts rxrpc's tracing from using string arrays
> to using TRACE_DEFINE_ENUM so that utilities like crash's trace buffer
> disassembler can find the string values.
> 
> When __print_symbolic() is used, each set of strings is rendered as an array
> of trace_print_flag structs which trace_print_symbols_seq() then iterates
> over to find a match.
> 

You mean to do something like this? (untested, not even compiled)

-- Steve

---
 include/linux/trace_events.h |    6 ++++--
 include/trace/trace_events.h |   10 ++++++----
 kernel/trace/trace_output.c  |   28 ++++++++++++++++++++++++----
 3 files changed, 34 insertions(+), 10 deletions(-)

Index: linux-trace.git/include/linux/trace_events.h
===================================================================
--- linux-trace.git.orig/include/linux/trace_events.h   2016-11-15 
17:27:19.397749523 -0500
+++ linux-trace.git/include/linux/trace_events.h        2016-12-16 
11:34:38.783424430 -0500
@@ -20,13 +20,15 @@ const char *trace_print_flags_seq(struct
                                  const struct trace_print_flags *flag_array);
 
 const char *trace_print_symbols_seq(struct trace_seq *p, unsigned long val,
-                                   const struct trace_print_flags 
*symbol_array);
+                                   const struct trace_print_flags 
*symbol_array,
+                                   unsigned long nr);
 
 #if BITS_PER_LONG == 32
 const char *trace_print_symbols_seq_u64(struct trace_seq *p,
                                        unsigned long long val,
                                        const struct trace_print_flags_u64
-                                                                *symbol_array);
+                                                                *symbol_array,
+                                       unsigned long long nr);
 #endif
 
 const char *trace_print_bitmask_seq(struct trace_seq *p, void *bitmask_ptr,
Index: linux-trace.git/include/trace/trace_events.h
===================================================================
--- linux-trace.git.orig/include/trace/trace_events.h   2016-12-16 
11:29:39.599950900 -0500
+++ linux-trace.git/include/trace/trace_events.h        2016-12-16 
11:30:39.927844742 -0500
@@ -279,8 +279,9 @@ TRACE_MAKE_SYSTEM_STR();
 #define __print_symbolic(value, symbol_array...)                       \
        ({                                                              \
                static const struct trace_print_flags symbols[] =       \
-                       { symbol_array, { -1, NULL }};                  \
-               trace_print_symbols_seq(p, value, symbols);             \
+                       { symbol_array}};                               \
+               trace_print_symbols_seq(p, value, symbols,              \
+                                       ARRAY_SIZE(symbols));           \
        })
 
 #undef __print_symbolic_u64
@@ -288,8 +289,9 @@ TRACE_MAKE_SYSTEM_STR();
 #define __print_symbolic_u64(value, symbol_array...)                   \
        ({                                                              \
                static const struct trace_print_flags_u64 symbols[] =   \
-                       { symbol_array, { -1, NULL } };                 \
-               trace_print_symbols_seq_u64(p, value, symbols); \
+                       { symbol_array };                               \
+               trace_print_symbols_seq_u64(p, value, symbols,          \
+                                           ARRAY_SIZE(symbols));       \
        })
 #else
 #define __print_symbolic_u64(value, symbol_array...)                   \
Index: linux-trace.git/kernel/trace/trace_output.c
===================================================================
--- linux-trace.git.orig/kernel/trace/trace_output.c    2016-12-14 
10:33:28.581929129 -0500
+++ linux-trace.git/kernel/trace/trace_output.c 2016-12-16 11:36:41.695208145 
-0500
@@ -99,12 +99,21 @@ EXPORT_SYMBOL(trace_print_flags_seq);
 
 const char *
 trace_print_symbols_seq(struct trace_seq *p, unsigned long val,
-                       const struct trace_print_flags *symbol_array)
+                       const struct trace_print_flags *symbol_array,
+                       unsigned long nr)
 {
        int i;
        const char *ret = trace_seq_buffer_ptr(p);
 
-       for (i = 0;  symbol_array[i].name; i++) {
+       /* A lot of arrays are simply enums that map to the array index */
+       if (val < nr) {
+               if (val == symbol_array[val].mask) {
+                       trace_seq_puts(p, symbol_array[val].name);
+                       goto out;
+               }
+       }
+
+       for (i = 0;  i < nr; i++) {
 
                if (val != symbol_array[i].mask)
                        continue;
@@ -116,6 +125,7 @@ trace_print_symbols_seq(struct trace_seq
        if (ret == (const char *)(trace_seq_buffer_ptr(p)))
                trace_seq_printf(p, "0x%lx", val);
 
+ out:
        trace_seq_putc(p, 0);
 
        return ret;
@@ -125,12 +135,21 @@ EXPORT_SYMBOL(trace_print_symbols_seq);
 #if BITS_PER_LONG == 32
 const char *
 trace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val,
-                        const struct trace_print_flags_u64 *symbol_array)
+                        const struct trace_print_flags_u64 *symbol_array,
+                           unsigned long long nr)
 {
        int i;
        const char *ret = trace_seq_buffer_ptr(p);
 
-       for (i = 0;  symbol_array[i].name; i++) {
+       /* A lot of arrays are simply enums that map to the array index */
+       if (val < nr) {
+               if (val == symbol_array[val].mask) {
+                       trace_seq_puts(p, symbol_array[val].name);
+                       goto out;
+               }
+       }
+
+       for (i = 0;  i < nr; i++) {
 
                if (val != symbol_array[i].mask)
                        continue;
@@ -142,6 +161,7 @@ trace_print_symbols_seq_u64(struct trace
        if (ret == (const char *)(trace_seq_buffer_ptr(p)))
                trace_seq_printf(p, "0x%llx", val);
 
+ out:
        trace_seq_putc(p, 0);
 
        return ret;

Reply via email to