9 #include "mem-events.h"
13 unsigned int perf_mem_events__loads_ldlat
= 30;
15 #define E(t, n, s) { .tag = t, .name = n, .sysfs_name = s }
17 struct perf_mem_event perf_mem_events
[PERF_MEM_EVENTS__MAX
] = {
18 E("ldlat-loads", "cpu/mem-loads,ldlat=%u/P", "mem-loads"),
19 E("ldlat-stores", "cpu/mem-stores/P", "mem-stores"),
25 static char mem_loads_name
[100];
26 static bool mem_loads_name__init
;
28 char *perf_mem_events__name(int i
)
30 if (i
== PERF_MEM_EVENTS__LOAD
) {
31 if (!mem_loads_name__init
) {
32 mem_loads_name__init
= true;
33 scnprintf(mem_loads_name
, sizeof(mem_loads_name
),
34 perf_mem_events
[i
].name
,
35 perf_mem_events__loads_ldlat
);
37 return mem_loads_name
;
40 return (char *)perf_mem_events
[i
].name
;
43 int perf_mem_events__parse(const char *str
)
45 char *tok
, *saveptr
= NULL
;
50 /* We need buffer that we know we can write to. */
51 buf
= malloc(strlen(str
) + 1);
57 tok
= strtok_r((char *)buf
, ",", &saveptr
);
60 for (j
= 0; j
< PERF_MEM_EVENTS__MAX
; j
++) {
61 struct perf_mem_event
*e
= &perf_mem_events
[j
];
63 if (strstr(e
->tag
, tok
))
64 e
->record
= found
= true;
67 tok
= strtok_r(NULL
, ",", &saveptr
);
75 pr_err("failed: event '%s' not found, use '-e list' to get list of available events\n", str
);
79 int perf_mem_events__init(void)
81 const char *mnt
= sysfs__mount();
88 for (j
= 0; j
< PERF_MEM_EVENTS__MAX
; j
++) {
90 struct perf_mem_event
*e
= &perf_mem_events
[j
];
93 scnprintf(path
, PATH_MAX
, "%s/devices/cpu/events/%s",
97 e
->supported
= found
= true;
100 return found
? 0 : -ENOENT
;
103 static const char * const tlb_access
[] = {
113 int perf_mem__tlb_scnprintf(char *out
, size_t sz
, struct mem_info
*mem_info
)
116 u64 m
= PERF_MEM_TLB_NA
;
119 sz
-= 1; /* -1 for null termination */
123 m
= mem_info
->data_src
.mem_dtlb
;
125 hit
= m
& PERF_MEM_TLB_HIT
;
126 miss
= m
& PERF_MEM_TLB_MISS
;
128 /* already taken care of */
129 m
&= ~(PERF_MEM_TLB_HIT
|PERF_MEM_TLB_MISS
);
131 for (i
= 0; m
&& i
< ARRAY_SIZE(tlb_access
); i
++, m
>>= 1) {
138 l
+= scnprintf(out
+ l
, sz
- l
, tlb_access
[i
]);
141 l
+= scnprintf(out
, sz
- l
, "N/A");
143 l
+= scnprintf(out
+ l
, sz
- l
, " hit");
145 l
+= scnprintf(out
+ l
, sz
- l
, " miss");
150 static const char * const mem_lvl
[] = {
159 "Remote RAM (1 hop)",
160 "Remote RAM (2 hops)",
161 "Remote Cache (1 hop)",
162 "Remote Cache (2 hops)",
167 int perf_mem__lvl_scnprintf(char *out
, size_t sz
, struct mem_info
*mem_info
)
170 u64 m
= PERF_MEM_LVL_NA
;
174 m
= mem_info
->data_src
.mem_lvl
;
176 sz
-= 1; /* -1 for null termination */
179 hit
= m
& PERF_MEM_LVL_HIT
;
180 miss
= m
& PERF_MEM_LVL_MISS
;
182 /* already taken care of */
183 m
&= ~(PERF_MEM_LVL_HIT
|PERF_MEM_LVL_MISS
);
185 for (i
= 0; m
&& i
< ARRAY_SIZE(mem_lvl
); i
++, m
>>= 1) {
192 l
+= scnprintf(out
+ l
, sz
- l
, mem_lvl
[i
]);
195 l
+= scnprintf(out
, sz
- l
, "N/A");
197 l
+= scnprintf(out
+ l
, sz
- l
, " hit");
199 l
+= scnprintf(out
+ l
, sz
- l
, " miss");
204 static const char * const snoop_access
[] = {
212 int perf_mem__snp_scnprintf(char *out
, size_t sz
, struct mem_info
*mem_info
)
215 u64 m
= PERF_MEM_SNOOP_NA
;
217 sz
-= 1; /* -1 for null termination */
221 m
= mem_info
->data_src
.mem_snoop
;
223 for (i
= 0; m
&& i
< ARRAY_SIZE(snoop_access
); i
++, m
>>= 1) {
230 l
+= scnprintf(out
+ l
, sz
- l
, snoop_access
[i
]);
234 l
+= scnprintf(out
, sz
- l
, "N/A");
239 int perf_mem__lck_scnprintf(char *out
, size_t sz
, struct mem_info
*mem_info
)
241 u64 mask
= PERF_MEM_LOCK_NA
;
245 mask
= mem_info
->data_src
.mem_lock
;
247 if (mask
& PERF_MEM_LOCK_NA
)
248 l
= scnprintf(out
, sz
, "N/A");
249 else if (mask
& PERF_MEM_LOCK_LOCKED
)
250 l
= scnprintf(out
, sz
, "Yes");
252 l
= scnprintf(out
, sz
, "No");
257 int perf_script__meminfo_scnprintf(char *out
, size_t sz
, struct mem_info
*mem_info
)
261 i
+= perf_mem__lvl_scnprintf(out
, sz
, mem_info
);
262 i
+= scnprintf(out
+ i
, sz
- i
, "|SNP ");
263 i
+= perf_mem__snp_scnprintf(out
+ i
, sz
- i
, mem_info
);
264 i
+= scnprintf(out
+ i
, sz
- i
, "|TLB ");
265 i
+= perf_mem__tlb_scnprintf(out
+ i
, sz
- i
, mem_info
);
266 i
+= scnprintf(out
+ i
, sz
- i
, "|LCK ");
267 i
+= perf_mem__lck_scnprintf(out
+ i
, sz
- i
, mem_info
);