Skip to content

Commit 1a8c2e0

Browse files
captain5050acmel
authored andcommitted
perf mem-info: Add reference count checking
Add reference count checking and switch 'struct mem_info' usage to use accessor functions. Signed-off-by: Ian Rogers <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Athira Rajeev <[email protected]> Cc: Ben Gainey <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: James Clark <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: K Prateek Nayak <[email protected]> Cc: Kajol Jain <[email protected]> Cc: Kan Liang <[email protected]> Cc: Li Dong <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Oliver Upton <[email protected]> Cc: Paran Lee <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Ravi Bangoria <[email protected]> Cc: Sun Haiyong <[email protected]> Cc: Tim Chen <[email protected]> Cc: Yanteng Si <[email protected]> Cc: Yicong Yang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent ad3003a commit 1a8c2e0

File tree

11 files changed

+135
-88
lines changed

11 files changed

+135
-88
lines changed

tools/perf/builtin-c2c.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ static int dcacheline_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
530530
char buf[20];
531531

532532
if (he->mem_info)
533-
addr = cl_address(he->mem_info->daddr.addr, chk_double_cl);
533+
addr = cl_address(mem_info__daddr(he->mem_info)->addr, chk_double_cl);
534534

535535
return scnprintf(hpp->buf, hpp->size, "%*s", width, HEX_STR(buf, addr));
536536
}
@@ -568,7 +568,7 @@ static int offset_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
568568
char buf[20];
569569

570570
if (he->mem_info)
571-
addr = cl_offset(he->mem_info->daddr.al_addr, chk_double_cl);
571+
addr = cl_offset(mem_info__daddr(he->mem_info)->al_addr, chk_double_cl);
572572

573573
return scnprintf(hpp->buf, hpp->size, "%*s", width, HEX_STR(buf, addr));
574574
}
@@ -580,10 +580,10 @@ offset_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
580580
uint64_t l = 0, r = 0;
581581

582582
if (left->mem_info)
583-
l = cl_offset(left->mem_info->daddr.addr, chk_double_cl);
583+
l = cl_offset(mem_info__daddr(left->mem_info)->addr, chk_double_cl);
584584

585585
if (right->mem_info)
586-
r = cl_offset(right->mem_info->daddr.addr, chk_double_cl);
586+
r = cl_offset(mem_info__daddr(right->mem_info)->addr, chk_double_cl);
587587

588588
return (int64_t)(r - l);
589589
}
@@ -597,7 +597,7 @@ iaddr_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
597597
char buf[20];
598598

599599
if (he->mem_info)
600-
addr = he->mem_info->iaddr.addr;
600+
addr = mem_info__iaddr(he->mem_info)->addr;
601601

