perf tools: Add 'evlist' control command
authorJiri Olsa <jolsa@kernel.org>
Sat, 26 Dec 2020 23:20:36 +0000 (00:20 +0100)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 20 Jan 2021 17:34:21 +0000 (14:34 -0300)
Add a new 'evlist' control command to display all the evlist events.
When it is received, perf will scan and print current evlist into perf
record terminal.

The interface string for control file is:

  evlist [-v|-g|-F]

The syntax follows perf evlist command:
  -F  Show just the sample frequency used for each event.
  -v  Show all fields.
  -g  Show event group information.

Example session:

  terminal 1:
    # mkfifo control ack
    # perf record --control=fifo:control,ack -e '{cycles,instructions}'

  terminal 2:
    # echo evlist > control

  terminal 1:
    cycles
    instructions
    dummy:HG

  terminal 2:
    # echo 'evlist -v' > control

  terminal 1:
    cycles: size: 120, { 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
    instructions: size: 120, config: 0x1, { sample_period, sample_freq }: 4000,      \
    sample_type: IP|TID|TIME|ID|CPU|PERIOD, read_format: ID, inherit: 1, freq: 1,    \
    sample_id_all: 1, exclude_guest: 1
    dummy:HG: type: 1, size: 120, config: 0x9, { sample_period, sample_freq }: 4000, \
    sample_type: IP|TID|TIME|ID|CPU|PERIOD, read_format: ID, inherit: 1, mmap: 1,    \
    comm: 1, freq: 1, task: 1, sample_id_all: 1, mmap2: 1, comm_exec: 1, ksymbol: 1, \
     bpf_event: 1

  terminal 2:
    # echo 'evlist -g' > control

  terminal 1:
    {cycles,instructions}
    dummy:HG

  terminal 2:
    # echo 'evlist -F' > control

  terminal 1:
    cycles: sample_freq=4000
    instructions: sample_freq=4000
    dummy:HG: sample_freq=4000

This new evlist command is handy to get real event names when
wildcards are used.

Adding evsel_fprintf.c object to python/perf.so build, because
it's now evlist.c dependency.

Adding PYTHON_PERF define for python/perf.so compilation, so we
can use it to compile in only evsel__fprintf from evsel_fprintf.c
object.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexei Budankov <abudankov@huawei.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Michael Petlan <mpetlan@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lore.kernel.org/lkml/20201226232038.390883-3-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/Documentation/perf-record.txt
tools/perf/builtin-record.c
tools/perf/builtin-stat.c
tools/perf/util/evlist.c
tools/perf/util/evlist.h
tools/perf/util/evsel_fprintf.c
tools/perf/util/python-ext-sources
tools/perf/util/setup.py

index 5ab78dcbadfb20c750606b6337a9253ccdc36372..3405268bd9a5e1a43ab03c29e7541bde193426b5 100644 (file)
@@ -646,11 +646,16 @@ ctl-fifo / ack-fifo are opened and used as ctl-fd / ack-fd as follows.
 Listen on ctl-fd descriptor for command to control measurement.
 
 Available commands:
-  'enable'       : enable events
-  'disable'      : disable events
-  'enable name'  : enable event 'name'
-  'disable name' : disable event 'name'
-  'snapshot'     : AUX area tracing snapshot).
+  'enable'           : enable events
+  'disable'          : disable events
+  'enable name'      : enable event 'name'
+  'disable name'     : disable event 'name'
+  'snapshot'         : AUX area tracing snapshot).
+
+  'evlist [-v|-g|-F] : display all events
+                       -F  Show just the sample frequency used for each event.
+                       -v  Show all fields.
+                       -g  Show event group information.
 
 Measurements can be started with events disabled using --delay=-1 option. Optionally
 send control command completion ('ack\n') to ack-fd descriptor to synchronize with the
index 71061a9af1c27eef96f951e9d4dc3ac08b933d31..a0e832002ecab2c8609b115d1be9a54db76c756b 100644 (file)
@@ -1946,6 +1946,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
                        case EVLIST_CTL_CMD_UNSUPPORTED:
                        case EVLIST_CTL_CMD_ENABLE:
                        case EVLIST_CTL_CMD_DISABLE:
+                       case EVLIST_CTL_CMD_EVLIST:
                        default:
                                break;
                        }
index 3ec12366bdd4d35d5f9a45b0bf07a9608bfc0e32..fc535e2df85798a931364d856cf113b9eafa9e66 100644 (file)
@@ -621,6 +621,7 @@ static void process_evlist(struct evlist *evlist, unsigned int interval)
                case EVLIST_CTL_CMD_SNAPSHOT:
                case EVLIST_CTL_CMD_ACK:
                case EVLIST_CTL_CMD_UNSUPPORTED:
+               case EVLIST_CTL_CMD_EVLIST:
                default:
                        break;
                }
index c71c7e035641c14f93074cba897ae7e8a880502b..9e890b482220ab0d25f5ec69ddc616495ad93683 100644 (file)
@@ -24,6 +24,7 @@
 #include "bpf-event.h"
 #include "util/string2.h"
 #include "util/perf_api_probe.h"
+#include "util/evsel_fprintf.h"
 #include <signal.h>
 #include <unistd.h>
 #include <sched.h>
