6a533d52ba
Resolves: bz2088798 Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2088798 Signed-off-by: Pingfan Liu <piliu@redhat.com>
157 lines
4.5 KiB
Diff
157 lines
4.5 KiB
Diff
From aefc85d7b956c4df998afb4cfe5c413e5fd5b062 Mon Sep 17 00:00:00 2001
|
|
From: Sandipan Das <sandipan.das@amd.com>
|
|
Date: Thu, 10 Mar 2022 10:32:51 +0530
|
|
Subject: [PATCH 08/15] x86/zen: Add support for memory access stats
|
|
|
|
Add support for capturing memory access statistics on Zen
|
|
processors using Instruction Based Sampling (IBS).
|
|
|
|
IBS, by design, cannot tag specific types of ops and hence
|
|
cannot provide samples for only those ops that cause memory
|
|
access. Hence, additional post-processing is required for
|
|
filtering out irrelevant samples. To get an appropriate
|
|
volume of samples, the sampling frequency also needs to be
|
|
high.
|
|
|
|
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
|
|
---
|
|
common/os/pfwrapper.c | 20 +++++++++++++++++---
|
|
x86/zen.c | 35 ++++++++++++++++++++++++++++++++++-
|
|
2 files changed, 51 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/common/os/pfwrapper.c b/common/os/pfwrapper.c
|
|
index e08ce07..d6102be 100644
|
|
--- a/common/os/pfwrapper.c
|
|
+++ b/common/os/pfwrapper.c
|
|
@@ -434,7 +434,8 @@ pf_ll_setup(struct _perf_cpu *cpu, pf_conf_t *conf)
|
|
attr.precise_ip = 1;
|
|
attr.exclude_guest = conf->exclude_guest;
|
|
attr.sample_type = PERF_SAMPLE_TID | PERF_SAMPLE_ADDR | PERF_SAMPLE_CPU |
|
|
- PERF_SAMPLE_WEIGHT | PERF_SAMPLE_CALLCHAIN;
|
|
+ PERF_SAMPLE_WEIGHT | PERF_SAMPLE_CALLCHAIN |
|
|
+ PERF_SAMPLE_DATA_SRC;
|
|
attr.disabled = 1;
|
|
|
|
if ((fds[0] = pf_event_open(&attr, -1, cpu->cpuid, -1, 0)) < 0) {
|
|
@@ -481,6 +482,7 @@ ll_sample_read(struct perf_event_mmap_page *mhdr, int size,
|
|
pf_ll_rec_t *rec)
|
|
{
|
|
struct { uint32_t pid, tid; } id;
|
|
+ union perf_mem_data_src data_src;
|
|
uint64_t i, addr, cpu, weight, nr, value, *ips;
|
|
int j, ret = -1;
|
|
|
|
@@ -492,6 +494,7 @@ ll_sample_read(struct perf_event_mmap_page *mhdr, int size,
|
|
* [ u64 nr; }
|
|
* { u64 ips[nr]; }
|
|
* { u64 weight; }
|
|
+ * { u64 data_src; }
|
|
* };
|
|
*/
|
|
if (mmap_buffer_read(mhdr, &id, sizeof (id)) == -1) {
|
|
@@ -551,7 +554,18 @@ ll_sample_read(struct perf_event_mmap_page *mhdr, int size,
|
|
}
|
|
|
|
size -= sizeof (weight);
|
|
-
|
|
+
|
|
+ if (mmap_buffer_read(mhdr, &data_src, sizeof (data_src)) == -1) {
|
|
+ debug_print(NULL, 2, "ll_sample_read: read data_src failed.\n");
|
|
+ goto L_EXIT;
|
|
+ }
|
|
+
|
|
+ size -= sizeof (data_src);
|
|
+
|
|
+ if (data_src.mem_op == PERF_MEM_OP_NA ||
|
|
+ data_src.mem_op == PERF_MEM_OP_EXEC)
|
|
+ addr = 0;
|
|
+
|
|
rec->ip_num = j;
|
|
rec->pid = id.pid;
|
|
rec->tid = id.tid;
|
|
@@ -575,7 +589,7 @@ ll_recbuf_update(pf_ll_rec_t *rec_arr, int *nrec, pf_ll_rec_t *rec)
|
|
{
|
|
int i;
|
|
|
|
- if ((rec->pid == 0) || (rec->tid == 0)) {
|
|
+ if ((rec->pid == 0) || (rec->tid == 0) || (rec->addr == 0)) {
|
|
/* Just consider the user-land process/thread. */
|
|
return;
|
|
}
|
|
diff --git a/x86/zen.c b/x86/zen.c
|
|
index 2f851a2..67a425b 100644
|
|
--- a/x86/zen.c
|
|
+++ b/x86/zen.c
|
|
@@ -30,7 +30,9 @@
|
|
|
|
#include <inttypes.h>
|
|
#include <stdlib.h>
|
|
+#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
+#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
@@ -39,6 +41,9 @@
|
|
#include "../common/include/os/plat.h"
|
|
#include "include/zen.h"
|
|
|
|
+#define IBS_OP_PMU_TYPE_PATH \
|
|
+ "/sys/bus/event_source/devices/ibs_op/type"
|
|
+
|
|
static plat_event_config_t s_zen_config[PERF_COUNT_NUM] = {
|
|
{ PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES, 0, 0, 0, 0, "LsNotHaltedCyc" },
|
|
{ PERF_TYPE_RAW, 0x0000000000004043, 0, 0, 0, 0, "LsDmndFillsFromSys.DRAM_IO_Far" },
|
|
@@ -47,8 +52,13 @@ static plat_event_config_t s_zen_config[PERF_COUNT_NUM] = {
|
|
{ PERF_TYPE_RAW, 0x0000000000000843, 0, 0, 0, 0, "LsDmndFillsFromSys.DRAM_IO_Near" },
|
|
};
|
|
|
|
+/*
|
|
+ * Owing to the nature of IBS uop tagging, a higher sampling period is
|
|
+ * required to capture meaningful samples. All samples may not originate
|
|
+ * from a memory access instruction and require additional filtering.
|
|
+ */
|
|
static plat_event_config_t s_zen_ll = {
|
|
- PERF_TYPE_RAW, 0, 0, 0, 0, 0, "Unsupported"
|
|
+ 0, 0x0000000000000000, 0, 0, LL_THRESH * 10, 0, "IbsOpCntCycles"
|
|
};
|
|
|
|
void
|
|
@@ -57,10 +67,33 @@ zen_profiling_config(perf_count_id_t perf_count_id, plat_event_config_t *cfg)
|
|
plat_config_get(perf_count_id, cfg, s_zen_config);
|
|
}
|
|
|
|
+static int
|
|
+zen_ibs_op_pmu_type(void)
|
|
+{
|
|
+ int fd, type, i;
|
|
+ char buf[32];
|
|
+
|
|
+ if ((fd = open(IBS_OP_PMU_TYPE_PATH, O_RDONLY)) < 0)
|
|
+ return (-1);
|
|
+
|
|
+ if ((i = read(fd, buf, sizeof (buf) - 1)) <= 0) {
|
|
+ close(fd);
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+ close(fd);
|
|
+ buf[i] = 0;
|
|
+ if ((type = atoi(buf)) == 0)
|
|
+ return (-1);
|
|
+
|
|
+ return (type);
|
|
+}
|
|
+
|
|
void
|
|
zen_ll_config(plat_event_config_t *cfg)
|
|
{
|
|
memcpy(cfg, &s_zen_ll, sizeof (plat_event_config_t));
|
|
+ cfg->type = zen_ibs_op_pmu_type();
|
|
}
|
|
|
|
int
|
|
--
|
|
2.31.1
|
|
|