perf tools: Enable pre-event inherit setting by config terms
authorWang Nan <wangnan0@huawei.com>
Wed, 28 Oct 2015 10:55:02 +0000 (10:55 +0000)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 28 Oct 2015 14:19:16 +0000 (11:19 -0300)
This patch allows perf record setting event's attr.inherit bit by
config terms like:

  # perf record -e cycles/no-inherit/ ...
  # perf record -e cycles/inherit/ ...

So user can control inherit bit for each event separately.

In following example, a.out fork()s in main then do some complex
CPU intensive computations in both of its children.

Basic result with and without inherit:

  # perf record -e cycles -e instructions ./a.out
  [ perf record: Woken up 9 times to write data ]
  [ perf record: Captured and wrote 2.205 MB perf.data (47920 samples) ]
  # perf report --stdio
  # ...
  # Samples: 23K of event 'cycles'
  # Event count (approx.): 23641752891
  ...
  # Samples: 24K of event 'instructions'
  # Event count (approx.): 30428312415

  # perf record -i -e cycles -e instructions ./a.out
  [ perf record: Woken up 5 times to write data ]
  [ perf record: Captured and wrote 1.111 MB perf.data (24019 samples) ]
  ...
  # Samples: 12K of event 'cycles'
  # Event count (approx.): 11699501775
  ...
  # Samples: 12K of event 'instructions'
  # Event count (approx.): 15058023559

Cancel inherit for one event when globally enable:

  # perf record -e cycles/no-inherit/ -e instructions ./a.out
  [ perf record: Woken up 7 times to write data ]
  [ perf record: Captured and wrote 1.660 MB perf.data (36004 samples) ]
  ...
  # Samples: 12K of event 'cycles/no-inherit/'
  # Event count (approx.): 11895759282
 ...
  # Samples: 24K of event 'instructions'
  # Event count (approx.): 30668000441

Enable inherit for one event when globally disable:

  # perf record -i -e cycles/inherit/ -e instructions ./a.out
  [ perf record: Woken up 7 times to write data ]
  [ perf record: Captured and wrote 1.654 MB perf.data (35868 samples) ]
  ...
  # Samples: 23K of event 'cycles/inherit/'
  # Event count (approx.): 23285400229
  ...
  # Samples: 11K of event 'instructions'
  # Event count (approx.): 14969050259

Committer note:

One can check if the bit was set, in addition to seeing the result in
the perf.data file size as above by doing one of:

  # perf record -e cycles -e instructions -a usleep 1
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.911 MB perf.data (63 samples) ]
  # perf evlist -v
  cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|ID|CPU|PERIOD, read_format: ID, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, task: 1, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
  instructions: size: 112, config: 0x1, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|ID|CPU|PERIOD, read_format: ID, disabled: 1, inherit: 1, freq: 1, sample_id_all: 1, exclude_guest: 1
  #

So, the inherit bit was set in both, now, if we disable it globally using
--no-inherit:

  # perf record --no-inherit -e cycles -e instructions -a usleep 1
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.910 MB perf.data (56 samples) ]
  # perf evlist -v
  cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|ID|CPU|PERIOD, read_format: ID, disabled: 1, mmap: 1, comm: 1, freq: 1, task: 1, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
  instructions: size: 112, config: 0x1, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|ID|CPU|PERIOD, read_format: ID, disabled: 1, freq: 1, sample_id_all: 1, exclude_guest: 1

No inherit bit set, then disabling it and setting just on the cycles event:

  # perf record --no-inherit -e cycles/inherit/ -e instructions -a usleep 1
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.909 MB perf.data (48 samples) ]
  # perf evlist -v
  cycles/inherit/: size: 112, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|ID|CPU|PERIOD, read_format: ID, disabled: 1, inherit: 1, mmap: 1, comm: 1, freq: 1, task: 1, sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1
  instructions: size: 112, config: 0x1, { sample_period, sample_freq }: 4000, sample_type: IP|TID|TIME|ID|CPU|PERIOD, read_format: ID, disabled: 1, freq: 1, sample_id_all: 1, exclude_guest: 1
  #

We can see it as well in by using a more verbose level of debug messages in
the tool that sets up the perf_event_attr, 'perf record' in this case:

  [root@zoo ~]# perf record -vv --no-inherit -e cycles/inherit/ -e instructions -a usleep 1
  ------------------------------------------------------------
  perf_event_attr:
    size                             112
    { sample_period, sample_freq }   4000
    sample_type                      IP|TID|TIME|ID|CPU|PERIOD
    read_format                      ID
    disabled                         1
    inherit                          1
    mmap                             1
    comm                             1
    freq                             1
    task                             1
    sample_id_all                    1
    exclude_guest                    1
    mmap2                            1
    comm_exec                        1
  ------------------------------------------------------------
  sys_perf_event_open: pid -1  cpu 0  group_fd -1  flags 0x8
  sys_perf_event_open: pid -1  cpu 1  group_fd -1  flags 0x8
  sys_perf_event_open: pid -1  cpu 2  group_fd -1  flags 0x8
  sys_perf_event_open: pid -1  cpu 3  group_fd -1  flags 0x8
  ------------------------------------------------------------
  perf_event_attr:
    size                             112
    config                           0x1
    { sample_period, sample_freq }   4000
    sample_type                      IP|TID|TIME|ID|CPU|PERIOD
    read_format                      ID
    disabled                         1
    freq                             1
    sample_id_all                    1
    exclude_guest                    1
  ------------------------------------------------------------
  sys_perf_event_open: pid -1  cpu 0  group_fd -1  flags 0x8

