perf tools: Support '<event>.*' dynamic sort key
authorNamhyung Kim <namhyung@kernel.org>
Tue, 22 Dec 2015 17:07:07 +0000 (02:07 +0900)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 6 Jan 2016 23:11:12 +0000 (20:11 -0300)
Support '*' character for field name to add all (non-common) fields as
sort keys easily.

  $ perf report -s 'switch.*' --stdio
  ...
  # Overhead    prev_comm  prev_pid   prev_prio  prev_state     next_comm  next_pid  next_prio
  # ........  ...........  .........  .........  ..........  ............  ........  .........
  #
       3.82%    swapper/0         0         120           0   netctl-auto     18711        120
       3.75%  netctl-auto     18711         120           1     swapper/0         0        120
       2.24%    swapper/1         0         120           0   netctl-auto     18709        120
       2.24%  netctl-auto     18709         120           1     swapper/1         0        120
       1.80%    swapper/2         0         120           0   rcu_preempt         7        120
       1.80%    swapper/2         0         120           0   netctl-auto     18711        120
       1.80%  rcu_preempt         7         120           1     swapper/2         0        120
       1.80%  netctl-auto     18711         120           1     swapper/2         0        120
  ...

Suggested-and-acked-by: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1450804030-29193-11-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/sort.c

index f3a98c25fb8d9090db0eb50c09f2cd6d587125c9..f6aef15a651dcbb4681819153bb10fdb64fb59df 100644 (file)
@@ -1908,12 +1908,27 @@ static struct perf_evsel *find_evsel(struct perf_evlist *evlist, char *event_nam
        return evsel;
 }
 
+static int __dynamic_dimension__add(struct perf_evsel *evsel,
+                                   struct format_field *field,
+                                   bool raw_trace)
+{
+       struct hpp_dynamic_entry *hde;
+
+       hde = __alloc_dynamic_entry(evsel, field);
+       if (hde == NULL)
+               return -ENOMEM;
+
+       hde->raw_trace = raw_trace;
+
+       perf_hpp__register_sort_field(&hde->hpp);
+       return 0;
+}
+
 static int add_dynamic_entry(struct perf_evlist *evlist, const char *tok)
 {
        char *str, *event_name, *field_name, *opt_name;
        struct perf_evsel *evsel;
        struct format_field *field;
-       struct hpp_dynamic_entry *hde;
        bool raw_trace = symbol_conf.raw_trace;
        int ret = 0;
 
@@ -1951,22 +1966,26 @@ static int add_dynamic_entry(struct perf_evlist *evlist, const char *tok)
                goto out;
        }
 
-       field = pevent_find_any_field(evsel->tp_format, field_name);
-       if (field == NULL) {
-               pr_debug("Cannot find event field for %s.%s\n",
-                      event_name, field_name);
-               ret = -ENOENT;
-               goto out;
-       }
+       if (!strcmp(field_name, "*")) {
+               field = evsel->tp_format->format.fields;
 
-       hde = __alloc_dynamic_entry(evsel, field);
-       if (hde == NULL) {
-               ret = -ENOMEM;
-               goto out;
-       }
-       hde->raw_trace = raw_trace;
+               while (field) {
+                       ret = __dynamic_dimension__add(evsel, field, raw_trace);
+                       if (ret < 0)
+                               goto out;
 
-       perf_hpp__register_sort_field(&hde->hpp);
+                       field = field->next;
+               }
+       } else {
+               field = pevent_find_any_field(evsel->tp_format, field_name);
+               if (field == NULL) {
+                       pr_debug("Cannot find event field for %s.%s\n",
+                                event_name, field_name);
+                       return -ENOENT;
+               }
+
+               ret = __dynamic_dimension__add(evsel, field, raw_trace);
+       }
 
 out:
        free(str);