mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
perf tools: Show memory region in perf-script subcommand
Show the memory region in perf-script subcommand. Memory region is found
in the mem_region field of the memory information data source. This
field was included with the introduction of support for the Off-module
Response facility (OMR) [1] in Intel's Diamond Rapids and Nova Lake
Architectures.
An example of perf-script output with the new memory region field is shown
below:
thread 5/0 ... |OP LOAD|LVL L3 hit|SNP HitM|TLB L1 or L2 hit|LCK No|BLK N/A|Region Local-shared-cache ffffffff9f002aba
thread 2/0 ... |OP LOAD|LVL L3 hit|SNP None|TLB L1 or L2 hit|LCK No|BLK N/A|Region Local-shared-cache ffffffff9dc54c95
thread 8/0 ... |OP LOAD|LVL L3 hit|SNP HitM|TLB L1 or L2 hit|LCK No|BLK N/A|Region Other-non-shared-cache ffffffff9dc54db3
thread 0/0 ... |OP LOAD|LVL LFB/MAB hit|SNP None|TLB L1 or L2 hit|LCK No|BLK Addr|Region N/A ffffffff9dc54db3
thread 2/0 ... |OP LOAD|LVL L0 hit|SNP None|TLB L1 or L2 hit|LCK Yes|BLK N/A|Region N/A ffffffff9f002a8c
thread 0/0 ... |OP LOAD|LVL L3 hit|SNP HitM or Fwd|TLB L1 or L2 hit|LCK No|BLK N/A|Region Local-non-shared-cache ffffffff9f002aba
thread 0/0 ... |OP LOAD|LVL L3 hit|SNP None|TLB L1 or L2 hit|LCK No|BLK N/A|Region Local-shared-cache ffffffff9dc54ca7
thread 30/0 ... |OP LOAD|LVL LFB/MAB hit|SNP None|TLB L1 or L2 hit|LCK Yes|BLK N/A|Region N/A ffffffff9dcc1ff2
thread 30/0 ... |OP LOAD|LVL RAM hit|SNP None|TLB L1 or L2 hit|LCK No|BLK N/A|Region Mem-0 ffffffff9dc54c95
thread 19/0 ... |OP LOAD|LVL LFB/MAB hit|SNP None|TLB L1 or L2 hit|LCK No|BLK N/A|Region N/A ffffffff9f002cbb
thread 19/0 ... |OP LOAD|LVL L3 hit|SNP HitM or Fwd|TLB L1 or L2 hit|LCK No|BLK N/A|Region Local-non-shared-cache ffffffff9f002aba
[1]: https://lore.kernel.org/all/20260114011750.350569-1-dapeng1.mi@linux.intel.com/
Reviewed-by: Ian Rogers <irogers@google.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Assisted-by: GitHub-Copilot:claude-opus-4-8
Assisted-by: Sashiko:gemini-3.1-pro-preview
Co-developed-by: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
41544ef9c9
commit
8eca6fa643
|
|
@ -2153,11 +2153,12 @@ static int evlist__max_name_len(struct evlist *evlist)
|
|||
return max;
|
||||
}
|
||||
|
||||
static int data_src__fprintf(u64 data_src, FILE *fp)
|
||||
static int data_src__fprintf(struct perf_session *session,
|
||||
u64 data_src, FILE *fp)
|
||||
{
|
||||
struct mem_info *mi = mem_info__new();
|
||||
char decode[100];
|
||||
char out[100];
|
||||
char decode[200];
|
||||
char out[200];
|
||||
static int maxlen;
|
||||
int len;
|
||||
|
||||
|
|
@ -2165,10 +2166,10 @@ static int data_src__fprintf(u64 data_src, FILE *fp)
|
|||
return -ENOMEM;
|
||||
|
||||
mem_info__data_src(mi)->val = data_src;
|
||||
perf_script__meminfo_scnprintf(decode, 100, mi);
|
||||
perf_script__meminfo_scnprintf(decode, 200, mi, session);
|
||||
mem_info__put(mi);
|
||||
|
||||
len = scnprintf(out, 100, "%16" PRIx64 " %s", data_src, decode);
|
||||
len = scnprintf(out, 200, "%16" PRIx64 " %s", data_src, decode);
|
||||
if (maxlen < len)
|
||||
maxlen = len;
|
||||
|
||||
|
|
@ -2562,7 +2563,7 @@ static void process_event(struct perf_script *script,
|
|||
perf_sample__fprintf_addr(sample, thread, evsel, fp);
|
||||
|
||||
if (PRINT_FIELD(DATA_SRC))
|
||||
data_src__fprintf(sample->data_src, fp);
|
||||
data_src__fprintf(evsel__session(evsel), sample->data_src, fp);
|
||||
|
||||
if (PRINT_FIELD(WEIGHT))
|
||||
fprintf(fp, "%16" PRIu64, sample->weight);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "symbol.h"
|
||||
#include "pmu.h"
|
||||
#include "pmus.h"
|
||||
#include "session.h"
|
||||
|
||||
unsigned int perf_mem_events__loads_ldlat = 30;
|
||||
|
||||
|
|
@ -604,8 +605,77 @@ int perf_mem__blk_scnprintf(char *out, size_t sz, const struct mem_info *mem_inf
|
|||
return l;
|
||||
}
|
||||
|
||||
int perf_script__meminfo_scnprintf(char *out, size_t sz, const struct mem_info *mem_info)
|
||||
static int perf_mem__region_scnprintf(char *out, size_t sz, const struct mem_info *mem_info)
|
||||
{
|
||||
size_t l = 0;
|
||||
u64 mem = PERF_MEM_REGION_NA;
|
||||
|
||||
sz -= 1; /* -1 for null termination */
|
||||
out[0] = '\0';
|
||||
|
||||
if (mem_info)
|
||||
mem = mem_info__const_data_src(mem_info)->mem_region;
|
||||
|
||||
switch (mem) {
|
||||
case PERF_MEM_REGION_NA:
|
||||
case PERF_MEM_REGION_RSVD:
|
||||
l += scnprintf(out + l, sz - l, "N/A");
|
||||
break;
|
||||
case PERF_MEM_REGION_L_SHARE:
|
||||
l += scnprintf(out + l, sz - l, "Local-shared-cache");
|
||||
break;
|
||||
case PERF_MEM_REGION_L_NON_SHARE:
|
||||
l += scnprintf(out + l, sz - l, "Local-non-shared-cache");
|
||||
break;
|
||||
case PERF_MEM_REGION_O_IO:
|
||||
l += scnprintf(out + l, sz - l, "Other-IO");
|
||||
break;
|
||||
case PERF_MEM_REGION_O_SHARE:
|
||||
l += scnprintf(out + l, sz - l, "Other-shared-cache");
|
||||
break;
|
||||
case PERF_MEM_REGION_O_NON_SHARE:
|
||||
l += scnprintf(out + l, sz - l, "Other-non-shared-cache");
|
||||
break;
|
||||
case PERF_MEM_REGION_MMIO:
|
||||
l += scnprintf(out + l, sz - l, "MMIO");
|
||||
break;
|
||||
case PERF_MEM_REGION_MEM0:
|
||||
l += scnprintf(out + l, sz - l, "Mem-0");
|
||||
break;
|
||||
case PERF_MEM_REGION_MEM1:
|
||||
l += scnprintf(out + l, sz - l, "Mem-1");
|
||||
break;
|
||||
case PERF_MEM_REGION_MEM2:
|
||||
l += scnprintf(out + l, sz - l, "Mem-2");
|
||||
break;
|
||||
case PERF_MEM_REGION_MEM3:
|
||||
l += scnprintf(out + l, sz - l, "Mem-3");
|
||||
break;
|
||||
case PERF_MEM_REGION_MEM4:
|
||||
l += scnprintf(out + l, sz - l, "Mem-4");
|
||||
break;
|
||||
case PERF_MEM_REGION_MEM5:
|
||||
l += scnprintf(out + l, sz - l, "Mem-5");
|
||||
break;
|
||||
case PERF_MEM_REGION_MEM6:
|
||||
l += scnprintf(out + l, sz - l, "Mem-6");
|
||||
break;
|
||||
case PERF_MEM_REGION_MEM7:
|
||||
l += scnprintf(out + l, sz - l, "Mem-7");
|
||||
break;
|
||||
default:
|
||||
l += scnprintf(out + l, sz - l, "N/A");
|
||||
break;
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
int perf_script__meminfo_scnprintf(char *out, size_t sz,
|
||||
const struct mem_info *mem_info,
|
||||
struct perf_session *session)
|
||||
{
|
||||
struct perf_env *env;
|
||||
int i = 0;
|
||||
|
||||
i += scnprintf(out, sz, "|OP ");
|
||||
|
|
@ -620,6 +690,21 @@ int perf_script__meminfo_scnprintf(char *out, size_t sz, const struct mem_info *
|
|||
i += perf_mem__lck_scnprintf(out + i, sz - i, mem_info);
|
||||
i += scnprintf(out + i, sz - i, "|BLK ");
|
||||
i += perf_mem__blk_scnprintf(out + i, sz - i, mem_info);
|
||||
if (session) {
|
||||
/*
|
||||
* In case the feature bits are not available, as in
|
||||
* pipe mode, fallback to checking for the existence of
|
||||
* memory ranges
|
||||
*/
|
||||
env = perf_session__env(session);
|
||||
if ((env && session->data->is_pipe && env->nr_memory_ranges) ||
|
||||
perf_header__has_feat(&session->header,
|
||||
HEADER_MEMORY_RANGES)) {
|
||||
i += scnprintf(out + i, sz - i, "|Region ");
|
||||
i += perf_mem__region_scnprintf(out + i, sz - i,
|
||||
mem_info);
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ enum {
|
|||
struct evsel;
|
||||
struct mem_info;
|
||||
struct perf_pmu;
|
||||
struct perf_session;
|
||||
|
||||
extern unsigned int perf_mem_events__loads_ldlat;
|
||||
extern struct perf_mem_event perf_mem_events[PERF_MEM_EVENTS__MAX];
|
||||
|
|
@ -47,7 +48,8 @@ int perf_mem__snp_scnprintf(char *out, size_t sz, const struct mem_info *mem_inf
|
|||
int perf_mem__lck_scnprintf(char *out, size_t sz, const struct mem_info *mem_info);
|
||||
int perf_mem__blk_scnprintf(char *out, size_t sz, const struct mem_info *mem_info);
|
||||
|
||||
int perf_script__meminfo_scnprintf(char *bf, size_t size, const struct mem_info *mem_info);
|
||||
int perf_script__meminfo_scnprintf(char *bf, size_t size, const struct mem_info *mem_info,
|
||||
struct perf_session *session);
|
||||
|
||||
struct c2c_stats {
|
||||
u32 nr_entries;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
#include "stat.h"
|
||||
#include "mem-events.h"
|
||||
#include "util/perf_regs.h"
|
||||
#include "util/session.h"
|
||||
|
||||
#define _PyUnicode_FromString(arg) \
|
||||
PyUnicode_FromString(arg)
|
||||
|
|
@ -694,8 +695,9 @@ static void set_sample_read_in_dict(PyObject *dict_sample, struct perf_sample *s
|
|||
static void set_sample_datasrc_in_dict(PyObject *dict,
|
||||
struct perf_sample *sample)
|
||||
{
|
||||
struct perf_session *session = evsel__session(sample->evsel);
|
||||
struct mem_info *mi = mem_info__new();
|
||||
char decode[100];
|
||||
char decode[200];
|
||||
|
||||
if (!mi)
|
||||
Py_FatalError("couldn't create mem-info");
|
||||
|
|
@ -704,7 +706,7 @@ static void set_sample_datasrc_in_dict(PyObject *dict,
|
|||
PyLong_FromUnsignedLongLong(sample->data_src));
|
||||
|
||||
mem_info__data_src(mi)->val = sample->data_src;
|
||||
perf_script__meminfo_scnprintf(decode, 100, mi);
|
||||
perf_script__meminfo_scnprintf(decode, 200, mi, session);
|
||||
mem_info__put(mi);
|
||||
|
||||
pydict_set_item_string_decref(dict, "datasrc_decode",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user