@@ -1936,6 +1937,9 @@ static int evlist__ctlfd_recv(struct evlist *evlist, enum evlist_ctl_cmd *cmd,
                                    (sizeof(EVLIST_CTL_CMD_SNAPSHOT_TAG)-1))) {
                        *cmd = EVLIST_CTL_CMD_SNAPSHOT;
                        pr_debug("is snapshot\n");
+               } else if (!strncmp(cmd_data, EVLIST_CTL_CMD_EVLIST_TAG,
+                                   (sizeof(EVLIST_CTL_CMD_EVLIST_TAG)-1))) {
+                       *cmd = EVLIST_CTL_CMD_EVLIST;
                }
        }
 
@@ -2015,6 +2019,40 @@ static int evlist__ctlfd_enable(struct evlist *evlist, char *cmd_data, bool enab
        return 0;
 }
 
+static int evlist__ctlfd_list(struct evlist *evlist, char *cmd_data)
+{
+       struct perf_attr_details details = { .verbose = false, };
+       struct evsel *evsel;
+       char *arg;
+       int err;
+
+       err = get_cmd_arg(cmd_data,
+                         sizeof(EVLIST_CTL_CMD_EVLIST_TAG) - 1,
+                         &arg);
+       if (err < 0) {
+               pr_info("failed: wrong command\n");
+               return -1;
+       }
+
+       if (err) {
+               if (!strcmp(arg, "-v")) {
+                       details.verbose = true;
+               } else if (!strcmp(arg, "-g")) {
+                       details.event_group = true;
+               } else if (!strcmp(arg, "-F")) {
+                       details.freq = true;
+               } else {
+                       pr_info("failed: wrong command\n");
+                       return -1;
+               }
+       }
+
+       evlist__for_each_entry(evlist, evsel)
+               evsel__fprintf(evsel, &details, stderr);
+
+       return 0;
+}
+
 int evlist__ctlfd_process(struct evlist *evlist, enum evlist_ctl_cmd *cmd)
 {
        int err = 0;
@@ -2035,6 +2073,9 @@ int evlist__ctlfd_process(struct evlist *evlist, enum evlist_ctl_cmd *cmd)
                                err = evlist__ctlfd_enable(evlist, cmd_data,
                                                           *cmd == EVLIST_CTL_CMD_ENABLE);
                                break;
+                       case EVLIST_CTL_CMD_EVLIST:
+                               err = evlist__ctlfd_list(evlist, cmd_data);
+                               break;
                        case EVLIST_CTL_CMD_SNAPSHOT:
                                break;
                        case EVLIST_CTL_CMD_ACK:
index 1aae75895dea0816da93067491fb4e8bfd81f717..e79c64d81d212cb6bb36eccf6cc98c774393d5bc 100644 (file)
@@ -330,6 +330,7 @@ struct evsel *evlist__reset_weak_group(struct evlist *evlist, struct evsel *evse
 #define EVLIST_CTL_CMD_DISABLE_TAG "disable"
 #define EVLIST_CTL_CMD_ACK_TAG     "ack\n"
 #define EVLIST_CTL_CMD_SNAPSHOT_TAG "snapshot"
+#define EVLIST_CTL_CMD_EVLIST_TAG "evlist"
 
 #define EVLIST_CTL_CMD_MAX_LEN 64
 
@@ -339,6 +340,7 @@ enum evlist_ctl_cmd {
        EVLIST_CTL_CMD_DISABLE,
        EVLIST_CTL_CMD_ACK,
        EVLIST_CTL_CMD_SNAPSHOT,
+       EVLIST_CTL_CMD_EVLIST,
 };
 
 int evlist__parse_control(const char *str, int *ctl_fd, int *ctl_fd_ack, bool *ctl_fd_close);
index fb498a723a006ac1bcbbc0e487f674a5aa11094b..bfedd7b235211a109a78354432474bc537858c3d 100644 (file)
@@ -100,6 +100,7 @@ out:
        return ++printed;
 }
 
+#ifndef PYTHON_PERF
 int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
                              unsigned int print_opts, struct callchain_cursor *cursor,
                              struct strlist *bt_stop_list, FILE *fp)
@@ -239,3 +240,4 @@ int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
 
        return printed;
 }
+#endif /* PYTHON_PERF */
index a9d9c142eb7c3c1e86610e0ff7d55c7d1df765c3..71b753523fac0f6791a0076d1311e6b91281960b 100644 (file)
@@ -10,6 +10,7 @@ util/python.c
 util/cap.c
 util/evlist.c
 util/evsel.c
+util/evsel_fprintf.c
 util/perf_event_attr_fprintf.c
 util/cpumap.c
 util/memswap.c
index c5e3e9a68162d784287f8837c2c802808df517a0..483f05004e682081be7b87c8dcb20c4e244d9c68 100644 (file)
@@ -43,7 +43,7 @@ class install_lib(_install_lib):
 
 cflags = getenv('CFLAGS', '').split()
 # switch off several checks (need to be at the end of cflags list)
-cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter', '-Wno-redundant-decls' ]
+cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter', '-Wno-redundant-decls', '-DPYTHON_PERF' ]
 if not cc_is_clang:
     cflags += ['-Wno-cast-function-type' ]