<SNIP>

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1446029705-199659-2-git-send-email-wangnan0@huawei.com
[ s/u64/bool/ for the perf_evsel_config_term inherit field - jolsa]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/parse-events.c
tools/perf/util/parse-events.h
tools/perf/util/parse-events.l

index ab05fa52a5cdbfea9f3848415cbe8faf81d4279f..3ac4ee9c6a6eeba9b66319d0c17a35f4b7db2706 100644 (file)
@@ -652,6 +652,15 @@ static void apply_config_terms(struct perf_evsel *evsel,
                case PERF_EVSEL__CONFIG_TERM_STACK_USER:
                        dump_size = term->val.stack_user;
                        break;
+               case PERF_EVSEL__CONFIG_TERM_INHERIT:
+                       /*
+                        * attr->inherit should has already been set by
+                        * perf_evsel__config. If user explicitly set
+                        * inherit using config terms, override global
+                        * opt->no_inherit setting.
+                        */
+                       attr->inherit = term->val.inherit ? 1 : 0;
+                       break;
                default:
                        break;
                }
index 0e22c0b7dab5c3cfccdf7d23a3d81b179a2f5b4d..1e8ff1906f712a96b4a2419346824d56921dca6f 100644 (file)
@@ -43,6 +43,7 @@ enum {
        PERF_EVSEL__CONFIG_TERM_TIME,
        PERF_EVSEL__CONFIG_TERM_CALLGRAPH,
        PERF_EVSEL__CONFIG_TERM_STACK_USER,
+       PERF_EVSEL__CONFIG_TERM_INHERIT,
        PERF_EVSEL__CONFIG_TERM_MAX,
 };
 
@@ -55,6 +56,7 @@ struct perf_evsel_config_term {
                bool    time;
                char    *callgraph;
                u64     stack_user;
+               bool    inherit;
        } val;
 };
 
index 991bbd469bea1b594afcd4932f40fab882aded84..72abcf254ccb606ebe4f3d496161b2caeebcf195 100644 (file)
@@ -666,6 +666,12 @@ do {                                                                          \
        case PARSE_EVENTS__TERM_TYPE_STACKSIZE:
                CHECK_TYPE_VAL(NUM);
                break;
+       case PARSE_EVENTS__TERM_TYPE_INHERIT:
+               CHECK_TYPE_VAL(NUM);
+               break;
+       case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
+               CHECK_TYPE_VAL(NUM);
+               break;
        case PARSE_EVENTS__TERM_TYPE_NAME:
                CHECK_TYPE_VAL(STR);
                break;
@@ -701,6 +707,8 @@ static int config_term_tracepoint(struct perf_event_attr *attr,
        switch (term->type_term) {
        case PARSE_EVENTS__TERM_TYPE_CALLGRAPH:
        case PARSE_EVENTS__TERM_TYPE_STACKSIZE:
+       case PARSE_EVENTS__TERM_TYPE_INHERIT:
+       case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
                return config_term_common(attr, term, err);
        default:
                if (err) {
@@ -764,6 +772,12 @@ do {                                                               \
                case PARSE_EVENTS__TERM_TYPE_STACKSIZE:
                        ADD_CONFIG_TERM(STACK_USER, stack_user, term->val.num);
                        break;
+               case PARSE_EVENTS__TERM_TYPE_INHERIT:
+                       ADD_CONFIG_TERM(INHERIT, inherit, term->val.num ? 1 : 0);
+                       break;
+               case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
+                       ADD_CONFIG_TERM(INHERIT, inherit, term->val.num ? 0 : 1);
+                       break;
                default:
                        break;
                }
index f13d3ccda4444212db7249b6f389521ac46b8e9a..13c9063513eb7e53518bd3b90e65bcaecfc7e17b 100644 (file)
@@ -67,6 +67,8 @@ enum {
        PARSE_EVENTS__TERM_TYPE_TIME,
        PARSE_EVENTS__TERM_TYPE_CALLGRAPH,
        PARSE_EVENTS__TERM_TYPE_STACKSIZE,
+       PARSE_EVENTS__TERM_TYPE_NOINHERIT,
+       PARSE_EVENTS__TERM_TYPE_INHERIT
 };
 
 struct parse_events_term {
index be244573a02e8852374f8db83432d86d578d4101..8d0de5b2991dfc1e69e44f9acecb3e89ad66795f 100644 (file)
@@ -187,6 +187,8 @@ branch_type         { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE
 time                   { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_TIME); }
 call-graph             { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CALLGRAPH); }
 stack-size             { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_STACKSIZE); }
+inherit                        { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_INHERIT); }
+no-inherit             { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOINHERIT); }
 ,                      { return ','; }
 "/"                    { BEGIN(INITIAL); return '/'; }
 {name_minus}           { return str(yyscanner, PE_NAME); }