]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
perf mem-info: Add reference count checking
authorIan Rogers <irogers@google.com>
Tue, 7 May 2024 18:35:44 +0000 (11:35 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 7 May 2024 21:06:44 +0000 (18:06 -0300)
Add reference count checking and switch 'struct mem_info' usage to use
accessor functions.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Ben Gainey <ben.gainey@arm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Li Dong <lidong@vivo.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Oliver Upton <oliver.upton@linux.dev>
Cc: Paran Lee <p4ranlee@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Sun Haiyong <sunhaiyong@loongson.cn>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Yanteng Si <siyanteng@loongson.cn>
Cc: Yicong Yang <yangyicong@hisilicon.com>
Link: https://lore.kernel.org/r/20240507183545.1236093-8-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/builtin-c2c.c
tools/perf/builtin-report.c
tools/perf/builtin-script.c
tools/perf/tests/mem.c
tools/perf/util/hist.c
tools/perf/util/machine.c
tools/perf/util/mem-events.c
tools/perf/util/mem-info.c
tools/perf/util/mem-info.h
tools/perf/util/scripting-engines/trace-event-python.c
tools/perf/util/sort.c

index c624414b22853866d02bdd77dff0656140ea4fc3..c157bd31f2e5a462087e928718e7bfbf7b4cf0bf 100644 (file)
@@ -530,7 +530,7 @@ static int dcacheline_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
        char buf[20];
 
        if (he->mem_info)
-               addr = cl_address(he->mem_info->daddr.addr, chk_double_cl);
+               addr = cl_address(mem_info__daddr(he->mem_info)->addr, chk_double_cl);
 
        return scnprintf(hpp->buf, hpp->size, "%*s", width, HEX_STR(buf, addr));
 }
@@ -568,7 +568,7 @@ static int offset_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
        char buf[20];
 
        if (he->mem_info)
-               addr = cl_offset(he->mem_info->daddr.al_addr, chk_double_cl);
+               addr = cl_offset(mem_info__daddr(he->mem_info)->al_addr, chk_double_cl);
 
        return scnprintf(hpp->buf, hpp->size, "%*s", width, HEX_STR(buf, addr));
 }
@@ -580,10 +580,10 @@ offset_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
        uint64_t l = 0, r = 0;
 
        if (left->mem_info)
-               l = cl_offset(left->mem_info->daddr.addr, chk_double_cl);
+               l = cl_offset(mem_info__daddr(left->mem_info)->addr, chk_double_cl);
 
        if (right->mem_info)
-               r = cl_offset(right->mem_info->daddr.addr, chk_double_cl);
+               r = cl_offset(mem_info__daddr(right->mem_info)->addr, chk_double_cl);
 
        return (int64_t)(r - l);
 }
@@ -597,7 +597,7 @@ iaddr_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
        char buf[20];
 
        if (he->mem_info)
-               addr = he->mem_info->iaddr.addr;
+               addr = mem_info__iaddr(he->mem_info)->addr;
 
        return scnprintf(hpp->buf, hpp->size, "%*s", width, HEX_STR(buf, addr));
 }
