aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-mem.c')
-rw-r--r--tools/perf/builtin-mem.c84
1 files changed, 76 insertions, 8 deletions
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index 390170041696..88aeac9aa1da 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -6,6 +6,8 @@
6#include "util/tool.h" 6#include "util/tool.h"
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"
10#include "util/debug.h"
9 11
10#define MEM_OPERATION_LOAD 0x1 12#define MEM_OPERATION_LOAD 0x1
11#define MEM_OPERATION_STORE 0x2 13#define MEM_OPERATION_STORE 0x2
@@ -21,11 +23,56 @@ struct perf_mem {
21 DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 23 DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
22}; 24};
23 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, "%-13s%-*s%s\n",
44 e->tag,
45 verbose ? 25 : 0,
46 verbose ? perf_mem_events__name(j) : "",
47 e->supported ? ": available" : "");
48 }
49 exit(0);
50}
51
52static const char * const __usage[] = {
53 "perf mem record [<options>] [<command>]",
54 "perf mem record [<options>] -- <command> [<options>]",
55 NULL
56};
57
58static const char * const *record_mem_usage = __usage;
59
24static int __cmd_record(int argc, const char **argv, struct perf_mem *mem) 60static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)
25{ 61{
26 int rec_argc, i = 0, j; 62 int rec_argc, i = 0, j;
27 const char **rec_argv; 63 const char **rec_argv;
28 int ret; 64 int ret;
65 struct option options[] = {
66 OPT_CALLBACK('e', "event", &mem, "event",
67 "event selector. use 'perf mem record -e list' to list available events",
68 parse_record_events),
69 OPT_INCR('v', "verbose", &verbose,
70 "be more verbose (show counter open errors, etc)"),
71 OPT_END()
72 };
73
74 argc = parse_options(argc, argv, options, record_mem_usage,
75 PARSE_OPT_STOP_AT_NON_OPTION);
29 76
30 rec_argc = argc + 7; /* max number of arguments */ 77 rec_argc = argc + 7; /* max number of arguments */
31 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 78 rec_argv = calloc(rec_argc + 1, sizeof(char *));
@@ -35,23 +82,40 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)
35 rec_argv[i++] = "record"; 82 rec_argv[i++] = "record";
36 83
37 if (mem->operation & MEM_OPERATION_LOAD) 84 if (mem->operation & MEM_OPERATION_LOAD)
85 perf_mem_events[PERF_MEM_EVENTS__LOAD].record = true;
86
87 if (perf_mem_events[PERF_MEM_EVENTS__LOAD].record)
38 rec_argv[i++] = "-W"; 88 rec_argv[i++] = "-W";
39 89
40 rec_argv[i++] = "-d"; 90 rec_argv[i++] = "-d";
41 91
42 if (mem->operation & MEM_OPERATION_LOAD) { 92 for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) {
43 rec_argv[i++] = "-e"; 93 if (!perf_mem_events[j].record)
44 rec_argv[i++] = "cpu/mem-loads/pp"; 94 continue;
45 } 95
96 if (!perf_mem_events[j].supported) {
97 pr_err("failed: event '%s' not supported\n",
98 perf_mem_events__name(j));
99 return -1;
100 }
46 101
47 if (mem->operation & MEM_OPERATION_STORE) {
48 rec_argv[i++] = "-e"; 102 rec_argv[i++] = "-e";
49 rec_argv[i++] = "cpu/mem-stores/pp"; 103 rec_argv[i++] = perf_mem_events__name(j);
50 } 104 };
51 105
52 for (j = 1; j < argc; j++, i++) 106 for (j = 0; j < argc; j++, i++)
53 rec_argv[i] = argv[j]; 107 rec_argv[i] = argv[j];
54 108
109 if (verbose > 0) {
110 pr_debug("calling: record ");
111
112 while (rec_argv[j]) {
113 pr_debug("%s ", rec_argv[j]);
114 j++;
115 }
116 pr_debug("\n");
117 }
118
55 ret = cmd_record(i, rec_argv, NULL); 119 ret = cmd_record(i, rec_argv, NULL);
56 free(rec_argv); 120 free(rec_argv);
57 return ret; 121 return ret;
@@ -298,6 +362,10 @@ int cmd_mem(int argc, const char **argv, const char *prefix __maybe_unused)
298 NULL 362 NULL
299 }; 363 };
300 364
365 if (perf_mem_events__init()) {
366 pr_err("failed: memory events not supported\n");
367 return -1;
368 }
301 369
302 argc = parse_options_subcommand(argc, argv, mem_options, mem_subcommands, 370 argc = parse_options_subcommand(argc, argv, mem_options, mem_subcommands,
303 mem_usage, PARSE_OPT_STOP_AT_NON_OPTION); 371 mem_usage, PARSE_OPT_STOP_AT_NON_OPTION);