602602
return scnprintf(hpp->buf, hpp->size, "%*s", width, HEX_STR(buf, addr));
603603
}
@@ -2593,7 +2593,7 @@ perf_c2c_cacheline_browser__title(struct hist_browser *browser,
25932593
he = cl_browser->he;
25942594

25952595
if (he->mem_info)
2596-
addr = cl_address(he->mem_info->daddr.addr, chk_double_cl);
2596+
addr = cl_address(mem_info__daddr(he->mem_info)->addr, chk_double_cl);
25972597

25982598
scnprintf(bf, size, "Cacheline 0x%lx", addr);
25992599
return 0;

tools/perf/builtin-report.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ static int hist_iter__report_callback(struct hist_entry_iter *iter,
186186

187187
} else if (rep->mem_mode) {
188188
mi = he->mem_info;
189-
err = addr_map_symbol__inc_samples(&mi->daddr, sample, evsel);
189+
err = addr_map_symbol__inc_samples(mem_info__daddr(mi), sample, evsel);
190190
if (err)
191191
goto out;
192192

tools/perf/builtin-script.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,13 +2051,18 @@ static int evlist__max_name_len(struct evlist *evlist)
20512051

20522052
static int data_src__fprintf(u64 data_src, FILE *fp)
20532053
{
2054-
struct mem_info mi = { .data_src.val = data_src };
2054+
struct mem_info *mi = mem_info__new();
20552055
char decode[100];
20562056
char out[100];
20572057
static int maxlen;
20582058
int len;
20592059

2060-
perf_script__meminfo_scnprintf(decode, 100, &mi);
2060+
if (!mi)
2061+
return -ENOMEM;
2062+
2063+
mem_info__data_src(mi)->val = data_src;
2064+
perf_script__meminfo_scnprintf(decode, 100, mi);
2065+
mem_info__put(mi);
20612066

20622067
len = scnprintf(out, 100, "%16" PRIx64 " %s", data_src, decode);
20632068
if (maxlen < len)
@@ -2498,7 +2503,7 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
24982503
evsel = evlist__last(*pevlist);
24992504

25002505
if (!evsel->priv) {
2501-
if (scr->per_event_dump) {
2506+
if (scr->per_event_dump) {
25022507
evsel->priv = evsel_script__new(evsel, scr->session->data);
25032508
if (!evsel->priv)
25042509
return -ENOMEM;

tools/perf/tests/mem.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ static int check(union perf_mem_data_src data_src,
1313
{
1414
char out[100];
1515
char failure[100];
16-
struct mem_info mi = { .data_src = data_src };
17-
16+
struct mem_info *mi = mem_info__new();
1817
int n;
1918

20-
n = perf_mem__snp_scnprintf(out, sizeof out, &mi);
21-
n += perf_mem__lvl_scnprintf(out + n, sizeof out - n, &mi);
19+
TEST_ASSERT_VAL("Memory allocation failed", mi);
20+
*mem_info__data_src(mi) = data_src;
21+
n = perf_mem__snp_scnprintf(out, sizeof out, mi);
22+
n += perf_mem__lvl_scnprintf(out + n, sizeof out - n, mi);
23+
mem_info__put(mi);
2224
scnprintf(failure, sizeof failure, "unexpected %s", out);
2325
TEST_ASSERT_VAL(failure, !strcmp(string, out));
2426
return 0;

tools/perf/util/hist.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
154154
}
155155

156156
if (h->mem_info) {
157-
if (h->mem_info->daddr.ms.sym) {
158-
symlen = (int)h->mem_info->daddr.ms.sym->namelen + 4
157+
if (mem_info__daddr(h->mem_info)->ms.sym) {
158+
symlen = (int)mem_info__daddr(h->mem_info)->ms.sym->namelen + 4
159159
+ unresolved_col_width + 2;
160160
hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL,
161161
symlen);
@@ -169,8 +169,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
169169
symlen);
170170
}
171171

172-
if (h->mem_info->iaddr.ms.sym) {
173-
symlen = (int)h->mem_info->iaddr.ms.sym->namelen + 4
172+
if (mem_info__iaddr(h->mem_info)->ms.sym) {
173+
symlen = (int)mem_info__iaddr(h->mem_info)->ms.sym->namelen + 4
174174
+ unresolved_col_width + 2;
175175
hists__new_col_len(hists, HISTC_MEM_IADDR_SYMBOL,
176176
symlen);
@@ -180,8 +180,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
180180
symlen);
181181
}
182182

183-
if (h->mem_info->daddr.ms.map) {
184-
symlen = dso__name_len(map__dso(h->mem_info->daddr.ms.map));
183+
if (mem_info__daddr(h->mem_info)->ms.map) {
184+
symlen = dso__name_len(map__dso(mem_info__daddr(h->mem_info)->ms.map));
185185
hists__new_col_len(hists, HISTC_MEM_DADDR_DSO,
186186
symlen);
187187
} else {
@@ -477,8 +477,10 @@ static int hist_entry__init(struct hist_entry *he,
477477
}
478478

479479
if (he->mem_info) {
480-
he->mem_info->iaddr.ms.map = map__get(he->mem_info->iaddr.ms.map);
481-
he->mem_info->daddr.ms.map = map__get(he->mem_info->daddr.ms.map);
480+
mem_info__iaddr(he->mem_info)->ms.map =
481+
map__get(mem_info__iaddr(he->mem_info)->ms.map);
482+
mem_info__daddr(he->mem_info)->ms.map =
483+
map__get(mem_info__daddr(he->mem_info)->ms.map);
482484
}
483485

484486
if (hist_entry__has_callchains(he) && symbol_conf.use_callchain)
@@ -526,8 +528,8 @@ static int hist_entry__init(struct hist_entry *he,
526528
zfree(&he->branch_info);
527529
}
528530
if (he->mem_info) {
529-
map_symbol__exit(&he->mem_info->iaddr.ms);
530-
map_symbol__exit(&he->mem_info->daddr.ms);
531+
map_symbol__exit(&mem_info__iaddr(he->mem_info)->ms);
532+
map_symbol__exit(&mem_info__daddr(he->mem_info)->ms);
531533
}
532534
err:
533535
map_symbol__exit(&he->ms);
@@ -1336,8 +1338,8 @@ void hist_entry__delete(struct hist_entry *he)
13361338
}
13371339

13381340
if (he->mem_info) {
1339-
map_symbol__exit(&he->mem_info->iaddr.ms);
1340-
map_symbol__exit(&he->mem_info->daddr.ms);
1341+
map_symbol__exit(&mem_info__iaddr(he->mem_info)->ms);
1342+
map_symbol__exit(&mem_info__daddr(he->mem_info)->ms);
13411343
mem_info__zput(he->mem_info);
13421344
}
13431345

tools/perf/util/machine.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2013,11 +2013,11 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,
20132013
if (!mi)
20142014
return NULL;
20152015

2016-
ip__resolve_ams(al->thread, &mi->iaddr, sample->ip);
2017-
ip__resolve_data(al->thread, al->cpumode, &mi->daddr,
2016+
ip__resolve_ams(al->thread, mem_info__iaddr(mi), sample->ip);
2017+
ip__resolve_data(al->thread, al->cpumode, mem_info__daddr(mi),
20182018
sample->addr, sample->phys_addr,
20192019
sample->data_page_size);
2020-
mi->data_src.val = sample->data_src;
2020+
mem_info__data_src(mi)->val = sample->data_src;
20212021

20222022
return mi;
20232023
}

tools/perf/util/mem-events.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ int perf_mem__tlb_scnprintf(char *out, size_t sz, const struct mem_info *mem_inf
293293
out[0] = '\0';
294294

295295
if (mem_info)
296-
m = mem_info->data_src.mem_dtlb;
296+
m = mem_info__const_data_src(mem_info)->mem_dtlb;
297297

298298
hit = m & PERF_MEM_TLB_HIT;
299299
miss = m & PERF_MEM_TLB_MISS;
@@ -367,7 +367,7 @@ static int perf_mem__op_scnprintf(char *out, size_t sz, const struct mem_info *m
367367
int l;
368368

369369
if (mem_info)
370-
op = mem_info->data_src.mem_op;
370+
op = mem_info__const_data_src(mem_info)->mem_op;
371371

372372
if (op & PERF_MEM_OP_NA)
373373
l = scnprintf(out, sz, "N/A");
@@ -400,7 +400,7 @@ int perf_mem__lvl_scnprintf(char *out, size_t sz, const struct mem_info *mem_inf
400400
if (!mem_info)
401401
goto na;
402402

403-
data_src = mem_info->data_src;
403+
data_src = *mem_info__const_data_src(mem_info);
404404

405405
if (data_src.mem_lvl & PERF_MEM_LVL_HIT)
406406
memcpy(hit_miss, "hit", 3);
@@ -476,7 +476,7 @@ int perf_mem__snp_scnprintf(char *out, size_t sz, const struct mem_info *mem_inf
476476
out[0] = '\0';
477477

478478
if (mem_info)
479-
m = mem_info->data_src.mem_snoop;
479+
m = mem_info__const_data_src(mem_info)->mem_snoop;
480480

481481
for (i = 0; m && i < ARRAY_SIZE(snoop_access); i++, m >>= 1) {
482482
if (!(m & 0x1))
@@ -490,7 +490,7 @@ int perf_mem__snp_scnprintf(char *out, size_t sz, const struct mem_info *mem_inf
490490

491491
m = 0;
492492
if (mem_info)
493-
m = mem_info->data_src.mem_snoopx;
493+
m = mem_info__const_data_src(mem_info)->mem_snoopx;
494494

495495
for (i = 0; m && i < ARRAY_SIZE(snoopx_access); i++, m >>= 1) {
496496
if (!(m & 0x1))
@@ -515,7 +515,7 @@ int perf_mem__lck_scnprintf(char *out, size_t sz, const struct mem_info *mem_inf
515515
int l;
516516

517517
if (mem_info)
518-
mask = mem_info->data_src.mem_lock;
518+
mask = mem_info__const_data_src(mem_info)->mem_lock;
519519

520520
if (mask & PERF_MEM_LOCK_NA)
521521
l = scnprintf(out, sz, "N/A");
@@ -536,7 +536,7 @@ int perf_mem__blk_scnprintf(char *out, size_t sz, const struct mem_info *mem_inf
536536
out[0] = '\0';
537537

538538
if (mem_info)
539-
mask = mem_info->data_src.mem_blk;
539+
mask = mem_info__const_data_src(mem_info)->mem_blk;
540540

541541
if (!mask || (mask & PERF_MEM_BLK_NA)) {
542542
l += scnprintf(out + l, sz - l, " N/A");
@@ -572,8 +572,8 @@ int perf_script__meminfo_scnprintf(char *out, size_t sz, const struct mem_info *
572572

573573
int c2c_decode_stats(struct c2c_stats *stats, struct mem_info *mi)
574574
{
575-
union perf_mem_data_src *data_src = &mi->data_src;
576-
u64 daddr = mi->daddr.addr;
575+
union perf_mem_data_src *data_src = mem_info__data_src(mi);
576+
u64 daddr = mem_info__daddr(mi)->addr;
577577
u64 op = data_src->mem_op;
578578
u64 lvl = data_src->mem_lvl;
579579
u64 snoop = data_src->mem_snoop;
@@ -700,7 +700,7 @@ do { \
700700
return -1;
701701
}
702702

703-
if (!mi->daddr.ms.map || !mi->iaddr.ms.map) {
703+
if (!mem_info__daddr(mi)->ms.map || !mem_info__iaddr(mi)->ms.map) {
704704
stats->nomap++;
705705
return -1;
706706
}

tools/perf/util/mem-info.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,32 @@
44

55
struct mem_info *mem_info__get(struct mem_info *mi)
66
{
7-
if (mi)
8-
refcount_inc(&mi->refcnt);
9-
return mi;
7+
struct mem_info *result;
8+
9+
if (RC_CHK_GET(result, mi))
10+
refcount_inc(mem_info__refcnt(mi));
11+
12+
return result;
1013
}
1114

1215
void mem_info__put(struct mem_info *mi)
1316
{
14-
if (mi && refcount_dec_and_test(&mi->refcnt)) {
15-
addr_map_symbol__exit(&mi->iaddr);
16-
addr_map_symbol__exit(&mi->daddr);
17-
free(mi);
17+
if (mi && refcount_dec_and_test(mem_info__refcnt(mi))) {
18+
addr_map_symbol__exit(mem_info__iaddr(mi));
19+
addr_map_symbol__exit(mem_info__daddr(mi));
20+
RC_CHK_FREE(mi);
21+
} else {
22+
RC_CHK_PUT(mi);
1823
}
1924
}
2025

2126
struct mem_info *mem_info__new(void)
2227
{
23-
struct mem_info *mi = zalloc(sizeof(*mi));
28+
struct mem_info *result = NULL;
29+
RC_STRUCT(mem_info) *mi = zalloc(sizeof(*mi));
30+
31+
if (ADD_RC_CHK(result, mi))
32+
refcount_set(mem_info__refcnt(result), 1);
2433

25-
if (mi)
26-
refcount_set(&mi->refcnt, 1);
27-
return mi;
34+
return result;
2835
}

tools/perf/util/mem-info.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44

55
#include <linux/refcount.h>
66
#include <linux/perf_event.h>
7+
#include <internal/rc_check.h>
78
#include "map_symbol.h"
89

9-
struct mem_info {
10+
DECLARE_RC_STRUCT(mem_info) {
1011
struct addr_map_symbol iaddr;
1112
struct addr_map_symbol daddr;
1213
union perf_mem_data_src data_src;
@@ -25,4 +26,29 @@ static inline void __mem_info__zput(struct mem_info **mi)
2526

2627
#define mem_info__zput(mi) __mem_info__zput(&mi)
2728

29+
static inline struct addr_map_symbol *mem_info__iaddr(struct mem_info *mi)
30+
{
31+
return &RC_CHK_ACCESS(mi)->iaddr;
32+
}
33+
34+
static inline struct addr_map_symbol *mem_info__daddr(struct mem_info *mi)
35+
{
36+
return &RC_CHK_ACCESS(mi)->daddr;
37+
}
38+
39+
static inline union perf_mem_data_src *mem_info__data_src(struct mem_info *mi)
40+
{
41+
return &RC_CHK_ACCESS(mi)->data_src;
42+
}
43+
44+
static inline const union perf_mem_data_src *mem_info__const_data_src(const struct mem_info *mi)
45+
{
46+
return &RC_CHK_ACCESS(mi)->data_src;
47+
}
48+
49+
static inline refcount_t *mem_info__refcnt(struct mem_info *mi)
50+
{
51+
return &RC_CHK_ACCESS(mi)->refcnt;
52+
}
53+
2854
#endif /* __PERF_MEM_INFO_H */

tools/perf/util/scripting-engines/trace-event-python.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -721,15 +721,20 @@ static void set_sample_read_in_dict(PyObject *dict_sample,
721721
}
722722

723723
static void set_sample_datasrc_in_dict(PyObject *dict,
724-
struct perf_sample *sample)
724+
struct perf_sample *sample)
725725
{
726-
struct mem_info mi = { .data_src.val = sample->data_src };
726+
struct mem_info *mi = mem_info__new();
727727
char decode[100];
728728

729+
if (!mi)
730+
Py_FatalError("couldn't create mem-info");
731+
729732
pydict_set_item_string_decref(dict, "datasrc",
730733
PyLong_FromUnsignedLongLong(sample->data_src));
731734

732-
perf_script__meminfo_scnprintf(decode, 100, &mi);
735+
mem_info__data_src(mi)->val = sample->data_src;
736+
perf_script__meminfo_scnprintf(decode, 100, mi);
737+
mem_info__put(mi);
733738

734739
pydict_set_item_string_decref(dict, "datasrc_decode",
735740
_PyUnicode_FromString(decode));

0 commit comments

Comments
 (0)