Merge remote-tracking branch 'asoc/topic/topology' into asoc-next
[deliverable/linux.git] / tools / perf / util / mem-events.c
CommitLineData
ce1e22b0
JO
1#include <stddef.h>
2#include <stdlib.h>
3#include <string.h>
4#include <errno.h>
54fbad54
JO
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <unistd.h>
8#include <api/fs/fs.h>
acbe613e 9#include "mem-events.h"
ce1e22b0 10#include "debug.h"
0c877d75 11#include "symbol.h"
acbe613e 12
54fbad54 13#define E(t, n, s) { .tag = t, .name = n, .sysfs_name = s }
acbe613e
JO
14
15struct perf_mem_event perf_mem_events[PERF_MEM_EVENTS__MAX] = {
54fbad54
JO
16 E("ldlat-loads", "cpu/mem-loads,ldlat=30/P", "mem-loads"),
17 E("ldlat-stores", "cpu/mem-stores/P", "mem-stores"),
acbe613e 18};
54fbad54 19#undef E
acbe613e
JO
20
21#undef E
ce1e22b0 22
2ba7ac58
JO
23char *perf_mem_events__name(int i)
24{
25 return (char *)perf_mem_events[i].name;
26}
27
ce1e22b0
JO
28int perf_mem_events__parse(const char *str)
29{
30 char *tok, *saveptr = NULL;
31 bool found = false;
32 char *buf;
33 int j;
34
35 /* We need buffer that we know we can write to. */
36 buf = malloc(strlen(str) + 1);
37 if (!buf)
38 return -ENOMEM;
39
40 strcpy(buf, str);
41
42 tok = strtok_r((char *)buf, ",", &saveptr);
43
44 while (tok) {
45 for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) {
46 struct perf_mem_event *e = &perf_mem_events[j];
47
48 if (strstr(e->tag, tok))
49 e->record = found = true;
50 }
51
52 tok = strtok_r(NULL, ",", &saveptr);
53 }
54
55 free(buf);
56
57 if (found)
58 return 0;
59
60 pr_err("failed: event '%s' not found, use '-e list' to get list of available events\n", str);
61 return -1;
62}
54fbad54
JO
63
64int perf_mem_events__init(void)
65{
66 const char *mnt = sysfs__mount();
67 bool found = false;
68 int j;
69
70 if (!mnt)
71 return -ENOENT;
72
73 for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) {
74 char path[PATH_MAX];
75 struct perf_mem_event *e = &perf_mem_events[j];
76 struct stat st;
77
78 scnprintf(path, PATH_MAX, "%s/devices/cpu/events/%s",
79 mnt, e->sysfs_name);
80
81 if (!stat(path, &st))
82 e->supported = found = true;
83 }
84
85 return found ? 0 : -ENOENT;
86}
0c877d75
JO
87
88static const char * const tlb_access[] = {
89 "N/A",
90 "HIT",
91 "MISS",
92 "L1",
93 "L2",
94 "Walker",
95 "Fault",
96};
97
b1a5fbea 98int perf_mem__tlb_scnprintf(char *out, size_t sz, struct mem_info *mem_info)
0c877d75
JO
99{
100 size_t l = 0, i;
101 u64 m = PERF_MEM_TLB_NA;
102 u64 hit, miss;
103
104 sz -= 1; /* -1 for null termination */
105 out[0] = '\0';
106
107 if (mem_info)
108 m = mem_info->data_src.mem_dtlb;
109
110 hit = m & PERF_MEM_TLB_HIT;
111 miss = m & PERF_MEM_TLB_MISS;
112
113 /* already taken care of */
114 m &= ~(PERF_MEM_TLB_HIT|PERF_MEM_TLB_MISS);
115
116 for (i = 0; m && i < ARRAY_SIZE(tlb_access); i++, m >>= 1) {
117 if (!(m & 0x1))
118 continue;
119 if (l) {
120 strcat(out, " or ");
121 l += 4;
122 }
b1a5fbea 123 l += scnprintf(out + l, sz - l, tlb_access[i]);
0c877d75
JO
124 }
125 if (*out == '\0')
b1a5fbea 126 l += scnprintf(out, sz - l, "N/A");
0c877d75 127 if (hit)
b1a5fbea 128 l += scnprintf(out + l, sz - l, " hit");
0c877d75 129 if (miss)
b1a5fbea
JO
130 l += scnprintf(out + l, sz - l, " miss");
131
132 return l;
0c877d75 133}
071e9a1e
JO
134
135static const char * const mem_lvl[] = {
136 "N/A",
137 "HIT",
138 "MISS",
139 "L1",
140 "LFB",
141 "L2",
142 "L3",
143 "Local RAM",
144 "Remote RAM (1 hop)",
145 "Remote RAM (2 hops)",
146 "Remote Cache (1 hop)",
147 "Remote Cache (2 hops)",
148 "I/O",
149 "Uncached",
150};
151
96907563 152int perf_mem__lvl_scnprintf(char *out, size_t sz, struct mem_info *mem_info)
071e9a1e
JO
153{
154 size_t i, l = 0;
155 u64 m = PERF_MEM_LVL_NA;
156 u64 hit, miss;
157
158 if (mem_info)
159 m = mem_info->data_src.mem_lvl;
160
161 sz -= 1; /* -1 for null termination */
162 out[0] = '\0';
163
164 hit = m & PERF_MEM_LVL_HIT;
165 miss = m & PERF_MEM_LVL_MISS;
166
167 /* already taken care of */
168 m &= ~(PERF_MEM_LVL_HIT|PERF_MEM_LVL_MISS);
169
170 for (i = 0; m && i < ARRAY_SIZE(mem_lvl); i++, m >>= 1) {
171 if (!(m & 0x1))
172 continue;
173 if (l) {
174 strcat(out, " or ");
175 l += 4;
176 }
96907563 177 l += scnprintf(out + l, sz - l, mem_lvl[i]);
071e9a1e
JO
178 }
179 if (*out == '\0')
96907563 180 l += scnprintf(out, sz - l, "N/A");
071e9a1e 181 if (hit)
96907563 182 l += scnprintf(out + l, sz - l, " hit");
071e9a1e 183 if (miss)
96907563
JO
184 l += scnprintf(out + l, sz - l, " miss");
185
186 return l;
071e9a1e 187}
2c07af13
JO
188
189static const char * const snoop_access[] = {
190 "N/A",
191 "None",
192 "Miss",
193 "Hit",
194 "HitM",
195};
196
149d7507 197int perf_mem__snp_scnprintf(char *out, size_t sz, struct mem_info *mem_info)
2c07af13
JO
198{
199 size_t i, l = 0;
200 u64 m = PERF_MEM_SNOOP_NA;
201
202 sz -= 1; /* -1 for null termination */
203 out[0] = '\0';
204
205 if (mem_info)
206 m = mem_info->data_src.mem_snoop;
207
208 for (i = 0; m && i < ARRAY_SIZE(snoop_access); i++, m >>= 1) {
209 if (!(m & 0x1))
210 continue;
211 if (l) {
212 strcat(out, " or ");
213 l += 4;
214 }
149d7507 215 l += scnprintf(out + l, sz - l, snoop_access[i]);
2c07af13
JO
216 }
217
218 if (*out == '\0')
149d7507
JO
219 l += scnprintf(out, sz - l, "N/A");
220
221 return l;
2c07af13 222}
69a77275 223
8b0819c8 224int perf_mem__lck_scnprintf(char *out, size_t sz, struct mem_info *mem_info)
69a77275
JO
225{
226 u64 mask = PERF_MEM_LOCK_NA;
8b0819c8 227 int l;
69a77275
JO
228
229 if (mem_info)
230 mask = mem_info->data_src.mem_lock;
231
232 if (mask & PERF_MEM_LOCK_NA)
8b0819c8 233 l = scnprintf(out, sz, "N/A");
69a77275 234 else if (mask & PERF_MEM_LOCK_LOCKED)
8b0819c8 235 l = scnprintf(out, sz, "Yes");
69a77275 236 else
8b0819c8
JO
237 l = scnprintf(out, sz, "No");
238
239 return l;
69a77275 240}
c19ac912
JO
241
242int perf_script__meminfo_scnprintf(char *out, size_t sz, struct mem_info *mem_info)
243{
244 int i = 0;
245
246 i += perf_mem__lvl_scnprintf(out, sz, mem_info);
247 i += scnprintf(out + i, sz - i, "|SNP ");
248 i += perf_mem__snp_scnprintf(out + i, sz - i, mem_info);
249 i += scnprintf(out + i, sz - i, "|TLB ");
250 i += perf_mem__tlb_scnprintf(out + i, sz - i, mem_info);
251 i += scnprintf(out + i, sz - i, "|LCK ");
252 i += perf_mem__lck_scnprintf(out + i, sz - i, mem_info);
253
254 return i;
255}
This page took 0.061124 seconds and 5 git commands to generate.