summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/perf/arch/x86/util/Build1
-rw-r--r--tools/perf/arch/x86/util/mem-events.c44
-rw-r--r--tools/perf/util/evsel.c3
-rw-r--r--tools/perf/util/mem-events.c5
-rw-r--r--tools/perf/util/mem-events.h2
-rw-r--r--tools/perf/util/parse-events.l1
-rw-r--r--tools/perf/util/record.c5
7 files changed, 60 insertions, 1 deletions
diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build
index ce1ec92fecdc..98014613b622 100644
--- a/tools/perf/arch/x86/util/Build
+++ b/tools/perf/arch/x86/util/Build
@@ -7,6 +7,7 @@ perf-y += topdown.o
perf-y += machine.o
perf-y += event.o
perf-y += evlist.o
+perf-y += mem-events.o
perf-$(CONFIG_DWARF) += dwarf-regs.o
perf-$(CONFIG_BPF_PROLOGUE) += dwarf-regs.o
diff --git a/tools/perf/arch/x86/util/mem-events.c b/tools/perf/arch/x86/util/mem-events.c
new file mode 100644
index 000000000000..588110fd8904
--- /dev/null
+++ b/tools/perf/arch/x86/util/mem-events.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "util/pmu.h"
+#include "map_symbol.h"
+#include "mem-events.h"
+
+static char mem_loads_name[100];
+static bool mem_loads_name__init;
+
+#define MEM_LOADS_AUX 0x8203
+#define MEM_LOADS_AUX_NAME "{cpu/mem-loads-aux/,cpu/mem-loads,ldlat=%u/pp}:S"
+
+bool is_mem_loads_aux_event(struct evsel *leader)
+{
+ if (!pmu_have_event("cpu", "mem-loads-aux"))
+ return false;
+
+ return leader->core.attr.config == MEM_LOADS_AUX;
+}
+
+char *perf_mem_events__name(int i)
+{
+ struct perf_mem_event *e = perf_mem_events__ptr(i);
+
+ if (!e)
+ return NULL;
+
+ if (i == PERF_MEM_EVENTS__LOAD) {
+ if (mem_loads_name__init)
+ return mem_loads_name;
+
+ mem_loads_name__init = true;
+
+ if (pmu_have_event("cpu", "mem-loads-aux")) {
+ scnprintf(mem_loads_name, sizeof(mem_loads_name),
+ MEM_LOADS_AUX_NAME, perf_mem_events__loads_ldlat);
+ } else {
+ scnprintf(mem_loads_name, sizeof(mem_loads_name),
+ e->name, perf_mem_events__loads_ldlat);
+ }
+ return mem_loads_name;
+ }
+
+ return (char *)e->name;
+}
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 8b18ec56e266..a8ce6b2ebd61 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -2712,6 +2712,9 @@ int evsel__open_strerror(struct evsel *evsel, struct target *target,
if (perf_missing_features.aux_output)
return scnprintf(msg, size, "The 'aux_output' feature is not supported, update the kernel.");
break;
+ case ENODATA:
+ return scnprintf(msg, size, "Cannot collect data source with the load latency event alone. "
+ "Please add an auxiliary event in front of the load latency event.");
default:
break;
}
diff --git a/tools/perf/util/mem-events.c b/tools/perf/util/mem-events.c
index 19007e463b8a..3edfb889fd9f 100644
--- a/tools/perf/util/mem-events.c
+++ b/tools/perf/util/mem-events.c
@@ -56,6 +56,11 @@ char * __weak perf_mem_events__name(int i)
return (char *)e->name;
}
+__weak bool is_mem_loads_aux_event(struct evsel *leader __maybe_unused)
+{
+ return false;
+}
+
int perf_mem_events__parse(const char *str)
{
char *tok, *saveptr = NULL;
diff --git a/tools/perf/util/mem-events.h b/tools/perf/util/mem-events.h
index 5ef178278909..045a50774153 100644
--- a/tools/perf/util/mem-events.h
+++ b/tools/perf/util/mem-events.h
@@ -9,6 +9,7 @@
#include <linux/refcount.h>
#include <linux/perf_event.h>
#include "stat.h"
+#include "evsel.h"
struct perf_mem_event {
bool record;
@@ -39,6 +40,7 @@ int perf_mem_events__init(void);
char *perf_mem_events__name(int i);
struct perf_mem_event *perf_mem_events__ptr(int i);
+bool is_mem_loads_aux_event(struct evsel *leader);
void perf_mem_events__list(void);
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 9db5097317f4..0b36285a9435 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -356,6 +356,7 @@ bpf-output { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_BPF_OUT
cycles-ct |
cycles-t |
mem-loads |
+mem-loads-aux |
mem-stores |
topdown-[a-z-]+ |
tx-capacity-[a-z-]+ |
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index 1c1f24d9b6d0..f99852d54b14 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -15,6 +15,8 @@
#include "record.h"
#include "../perf-sys.h"
#include "topdown.h"
+#include "map_symbol.h"
+#include "mem-events.h"
/*
* evsel__config_leader_sampling() uses special rules for leader sampling.
@@ -25,7 +27,8 @@ static struct evsel *evsel__read_sampler(struct evsel *evsel, struct evlist *evl
{
struct evsel *leader = evsel->leader;
- if (evsel__is_aux_event(leader) || arch_topdown_sample_read(leader)) {
+ if (evsel__is_aux_event(leader) || arch_topdown_sample_read(leader) ||
+ is_mem_loads_aux_event(leader)) {
evlist__for_each_entry(evlist, evsel) {
if (evsel->leader == leader && evsel != evsel->leader)
return evsel;