Re: [PATCH 4/4] tools lib traceevent: Added support for __get_bitmask() macro

2014-06-02 Thread Steven Rostedt
On Tue, 03 Jun 2014 11:43:26 +0900
Namhyung Kim  wrote:

> Hi Steve,
> 
> On Fri, 16 May 2014 10:02:19 -0400, Steven Rostedt wrote:
> > @@ -3691,6 +3784,23 @@ static void print_str_arg(struct trace_seq *s, void 
> > *data, int size,
> > case PRINT_BSTRING:
> > print_str_to_seq(s, format, len_arg, arg->string.string);
> > break;
> > +   case PRINT_BITMASK: {
> > +   int bitmask_offset;
> > +   int bitmask_size;
> > +
> > +   if (arg->bitmask.offset == -1) {
> > +   struct format_field *f;
> > +
> > +   f = pevent_find_any_field(event, arg->bitmask.bitmask);
> > +   arg->bitmask.offset = f->offset;
> > +   }
> > +   bitmask_offset = data2host4(pevent, data + arg->string.offset);
> 
> s/string.offset/bitmask.offset/

Duh, thanks!

-- Steve

> 
> Thanks,
> Namhyung
> 
> 
> > +   bitmask_size = bitmask_offset >> 16;
> > +   bitmask_offset &= 0x;
> > +   print_bitmask_to_seq(pevent, s, format, len_arg,
> > +data + bitmask_offset, bitmask_size);
> > +   break;
> > +   }

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


Re: [PATCH 4/4] tools lib traceevent: Added support for __get_bitmask() macro

2014-06-02 Thread Namhyung Kim
Hi Steve,

On Fri, 16 May 2014 10:02:19 -0400, Steven Rostedt wrote:
> @@ -3691,6 +3784,23 @@ static void print_str_arg(struct trace_seq *s, void 
> *data, int size,
>   case PRINT_BSTRING:
>   print_str_to_seq(s, format, len_arg, arg->string.string);
>   break;
> + case PRINT_BITMASK: {
> + int bitmask_offset;
> + int bitmask_size;
> +
> + if (arg->bitmask.offset == -1) {
> + struct format_field *f;
> +
> + f = pevent_find_any_field(event, arg->bitmask.bitmask);
> + arg->bitmask.offset = f->offset;
> + }
> + bitmask_offset = data2host4(pevent, data + arg->string.offset);

s/string.offset/bitmask.offset/

Thanks,
Namhyung


> + bitmask_size = bitmask_offset >> 16;
> + bitmask_offset &= 0x;
> + print_bitmask_to_seq(pevent, s, format, len_arg,
> +  data + bitmask_offset, bitmask_size);
> + break;
> + }
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 4/4] tools lib traceevent: Added support for __get_bitmask() macro

2014-06-02 Thread Namhyung Kim
Hi Steve,

On Fri, 16 May 2014 10:02:19 -0400, Steven Rostedt wrote:
 @@ -3691,6 +3784,23 @@ static void print_str_arg(struct trace_seq *s, void 
 *data, int size,
   case PRINT_BSTRING:
   print_str_to_seq(s, format, len_arg, arg-string.string);
   break;
 + case PRINT_BITMASK: {
 + int bitmask_offset;
 + int bitmask_size;
 +
 + if (arg-bitmask.offset == -1) {
 + struct format_field *f;
 +
 + f = pevent_find_any_field(event, arg-bitmask.bitmask);
 + arg-bitmask.offset = f-offset;
 + }
 + bitmask_offset = data2host4(pevent, data + arg-string.offset);

s/string.offset/bitmask.offset/

Thanks,
Namhyung


 + bitmask_size = bitmask_offset  16;
 + bitmask_offset = 0x;
 + print_bitmask_to_seq(pevent, s, format, len_arg,
 +  data + bitmask_offset, bitmask_size);
 + break;
 + }
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 4/4] tools lib traceevent: Added support for __get_bitmask() macro

2014-06-02 Thread Steven Rostedt
On Tue, 03 Jun 2014 11:43:26 +0900
Namhyung Kim namhy...@gmail.com wrote:

 Hi Steve,
 
 On Fri, 16 May 2014 10:02:19 -0400, Steven Rostedt wrote:
  @@ -3691,6 +3784,23 @@ static void print_str_arg(struct trace_seq *s, void 
  *data, int size,
  case PRINT_BSTRING:
  print_str_to_seq(s, format, len_arg, arg-string.string);
  break;
  +   case PRINT_BITMASK: {
  +   int bitmask_offset;
  +   int bitmask_size;
  +
  +   if (arg-bitmask.offset == -1) {
  +   struct format_field *f;
  +
  +   f = pevent_find_any_field(event, arg-bitmask.bitmask);
  +   arg-bitmask.offset = f-offset;
  +   }
  +   bitmask_offset = data2host4(pevent, data + arg-string.offset);
 
 s/string.offset/bitmask.offset/

Duh, thanks!

-- Steve

 
 Thanks,
 Namhyung
 
 
  +   bitmask_size = bitmask_offset  16;
  +   bitmask_offset = 0x;
  +   print_bitmask_to_seq(pevent, s, format, len_arg,
  +data + bitmask_offset, bitmask_size);
  +   break;
  +   }

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


[PATCH 4/4] tools lib traceevent: Added support for __get_bitmask() macro

2014-05-16 Thread Steven Rostedt
From: "Steven Rostedt (Red Hat)" 

Coming in v3.16, trace events will be able to save bitmasks in raw
format in the ring buffer and output it with the __get_bitmask() macro.

In order for userspace tools to parse this, it must be able to handle
the __get_bitmask() call and be able to convert the data that's in
the ring buffer into a nice bitmask format. The output is similar to
what the kernel uses to print bitmasks, with a comma separator every
4 bytes (8 characters).

This allows for cpumasks to also be saved efficiently.

The first user is the thermal:thermal_power_limit event which has the
following output:

 thermal_power_limit:  cpus=000f freq=190 cdev_state=0 power=5252

Link: http://lkml.kernel.org/r/20140506132238.22e13...@gandalf.local.home

Suggested-by: Javi Merino 
Tested-by: Javi Merino 
Signed-off-by: Steven Rostedt 
---
 tools/lib/traceevent/event-parse.c | 113 +
 tools/lib/traceevent/event-parse.h |   7 ++
 .../perf/util/scripting-engines/trace-event-perl.c |   1 +
 .../util/scripting-engines/trace-event-python.c|   1 +
 4 files changed, 122 insertions(+)

diff --git a/tools/lib/traceevent/event-parse.c 
b/tools/lib/traceevent/event-parse.c
index b83184f2d484..2d6aa92bcd1f 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -765,6 +765,9 @@ static void free_arg(struct print_arg *arg)
case PRINT_BSTRING:
free(arg->string.string);
break;
+   case PRINT_BITMASK:
+   free(arg->bitmask.bitmask);
+   break;
case PRINT_DYNAMIC_ARRAY:
free(arg->dynarray.index);
break;
@@ -2268,6 +2271,7 @@ static int arg_num_eval(struct print_arg *arg, long long 
*val)
case PRINT_FIELD ... PRINT_SYMBOL:
case PRINT_STRING:
case PRINT_BSTRING:
+   case PRINT_BITMASK:
default:
do_warning("invalid eval type %d", arg->type);
ret = 0;
@@ -2296,6 +2300,7 @@ static char *arg_eval (struct print_arg *arg)
case PRINT_FIELD ... PRINT_SYMBOL:
case PRINT_STRING:
case PRINT_BSTRING:
+   case PRINT_BITMASK:
default:
do_warning("invalid eval type %d", arg->type);
break;
@@ -2683,6 +2688,35 @@ process_str(struct event_format *event __maybe_unused, 
struct print_arg *arg,
return EVENT_ERROR;
 }
 
+static enum event_type
+process_bitmask(struct event_format *event __maybe_unused, struct print_arg 
*arg,
+   char **tok)
+{
+   enum event_type type;
+   char *token;
+
+   if (read_expect_type(EVENT_ITEM, ) < 0)
+   goto out_free;
+
+   arg->type = PRINT_BITMASK;
+   arg->bitmask.bitmask = token;
+   arg->bitmask.offset = -1;
+
+   if (read_expected(EVENT_DELIM, ")") < 0)
+   goto out_err;
+
+   type = read_token();
+   *tok = token;
+
+   return type;
+
+ out_free:
+   free_token(token);
+ out_err:
+   *tok = NULL;
+   return EVENT_ERROR;
+}
+
 static struct pevent_function_handler *
 find_func_handler(struct pevent *pevent, char *func_name)
 {
@@ -2797,6 +2831,10 @@ process_function(struct event_format *event, struct 
print_arg *arg,
free_token(token);
return process_str(event, arg, tok);
}
+   if (strcmp(token, "__get_bitmask") == 0) {
+   free_token(token);
+   return process_bitmask(event, arg, tok);
+   }
if (strcmp(token, "__get_dynamic_array") == 0) {
free_token(token);
return process_dynamic_array(event, arg, tok);
@@ -3324,6 +3362,7 @@ eval_num_arg(void *data, int size, struct event_format 
*event, struct print_arg
return eval_type(val, arg, 0);
case PRINT_STRING:
case PRINT_BSTRING:
+   case PRINT_BITMASK:
return 0;
case PRINT_FUNC: {
struct trace_seq s;
@@ -3556,6 +3595,60 @@ static void print_str_to_seq(struct trace_seq *s, const 
char *format,
trace_seq_printf(s, format, str);
 }
 
+static void print_bitmask_to_seq(struct pevent *pevent,
+struct trace_seq *s, const char *format,
+int len_arg, const void *data, int size)
+{
+   int nr_bits = size * 8;
+   int str_size = (nr_bits + 3) / 4;
+   int len = 0;
+   char buf[3];
+   char *str;
+   int index;
+   int i;
+
+   /*
+* The kernel likes to put in commas every 32 bits, we
+* can do the same.
+*/
+   str_size += (nr_bits - 1) / 32;
+
+   str = malloc(str_size + 1);
+   if (!str) {
+   do_warning("%s: not enough memory!", __func__);
+   return;
+   }
+   str[str_size] = 0;
+
+   /* Start out with -2 for the two chars per byte */
+   for (i = str_size - 2; i >= 0; i -= 2) 

[PATCH 4/4] tools lib traceevent: Added support for __get_bitmask() macro

2014-05-16 Thread Steven Rostedt
From: Steven Rostedt (Red Hat) rost...@goodmis.org

Coming in v3.16, trace events will be able to save bitmasks in raw
format in the ring buffer and output it with the __get_bitmask() macro.

In order for userspace tools to parse this, it must be able to handle
the __get_bitmask() call and be able to convert the data that's in
the ring buffer into a nice bitmask format. The output is similar to
what the kernel uses to print bitmasks, with a comma separator every
4 bytes (8 characters).

This allows for cpumasks to also be saved efficiently.

The first user is the thermal:thermal_power_limit event which has the
following output:

 thermal_power_limit:  cpus=000f freq=190 cdev_state=0 power=5252

Link: http://lkml.kernel.org/r/20140506132238.22e13...@gandalf.local.home

Suggested-by: Javi Merino javi.mer...@arm.com
Tested-by: Javi Merino javi.mer...@arm.com
Signed-off-by: Steven Rostedt rost...@goodmis.org
---
 tools/lib/traceevent/event-parse.c | 113 +
 tools/lib/traceevent/event-parse.h |   7 ++
 .../perf/util/scripting-engines/trace-event-perl.c |   1 +
 .../util/scripting-engines/trace-event-python.c|   1 +
 4 files changed, 122 insertions(+)

diff --git a/tools/lib/traceevent/event-parse.c 
b/tools/lib/traceevent/event-parse.c
index b83184f2d484..2d6aa92bcd1f 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -765,6 +765,9 @@ static void free_arg(struct print_arg *arg)
case PRINT_BSTRING:
free(arg-string.string);
break;
+   case PRINT_BITMASK:
+   free(arg-bitmask.bitmask);
+   break;
case PRINT_DYNAMIC_ARRAY:
free(arg-dynarray.index);
break;
@@ -2268,6 +2271,7 @@ static int arg_num_eval(struct print_arg *arg, long long 
*val)
case PRINT_FIELD ... PRINT_SYMBOL:
case PRINT_STRING:
case PRINT_BSTRING:
+   case PRINT_BITMASK:
default:
do_warning(invalid eval type %d, arg-type);
ret = 0;
@@ -2296,6 +2300,7 @@ static char *arg_eval (struct print_arg *arg)
case PRINT_FIELD ... PRINT_SYMBOL:
case PRINT_STRING:
case PRINT_BSTRING:
+   case PRINT_BITMASK:
default:
do_warning(invalid eval type %d, arg-type);
break;
@@ -2683,6 +2688,35 @@ process_str(struct event_format *event __maybe_unused, 
struct print_arg *arg,
return EVENT_ERROR;
 }
 
+static enum event_type
+process_bitmask(struct event_format *event __maybe_unused, struct print_arg 
*arg,
+   char **tok)
+{
+   enum event_type type;
+   char *token;
+
+   if (read_expect_type(EVENT_ITEM, token)  0)
+   goto out_free;
+
+   arg-type = PRINT_BITMASK;
+   arg-bitmask.bitmask = token;
+   arg-bitmask.offset = -1;
+
+   if (read_expected(EVENT_DELIM, ))  0)
+   goto out_err;
+
+   type = read_token(token);
+   *tok = token;
+
+   return type;
+
+ out_free:
+   free_token(token);
+ out_err:
+   *tok = NULL;
+   return EVENT_ERROR;
+}
+
 static struct pevent_function_handler *
 find_func_handler(struct pevent *pevent, char *func_name)
 {
@@ -2797,6 +2831,10 @@ process_function(struct event_format *event, struct 
print_arg *arg,
free_token(token);
return process_str(event, arg, tok);
}
+   if (strcmp(token, __get_bitmask) == 0) {
+   free_token(token);
+   return process_bitmask(event, arg, tok);
+   }
if (strcmp(token, __get_dynamic_array) == 0) {
free_token(token);
return process_dynamic_array(event, arg, tok);
@@ -3324,6 +3362,7 @@ eval_num_arg(void *data, int size, struct event_format 
*event, struct print_arg
return eval_type(val, arg, 0);
case PRINT_STRING:
case PRINT_BSTRING:
+   case PRINT_BITMASK:
return 0;
case PRINT_FUNC: {
struct trace_seq s;
@@ -3556,6 +3595,60 @@ static void print_str_to_seq(struct trace_seq *s, const 
char *format,
trace_seq_printf(s, format, str);
 }
 
+static void print_bitmask_to_seq(struct pevent *pevent,
+struct trace_seq *s, const char *format,
+int len_arg, const void *data, int size)
+{
+   int nr_bits = size * 8;
+   int str_size = (nr_bits + 3) / 4;
+   int len = 0;
+   char buf[3];
+   char *str;
+   int index;
+   int i;
+
+   /*
+* The kernel likes to put in commas every 32 bits, we
+* can do the same.
+*/
+   str_size += (nr_bits - 1) / 32;
+
+   str = malloc(str_size + 1);
+   if (!str) {
+   do_warning(%s: not enough memory!, __func__);
+   return;
+   }
+   str[str_size] = 0;
+
+   /* Start out with -2 for the two