aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-mem.c
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2016-02-15 03:34:35 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-02-23 10:15:59 -0500
commitce1e22b08f0728e840614d3d0fc43fd1d6b7f7a2 (patch)
tree284f4a451e2a6b01751532b02fa8daa1eb8e0ac4 /tools/perf/builtin-mem.c
parentacbe613e0c03d59cab21aec3565cdb28c7df98c3 (diff)
perf mem: Add -e record option
Adding -e option for perf mem record command, to be able to specify memory event directly. Get list of available events: $ perf mem record -e list ldlat-loads ldlat-stores Monitor ldlat-loads: $ perf mem record -e ldlat-loads true Committer notes: Further testing: # perf mem record -e ldlat-loads true [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.020 MB perf.data (10 samples) ] # perf evlist cpu/mem-loads,ldlat=30/P # Signed-off-by: Jiri Olsa <jolsa@kernel.org> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1455525293-8671-6-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-mem.c')
-rw-r--r--tools/perf/builtin-mem.c63
1 files changed, 59 insertions, 4 deletions
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index 36c56a4b778b..b3f8a89ede40 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -7,6 +7,7 @@
7#include "util/session.h" 7#include "util/session.h"
8#include "util/data.h" 8#include "util/data.h"
9#include "util/mem-events.h" 9#include "util/mem-events.h"
10#include "util/debug.h"
10 11
11#define MEM_OPERATION_LOAD 0x1 12#define MEM_OPERATION_LOAD 0x1
12#define MEM_OPERATION_STORE 0x2 13#define MEM_OPERATION_STORE 0x2
@@ -22,11 +23,55 @@ struct perf_mem {
22 DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 23 DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
23}; 24};
24 25
26static int parse_record_events(const struct option *opt,
27 const char *str, int unset __maybe_unused)
28{
29 struct perf_mem *mem = *(struct perf_mem **)opt->value;
30 int j;
31
32 if (strcmp(str, "list")) {
33 if (!perf_mem_events__parse(str)) {
34 mem->operation = 0;
35 return 0;
36 }
37 exit(-1);
38 }
39
40 for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) {
41 struct perf_mem_event *e = &perf_mem_events[j];
42
43 fprintf(stderr, "%-20s%s",
44 e->tag, verbose ? "" : "\n");
45 if (verbose)
46 fprintf(stderr, " [%s]\n", e->name);
47 }
48 exit(0);
49}
50
51static const char * const __usage[] = {
52 "perf mem record [<options>] [<command>]",
53 "perf mem record [<options>] -- <command> [<options>]",
54 NULL
55};
56
57static const char * const *record_mem_usage = __usage;
58
25static int __cmd_record(int argc, const char **argv, struct perf_mem *mem) 59static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)
26{ 60{
27 int rec_argc, i = 0, j; 61 int rec_argc, i = 0, j;
28 const char **rec_argv; 62 const char **rec_argv;
29 int ret; 63 int ret;
64 struct option options[] = {
65 OPT_CALLBACK('e', "event", &mem, "event",
66 "event selector. use 'perf mem record -e list' to list available events",
67 parse_record_events),
68 OPT_INCR('v', "verbose", &verbose,
69 "be more verbose (show counter open errors, etc)"),
70 OPT_END()
71 };
72
73 argc = parse_options(argc, argv, options, record_mem_usage,
74 PARSE_OPT_STOP_AT_NON_OPTION);
30 75
31 rec_argc = argc + 7; /* max number of arguments */ 76 rec_argc = argc + 7; /* max number of arguments */
32 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 77 rec_argv = calloc(rec_argc + 1, sizeof(char *));
@@ -35,10 +80,11 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)
35 80
36 rec_argv[i++] = "record"; 81 rec_argv[i++] = "record";
37 82
38 if (mem->operation & MEM_OPERATION_LOAD) { 83 if (mem->operation & MEM_OPERATION_LOAD)
39 perf_mem_events[PERF_MEM_EVENTS__LOAD].record = true; 84 perf_mem_events[PERF_MEM_EVENTS__LOAD].record = true;
85
86 if (perf_mem_events[PERF_MEM_EVENTS__LOAD].record)
40 rec_argv[i++] = "-W"; 87 rec_argv[i++] = "-W";
41 }
42 88
43 rec_argv[i++] = "-d"; 89 rec_argv[i++] = "-d";
44 90
@@ -50,9 +96,19 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)
50 rec_argv[i++] = perf_mem_events[j].name; 96 rec_argv[i++] = perf_mem_events[j].name;
51 }; 97 };
52 98
53 for (j = 1; j < argc; j++, i++) 99 for (j = 0; j < argc; j++, i++)
54 rec_argv[i] = argv[j]; 100 rec_argv[i] = argv[j];
55 101
102 if (verbose > 0) {
103 pr_debug("calling: record ");
104
105 while (rec_argv[j]) {
106 pr_debug("%s ", rec_argv[j]);
107 j++;
108 }
109 pr_debug("\n");
110 }
111
56 ret = cmd_record(i, rec_argv, NULL); 112 ret = cmd_record(i, rec_argv, NULL);
57 free(rec_argv); 113 free(rec_argv);
58 return ret; 114 return ret;
@@ -299,7 +355,6 @@ int cmd_mem(int argc, const char **argv, const char *prefix __maybe_unused)
299 NULL 355 NULL
300 }; 356 };
301 357
302
303 argc = parse_options_subcommand(argc, argv, mem_options, mem_subcommands, 358 argc = parse_options_subcommand(argc, argv, mem_options, mem_subcommands,
304 mem_usage, PARSE_OPT_STOP_AT_NON_OPTION); 359 mem_usage, PARSE_OPT_STOP_AT_NON_OPTION);
305 360