@@ -2593,7 +2593,7 @@ perf_c2c_cacheline_browser__title(struct hist_browser *browser,
        he = cl_browser->he;
 
        if (he->mem_info)
-               addr = cl_address(he->mem_info->daddr.addr, chk_double_cl);
+               addr = cl_address(mem_info__daddr(he->mem_info)->addr, chk_double_cl);
 
        scnprintf(bf, size, "Cacheline 0x%lx", addr);
        return 0;
index 6eb1d90b589f391cdeaecb66e553051fbd3c36d6..0892b6e3e5e77674f2c16a6edeb3c7f0199bb897 100644 (file)
@@ -186,7 +186,7 @@ static int hist_iter__report_callback(struct hist_entry_iter *iter,
 
        } else if (rep->mem_mode) {
                mi = he->mem_info;
-               err = addr_map_symbol__inc_samples(&mi->daddr, sample, evsel);
+               err = addr_map_symbol__inc_samples(mem_info__daddr(mi), sample, evsel);
                if (err)
                        goto out;
 
index 58af4f3aa592bb265b1e6916a246a58b5aa01ee9..c16224b1fef3fdebfaa8b01fa95e143aeb7491ab 100644 (file)
@@ -2051,13 +2051,18 @@ static int evlist__max_name_len(struct evlist *evlist)
 
 static int data_src__fprintf(u64 data_src, FILE *fp)
 {
-       struct mem_info mi = { .data_src.val = data_src };
+       struct mem_info *mi = mem_info__new();
        char decode[100];
        char out[100];
        static int maxlen;
        int len;
 
-       perf_script__meminfo_scnprintf(decode, 100, &mi);
+       if (!mi)
+               return -ENOMEM;
+
+       mem_info__data_src(mi)->val = data_src;
+       perf_script__meminfo_scnprintf(decode, 100, mi);
+       mem_info__put(mi);
 
        len = scnprintf(out, 100, "%16" PRIx64 " %s", data_src, decode);
        if (maxlen < len)
@@ -2498,7 +2503,7 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
        evsel = evlist__last(*pevlist);
 
        if (!evsel->priv) {
-               if (scr->per_event_dump) { 
+               if (scr->per_event_dump) {
                        evsel->priv = evsel_script__new(evsel, scr->session->data);
                        if (!evsel->priv)
                                return -ENOMEM;
index f694a60d8a73a57879634788653bf704a4f38817..cb3d749e157b08b2e77fb2089f011fbbc6365310 100644 (file)
@@ -13,12 +13,14 @@ static int check(union perf_mem_data_src data_src,
 {
        char out[100];
        char failure[100];
-       struct mem_info mi = { .data_src = data_src };
-
+       struct mem_info *mi = mem_info__new();
        int n;
 
-       n = perf_mem__snp_scnprintf(out, sizeof out, &mi);
-       n += perf_mem__lvl_scnprintf(out + n, sizeof out - n, &mi);
+       TEST_ASSERT_VAL("Memory allocation failed", mi);
+       *mem_info__data_src(mi) = data_src;
+       n = perf_mem__snp_scnprintf(out, sizeof out, mi);
+       n += perf_mem__lvl_scnprintf(out + n, sizeof out - n, mi);
+       mem_info__put(mi);
        scnprintf(failure, sizeof failure, "unexpected %s", out);
        TEST_ASSERT_VAL(failure, !strcmp(string, out));
        return 0;
index 56453a02cdf48dbd8a02dc4ace9cf7968d06b152..00814d42d5f108da169f6af42e03aaaefcb147b4 100644 (file)
@@ -154,8 +154,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
        }
 
        if (h->mem_info) {
-               if (h->mem_info->daddr.ms.sym) {
-                       symlen = (int)h->mem_info->daddr.ms.sym->namelen + 4
+               if (mem_info__daddr(h->mem_info)->ms.sym) {
+                       symlen = (int)mem_info__daddr(h->mem_info)->ms.sym->namelen + 4
                               + unresolved_col_width + 2;
                        hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL,
                                           symlen);
@@ -169,8 +169,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
                                           symlen);
                }
 
-               if (h->mem_info->iaddr.ms.sym) {
-                       symlen = (int)h->mem_info->iaddr.ms.sym->namelen + 4
+               if (mem_info__iaddr(h->mem_info)->ms.sym) {
+                       symlen = (int)mem_info__iaddr(h->mem_info)->ms.sym->namelen + 4
                               + unresolved_col_width + 2;
                        hists__new_col_len(hists, HISTC_MEM_IADDR_SYMBOL,
                                           symlen);
@@ -180,8 +180,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
                                           symlen);
                }
 
-               if (h->mem_info->daddr.ms.map) {
-                       symlen = dso__name_len(map__dso(h->mem_info->daddr.ms.map));
+               if (mem_info__daddr(h->mem_info)->ms.map) {
+                       symlen = dso__name_len(map__dso(mem_info__daddr(h->mem_info)->ms.map));
                        hists__new_col_len(hists, HISTC_MEM_DADDR_DSO,
                                           symlen);
                } else {
@@ -477,8 +477,10 @@ static int hist_entry__init(struct hist_entry *he,
        }
 
        if (he->mem_info) {
-               he->mem_info->iaddr.ms.map = map__get(he->mem_info->iaddr.ms.map);
-               he->mem_info->daddr.ms.map = map__get(he->mem_info->daddr.ms.map);
+               mem_info__iaddr(he->mem_info)->ms.map =
+                       map__get(mem_info__iaddr(he->mem_info)->ms.map);
+               mem_info__daddr(he->mem_info)->ms.map =
+                       map__get(mem_info__daddr(he->mem_info)->ms.map);
        }
 
        if (hist_entry__has_callchains(he) && symbol_conf.use_callchain)
@@ -526,8 +528,8 @@ err_infos:
                zfree(&he->branch_info);
        }
        if (he->mem_info) {
-               map_symbol__exit(&he->mem_info->iaddr.ms);
-               map_symbol__exit(&he->mem_info->daddr.ms);
+               map_symbol__exit(&mem_info__iaddr(he->mem_info)->ms);
+               map_symbol__exit(&mem_info__daddr(he->mem_info)->ms);
        }
 err:
        map_symbol__exit(&he->ms);
@@ -1336,8 +1338,8 @@ void hist_entry__delete(struct hist_entry *he)
        }
 
        if (he->mem_info) {
-               map_symbol__exit(&he->mem_info->iaddr.ms);
-               map_symbol__exit(&he->mem_info->daddr.ms);
+               map_symbol__exit(&mem_info__iaddr(he->mem_info)->ms);
+               map_symbol__exit(&mem_info__daddr(he->mem_info)->ms);
                mem_info__zput(he->mem_info);
        }
 
index d5a01ef926683d780110ee744ae35fc9b5ad0369..8477edefc29978f7adc2aef9782361d60122d4a1 100644 (file)
@@ -2013,11 +2013,11 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,
        if (!mi)
                return NULL;
 
-       ip__resolve_ams(al->thread, &mi->iaddr, sample->ip);
-       ip__resolve_data(al->thread, al->cpumode, &mi->daddr,
+       ip__resolve_ams(al->thread, mem_info__iaddr(mi), sample->ip);
+       ip__resolve_data(al->thread, al->cpumode, mem_info__daddr(mi),
                         sample->addr, sample->phys_addr,
                         sample->data_page_size);
-       mi->data_src.val = sample->data_src;
+       mem_info__data_src(mi)->val = sample->data_src;
 
        return mi;
 }
index f618a5ccc7af6f8cb0f91370ec5ddda2cfdad96a..6dda47bb774faa7887fcf99a77c914e4638e2073 100644 (file)
@@ -293,7 +293,7 @@ int perf_mem__tlb_scnprintf(char *out, size_t sz, const struct mem_info *mem_inf
        out[0] = '\0';
 
        if (mem_info)
-               m = mem_info->data_src.mem_dtlb;
+               m = mem_info__const_data_src(mem_info)->mem_dtlb;
 
        hit = m & PERF_MEM_TLB_HIT;
        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
        int l;
 
        if (mem_info)
-               op = mem_info->data_src.mem_op;
+               op = mem_info__const_data_src(mem_info)->mem_op;
 
        if (op & PERF_MEM_OP_NA)
                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
        if (!mem_info)
                goto na;
 
-       data_src = mem_info->data_src;
+       data_src = *mem_info__const_data_src(mem_info);
 
        if (data_src.mem_lvl & PERF_MEM_LVL_HIT)
                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
        out[0] = '\0';
 
        if (mem_info)
-               m = mem_info->data_src.mem_snoop;
+               m = mem_info__const_data_src(mem_info)->mem_snoop;
 
        for (i = 0; m && i < ARRAY_SIZE(snoop_access); i++, m >>= 1) {
                if (!(m & 0x1))
@@ -490,7 +490,7 @@ int perf_mem__snp_scnprintf(char *out, size_t sz, const struct mem_info *mem_inf
 
        m = 0;
        if (mem_info)
-               m = mem_info->data_src.mem_snoopx;
+               m = mem_info__const_data_src(mem_info)->mem_snoopx;
 
        for (i = 0; m && i < ARRAY_SIZE(snoopx_access); i++, m >>= 1) {
                if (!(m & 0x1))
@@ -515,7 +515,7 @@ int perf_mem__lck_scnprintf(char *out, size_t sz, const struct mem_info *mem_inf
        int l;
 
        if (mem_info)
-               mask = mem_info->data_src.mem_lock;
+               mask = mem_info__const_data_src(mem_info)->mem_lock;
 
        if (mask & PERF_MEM_LOCK_NA)
                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
        out[0] = '\0';
 
        if (mem_info)
-               mask = mem_info->data_src.mem_blk;
+               mask = mem_info__const_data_src(mem_info)->mem_blk;
 
        if (!mask || (mask & PERF_MEM_BLK_NA)) {
                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 *
 
 int c2c_decode_stats(struct c2c_stats *stats, struct mem_info *mi)
 {
-       union perf_mem_data_src *data_src = &mi->data_src;
-       u64 daddr  = mi->daddr.addr;
+       union perf_mem_data_src *data_src = mem_info__data_src(mi);
+       u64 daddr  = mem_info__daddr(mi)->addr;
        u64 op     = data_src->mem_op;
        u64 lvl    = data_src->mem_lvl;
        u64 snoop  = data_src->mem_snoop;
@@ -700,7 +700,7 @@ do {                                \
                return -1;
        }
 
-       if (!mi->daddr.ms.map || !mi->iaddr.ms.map) {
+       if (!mem_info__daddr(mi)->ms.map || !mem_info__iaddr(mi)->ms.map) {
                stats->nomap++;
                return -1;
        }
index ff0dfdb5369ac9a3d980a3a70ceb8e26bb3d08da..27d67721a6950664871665653687f5fa6ad1419e 100644 (file)
@@ -4,25 +4,32 @@
 
 struct mem_info *mem_info__get(struct mem_info *mi)
 {
-       if (mi)
-               refcount_inc(&mi->refcnt);
-       return mi;
+       struct mem_info *result;
+
+       if (RC_CHK_GET(result, mi))
+               refcount_inc(mem_info__refcnt(mi));
+
+       return result;
 }
 
 void mem_info__put(struct mem_info *mi)
 {
-       if (mi && refcount_dec_and_test(&mi->refcnt)) {
-               addr_map_symbol__exit(&mi->iaddr);
-               addr_map_symbol__exit(&mi->daddr);
-               free(mi);
+       if (mi && refcount_dec_and_test(mem_info__refcnt(mi))) {
+               addr_map_symbol__exit(mem_info__iaddr(mi));
+               addr_map_symbol__exit(mem_info__daddr(mi));
+               RC_CHK_FREE(mi);
+       } else {
+               RC_CHK_PUT(mi);
        }
 }
 
 struct mem_info *mem_info__new(void)
 {
-       struct mem_info *mi = zalloc(sizeof(*mi));
+       struct mem_info *result = NULL;
+       RC_STRUCT(mem_info) *mi = zalloc(sizeof(*mi));
+
+       if (ADD_RC_CHK(result, mi))
+               refcount_set(mem_info__refcnt(result), 1);
 
-       if (mi)
-               refcount_set(&mi->refcnt, 1);
-       return mi;
+       return result;
 }
index bb7d8375d73cac9f04b0bffdff0372b2c19c8ee7..0f68e29f311b94ee404f3b3bd65c8306c10ac29c 100644 (file)
@@ -4,9 +4,10 @@
 
 #include <linux/refcount.h>
 #include <linux/perf_event.h>
+#include <internal/rc_check.h>
 #include "map_symbol.h"
 
-struct mem_info {
+DECLARE_RC_STRUCT(mem_info) {
        struct addr_map_symbol  iaddr;
        struct addr_map_symbol  daddr;
        union perf_mem_data_src data_src;
@@ -25,4 +26,29 @@ static inline void __mem_info__zput(struct mem_info **mi)
 
 #define mem_info__zput(mi) __mem_info__zput(&mi)
 
+static inline struct addr_map_symbol *mem_info__iaddr(struct mem_info *mi)
+{
+       return &RC_CHK_ACCESS(mi)->iaddr;
+}
+
+static inline struct addr_map_symbol *mem_info__daddr(struct mem_info *mi)
+{
+       return &RC_CHK_ACCESS(mi)->daddr;
+}
+
+static inline union perf_mem_data_src *mem_info__data_src(struct mem_info *mi)
+{
+       return &RC_CHK_ACCESS(mi)->data_src;
+}
+
+static inline const union perf_mem_data_src *mem_info__const_data_src(const struct mem_info *mi)
+{
+       return &RC_CHK_ACCESS(mi)->data_src;
+}
+
+static inline refcount_t *mem_info__refcnt(struct mem_info *mi)
+{
+       return &RC_CHK_ACCESS(mi)->refcnt;
+}
+
 #endif /* __PERF_MEM_INFO_H */
index c77fe08a0545d5cc69690d53a6725523737e2367..fb00f3ad6815934e102c2cc29476a7f776fa17f8 100644 (file)
@@ -721,15 +721,20 @@ static void set_sample_read_in_dict(PyObject *dict_sample,
 }
 
 static void set_sample_datasrc_in_dict(PyObject *dict,
-                                      struct perf_sample *sample)
+                                     struct perf_sample *sample)
 {
-       struct mem_info mi = { .data_src.val = sample->data_src };
+       struct mem_info *mi = mem_info__new();
        char decode[100];
 
+       if (!mi)
+               Py_FatalError("couldn't create mem-info");
+
        pydict_set_item_string_decref(dict, "datasrc",
                        PyLong_FromUnsignedLongLong(sample->data_src));
 
-       perf_script__meminfo_scnprintf(decode, 100, &mi);
+       mem_info__data_src(mi)->val = sample->data_src;
+       perf_script__meminfo_scnprintf(decode, 100, mi);
+       mem_info__put(mi);
 
        pydict_set_item_string_decref(dict, "datasrc_decode",
                        _PyUnicode_FromString(decode));
index 711ef69306f387227c41a69deac36f47b068a5ee..cd39ea97219372aabf92fa2f27affe3809d38d15 100644 (file)
@@ -1365,9 +1365,9 @@ sort__daddr_cmp(struct hist_entry *left, struct hist_entry *right)
        uint64_t l = 0, r = 0;
 
        if (left->mem_info)
-               l = left->mem_info->daddr.addr;
+               l = mem_info__daddr(left->mem_info)->addr;
        if (right->mem_info)
-               r = right->mem_info->daddr.addr;
+               r = mem_info__daddr(right->mem_info)->addr;
 
        return (int64_t)(r - l);
 }
@@ -1379,8 +1379,8 @@ static int hist_entry__daddr_snprintf(struct hist_entry *he, char *bf,
        struct map_symbol *ms = NULL;
 
        if (he->mem_info) {
-               addr = he->mem_info->daddr.addr;
-               ms = &he->mem_info->daddr.ms;
+               addr = mem_info__daddr(he->mem_info)->addr;
+               ms = &mem_info__daddr(he->mem_info)->ms;
        }
        return _hist_entry__sym_snprintf(ms, addr, he->level, bf, size, width);
 }
@@ -1391,9 +1391,9 @@ sort__iaddr_cmp(struct hist_entry *left, struct hist_entry *right)
        uint64_t l = 0, r = 0;
 
        if (left->mem_info)
-               l = left->mem_info->iaddr.addr;
+               l = mem_info__iaddr(left->mem_info)->addr;
        if (right->mem_info)
-               r = right->mem_info->iaddr.addr;
+               r = mem_info__iaddr(right->mem_info)->addr;
 
        return (int64_t)(r - l);
 }
@@ -1405,8 +1405,8 @@ static int hist_entry__iaddr_snprintf(struct hist_entry *he, char *bf,
        struct map_symbol *ms = NULL;
 
        if (he->mem_info) {
-               addr = he->mem_info->iaddr.addr;
-               ms   = &he->mem_info->iaddr.ms;
+               addr = mem_info__iaddr(he->mem_info)->addr;
+               ms   = &mem_info__iaddr(he->mem_info)->ms;
        }
        return _hist_entry__sym_snprintf(ms, addr, he->level, bf, size, width);
 }
@@ -1418,9 +1418,9 @@ sort__dso_daddr_cmp(struct hist_entry *left, struct hist_entry *right)
        struct map *map_r = NULL;
 
        if (left->mem_info)
-               map_l = left->mem_info->daddr.ms.map;
+               map_l = mem_info__daddr(left->mem_info)->ms.map;
        if (right->mem_info)
-               map_r = right->mem_info->daddr.ms.map;
+               map_r = mem_info__daddr(right->mem_info)->ms.map;
 
        return _sort__dso_cmp(map_l, map_r);
 }
@@ -1431,7 +1431,7 @@ static int hist_entry__dso_daddr_snprintf(struct hist_entry *he, char *bf,
        struct map *map = NULL;
 
        if (he->mem_info)
-               map = he->mem_info->daddr.ms.map;
+               map = mem_info__daddr(he->mem_info)->ms.map;
 
        return _hist_entry__dso_snprintf(map, bf, size, width);
 }
@@ -1443,12 +1443,12 @@ sort__locked_cmp(struct hist_entry *left, struct hist_entry *right)
        union perf_mem_data_src data_src_r;
 
        if (left->mem_info)
-               data_src_l = left->mem_info->data_src;
+               data_src_l = *mem_info__data_src(left->mem_info);
        else
                data_src_l.mem_lock = PERF_MEM_LOCK_NA;
 
        if (right->mem_info)
-               data_src_r = right->mem_info->data_src;
+               data_src_r = *mem_info__data_src(right->mem_info);
        else
                data_src_r.mem_lock = PERF_MEM_LOCK_NA;
 
@@ -1471,12 +1471,12 @@ sort__tlb_cmp(struct hist_entry *left, struct hist_entry *right)
        union perf_mem_data_src data_src_r;
 
        if (left->mem_info)
-               data_src_l = left->mem_info->data_src;
+               data_src_l = *mem_info__data_src(left->mem_info);
        else
                data_src_l.mem_dtlb = PERF_MEM_TLB_NA;
 
        if (right->mem_info)
-               data_src_r = right->mem_info->data_src;
+               data_src_r = *mem_info__data_src(right->mem_info);
        else
                data_src_r.mem_dtlb = PERF_MEM_TLB_NA;
 
@@ -1499,12 +1499,12 @@ sort__lvl_cmp(struct hist_entry *left, struct hist_entry *right)
        union perf_mem_data_src data_src_r;
 
        if (left->mem_info)
-               data_src_l = left->mem_info->data_src;
+               data_src_l = *mem_info__data_src(left->mem_info);
        else
                data_src_l.mem_lvl = PERF_MEM_LVL_NA;
 
        if (right->mem_info)
-               data_src_r = right->mem_info->data_src;
+               data_src_r = *mem_info__data_src(right->mem_info);
        else
                data_src_r.mem_lvl = PERF_MEM_LVL_NA;
 
@@ -1527,12 +1527,12 @@ sort__snoop_cmp(struct hist_entry *left, struct hist_entry *right)
        union perf_mem_data_src data_src_r;
 
        if (left->mem_info)
-               data_src_l = left->mem_info->data_src;
+               data_src_l = *mem_info__data_src(left->mem_info);
        else
                data_src_l.mem_snoop = PERF_MEM_SNOOP_NA;
 
        if (right->mem_info)
-               data_src_r = right->mem_info->data_src;
+               data_src_r = *mem_info__data_src(right->mem_info);
        else
                data_src_r.mem_snoop = PERF_MEM_SNOOP_NA;
 
@@ -1563,8 +1563,8 @@ sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right)
        if (left->cpumode > right->cpumode) return -1;
        if (left->cpumode < right->cpumode) return 1;
 
-       l_map = left->mem_info->daddr.ms.map;
-       r_map = right->mem_info->daddr.ms.map;
+       l_map = mem_info__daddr(left->mem_info)->ms.map;
+       r_map = mem_info__daddr(right->mem_info)->ms.map;
 
        /* if both are NULL, jump to sort on al_addr instead */
        if (!l_map && !r_map)
@@ -1599,8 +1599,8 @@ sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right)
 
 addr:
        /* al_addr does all the right addr - start + offset calculations */
-       l = cl_address(left->mem_info->daddr.al_addr, chk_double_cl);
-       r = cl_address(right->mem_info->daddr.al_addr, chk_double_cl);
+       l = cl_address(mem_info__daddr(left->mem_info)->al_addr, chk_double_cl);
+       r = cl_address(mem_info__daddr(right->mem_info)->al_addr, chk_double_cl);
 
        if (l > r) return -1;
        if (l < r) return 1;
@@ -1617,11 +1617,11 @@ static int hist_entry__dcacheline_snprintf(struct hist_entry *he, char *bf,
        char level = he->level;
 
        if (he->mem_info) {
-               struct map *map = he->mem_info->daddr.ms.map;
+               struct map *map = mem_info__daddr(he->mem_info)->ms.map;
                struct dso *dso = map ? map__dso(map) : NULL;
 
-               addr = cl_address(he->mem_info->daddr.al_addr, chk_double_cl);
-               ms = &he->mem_info->daddr.ms;
+               addr = cl_address(mem_info__daddr(he->mem_info)->al_addr, chk_double_cl);
+               ms = &mem_info__daddr(he->mem_info)->ms;
 
                /* print [s] for shared data mmaps */
                if ((he->cpumode != PERF_RECORD_MISC_KERNEL) &&
@@ -1806,12 +1806,12 @@ sort__blocked_cmp(struct hist_entry *left, struct hist_entry *right)
        union perf_mem_data_src data_src_r;
 
        if (left->mem_info)
-               data_src_l = left->mem_info->data_src;
+               data_src_l = *mem_info__data_src(left->mem_info);
        else
                data_src_l.mem_blk = PERF_MEM_BLK_NA;
 
        if (right->mem_info)
-               data_src_r = right->mem_info->data_src;
+               data_src_r = *mem_info__data_src(right->mem_info);
        else
                data_src_r.mem_blk = PERF_MEM_BLK_NA;
 
@@ -1840,9 +1840,9 @@ sort__phys_daddr_cmp(struct hist_entry *left, struct hist_entry *right)
        uint64_t l = 0, r = 0;
 
        if (left->mem_info)
-               l = left->mem_info->daddr.phys_addr;
+               l = mem_info__daddr(left->mem_info)->phys_addr;
        if (right->mem_info)
-               r = right->mem_info->daddr.phys_addr;
+               r = mem_info__daddr(right->mem_info)->phys_addr;
 
        return (int64_t)(r - l);
 }
@@ -1854,7 +1854,7 @@ static int hist_entry__phys_daddr_snprintf(struct hist_entry *he, char *bf,
        size_t ret = 0;
        size_t len = BITS_PER_LONG / 4;
 
-       addr = he->mem_info->daddr.phys_addr;
+       addr = mem_info__daddr(he->mem_info)->phys_addr;
 
        ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", he->level);
 
@@ -1881,9 +1881,9 @@ sort__data_page_size_cmp(struct hist_entry *left, struct hist_entry *right)
        uint64_t l = 0, r = 0;
 
        if (left->mem_info)
-               l = left->mem_info->daddr.data_page_size;
+               l = mem_info__daddr(left->mem_info)->data_page_size;
        if (right->mem_info)
-               r = right->mem_info->daddr.data_page_size;
+               r = mem_info__daddr(right->mem_info)->data_page_size;
 
        return (int64_t)(r - l);
 }
@@ -1894,7 +1894,7 @@ static int hist_entry__data_page_size_snprintf(struct hist_entry *he, char *bf,
        char str[PAGE_SIZE_NAME_LEN];
 
        return repsep_snprintf(bf, size, "%-*s", width,
-                              get_page_size_name(he->mem_info->daddr.data_page_size, str));
+                       get_page_size_name(mem_info__daddr(he->mem_info)->data_page_size, str));
 }
 
 struct sort_entry sort_mem_data_page_size = {