diff --git a/kernel.spec b/kernel.spec index 1903cce1c4eb74075c37078aaa5686de0e91fe74..21c0951a31518c3a34ab12a2395e966d35aa9598 100644 --- a/kernel.spec +++ b/kernel.spec @@ -32,7 +32,7 @@ Name: kernel Version: 4.19.90 -Release: %{hulkrelease}.0234 +Release: %{hulkrelease}.0235 Summary: Linux Kernel License: GPLv2 URL: http://www.kernel.org/ @@ -831,6 +831,14 @@ fi %endif %changelog +* Mon Nov 6 2023 YunYi Yang - 4.19.90-2311.1.0.0235 +- Fix the header file location error and adjust the function and structure version. +- perf auxtrace arm64: Add support for parsing HiSilicon PCIe Trace packet +- perf auxtrace arm64: Add support for HiSilicon PCIe Tune and Trace device driver +- perf auxtrace arm: Refactor event list iteration in auxtrace_record__init() +- perf tools: No need to cache the PMUs in ARM SPE auxtrace init routine +- perf tools: Fix record failure when mixed with ARM SPE event +- perf pmu: Move EVENT_SOURCE_DEVICE_PATH to PMU header file * Mon Nov 6 2023 Jiang Yi - 4.19.90-2311.1.0.0234 - spi: hisi-kunpeng: Fix the debugfs directory name incorrect diff --git a/patches/0110-perf-pmu-Move-EVENT_SOURCE_DEVICE_PATH-to-PMU-header.patch b/patches/0110-perf-pmu-Move-EVENT_SOURCE_DEVICE_PATH-to-PMU-header.patch new file mode 100644 index 0000000000000000000000000000000000000000..bf1b4d5678165fbe80abd740a55d61f4042fe2b8 --- /dev/null +++ b/patches/0110-perf-pmu-Move-EVENT_SOURCE_DEVICE_PATH-to-PMU-header.patch @@ -0,0 +1,73 @@ +From 92bf4539580e33003e3597a3ff8ee90fabec66a4 Mon Sep 17 00:00:00 2001 +From: Mathieu Poirier +Date: Thu, 31 Jan 2019 11:47:11 -0700 +Subject: [PATCH 1/7] perf pmu: Move EVENT_SOURCE_DEVICE_PATH to PMU header + file + +mainline inclusion +from mainline-v5.1-rc1 +commit ffe8881eb20b0452e47efe151e870b4fae8bd5d2 +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8DP81 +CVE: NA + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ffe8881eb20b0452e47efe151e870b4fae8bd5d2 + +---------------------------------------------------------------------------- + +Move definition of EVENT_SOURCE_DEVICE_PATH to pmu.h so that it can be +used by other files than pmu.c + +Signed-off-by: Mathieu Poirier +Acked-by: Suzuki K Poulouse +Cc: Adrian Hunter +Cc: Alexander Shishkin +Cc: Alexei Starovoitov +Cc: Greg Kroah-Hartman +Cc: H. Peter Anvin +Cc: Heiko Carstens +Cc: Jiri Olsa +Cc: Mark Rutland +Cc: Martin Schwidefsky +Cc: Namhyung Kim +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: Will Deacon +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-s390@vger.kernel.org +Link: http://lkml.kernel.org/r/20190131184714.20388-5-mathieu.poirier@linaro.org +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: YunYi Yang +--- + tools/perf/util/pmu.c | 2 -- + tools/perf/util/pmu.h | 1 + + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c +index aa91fcb51a6d..23b0600d02f0 100644 +--- a/tools/perf/util/pmu.c ++++ b/tools/perf/util/pmu.c +@@ -29,8 +29,6 @@ struct perf_pmu_format { + struct list_head list; + }; + +-#define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/" +- + int perf_pmu_parse(struct list_head *list, char *name); + extern FILE *perf_pmu_in; + +diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h +index 76fecec7b3f9..350c54e0bd3d 100644 +--- a/tools/perf/util/pmu.h ++++ b/tools/perf/util/pmu.h +@@ -16,6 +16,7 @@ enum { + }; + + #define PERF_PMU_FORMAT_BITS 64 ++#define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/" + + struct perf_event_attr; + +-- +2.27.0 + diff --git a/patches/0111-perf-tools-Fix-record-failure-when-mixed-with-ARM-SP.patch b/patches/0111-perf-tools-Fix-record-failure-when-mixed-with-ARM-SP.patch new file mode 100644 index 0000000000000000000000000000000000000000..65c2c3681bfb4387aae7253c186b0a6e6e80674a --- /dev/null +++ b/patches/0111-perf-tools-Fix-record-failure-when-mixed-with-ARM-SP.patch @@ -0,0 +1,105 @@ +From 7b8c9c01545bd1614004948af4d66875a55bb6f7 Mon Sep 17 00:00:00 2001 +From: Wei Li +Date: Fri, 24 Jul 2020 15:11:10 +0800 +Subject: [PATCH 2/7] perf tools: Fix record failure when mixed with ARM SPE + event + +mainline inclusion +from mainline-v5.9-rc1 +commit 31e81e0bed8b4a9c2bb6914c36cf6a8b4ef8a9b7 +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8DP81 +CVE: NA + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=31e81e0bed8b4a9c2bb6914c36cf6a8b4ef8a9b7 + +---------------------------------------------------------------------------- + +When recording with cache-misses and arm_spe_x event, I found that it +will just fail without showing any error info if i put cache-misses +after 'arm_spe_x' event. + + [root@localhost 0620]# perf record -e cache-misses \ + -e arm_spe_0/ts_enable=1,pct_enable=1,pa_enable=1,load_filter=1,jitter=1,store_filter=1,min_latency=0/ sleep 1 + [ perf record: Woken up 1 times to write data ] + [ perf record: Captured and wrote 0.067 MB perf.data ] + [root@localhost 0620]# + [root@localhost 0620]# perf record -e arm_spe_0/ts_enable=1,pct_enable=1,pa_enable=1,load_filter=1,jitter=1,store_filter=1,min_latency=0/ \ + -e cache-misses sleep 1 + [root@localhost 0620]# + +The current code can only work if the only event to be traced is an +'arm_spe_x', or if it is the last event to be specified. Otherwise the +last event type will be checked against all the arm_spe_pmus[i]->types, +none will match and an out of bound 'i' index will be used in +arm_spe_recording_init(). + +We don't support concurrent multiple arm_spe_x events currently, that +is checked in arm_spe_recording_options(), and it will show the relevant +info. So add the check and record of the first found 'arm_spe_pmu' to +fix this issue here. + +Fixes: ffd3d18c20b8 ("perf tools: Add ARM Statistical Profiling Extensions (SPE) support") +Signed-off-by: Wei Li +Reviewed-by: Mathieu Poirier +Tested-by-by: Leo Yan +Cc: Alexander Shishkin +Cc: Hanjun Guo +Cc: Jiri Olsa +Cc: Kim Phillips +Cc: Mark Rutland +Cc: Mike Leach +Cc: Namhyung Kim +Cc: Peter Zijlstra +Cc: Suzuki Poulouse +Cc: linux-arm-kernel@lists.infradead.org +Link: http://lore.kernel.org/lkml/20200724071111.35593-2-liwei391@huawei.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: YunYi Yang + + Conflicts: + tools/perf/arch/arm/util/auxtrace.c +--- + tools/perf/arch/arm/util/auxtrace.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c +index 1ce6bdbda561..b9d471a0babd 100644 +--- a/tools/perf/arch/arm/util/auxtrace.c ++++ b/tools/perf/arch/arm/util/auxtrace.c +@@ -54,7 +54,7 @@ struct auxtrace_record + struct perf_pmu *cs_etm_pmu; + struct perf_evsel *evsel; + bool found_etm = false; +- bool found_spe = false; ++ struct perf_pmu *found_spe = NULL; + static struct perf_pmu **arm_spe_pmus = NULL; + static int nr_spes = 0; + int i = 0; +@@ -72,12 +72,12 @@ struct auxtrace_record + evsel->attr.type == cs_etm_pmu->type) + found_etm = true; + +- if (!nr_spes) ++ if (!nr_spes || found_spe) + continue; + + for (i = 0; i < nr_spes; i++) { + if (evsel->attr.type == arm_spe_pmus[i]->type) { +- found_spe = true; ++ found_spe = arm_spe_pmus[i]; + break; + } + } +@@ -94,7 +94,7 @@ struct auxtrace_record + + #if defined(__aarch64__) + if (found_spe) +- return arm_spe_recording_init(err, arm_spe_pmus[i]); ++ return arm_spe_recording_init(err, found_spe); + #endif + + /* +-- +2.27.0 + diff --git a/patches/0112-perf-tools-No-need-to-cache-the-PMUs-in-ARM-SPE-auxt.patch b/patches/0112-perf-tools-No-need-to-cache-the-PMUs-in-ARM-SPE-auxt.patch new file mode 100644 index 0000000000000000000000000000000000000000..53eb1af7346e29880005f6b220254f178d54f3fb --- /dev/null +++ b/patches/0112-perf-tools-No-need-to-cache-the-PMUs-in-ARM-SPE-auxt.patch @@ -0,0 +1,83 @@ +From 6d25c7fd1b39c93662e8094519b55f5b577def79 Mon Sep 17 00:00:00 2001 +From: Wei Li +Date: Fri, 24 Jul 2020 15:11:11 +0800 +Subject: [PATCH 3/7] perf tools: No need to cache the PMUs in ARM SPE auxtrace + init routine + +mainline inclusion +from mainline-v5.9-rc1 +commit 3e43d79da1dc9731aee24d8b3e8059a4d2297bfc +category: bugfix +bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8DP81 +CVE: NA + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3e43d79da1dc9731aee24d8b3e8059a4d2297bfc + +---------------------------------------------------------------------------- + +- auxtrace_record__init() is called only once, so there is no point in + using a static variable to cache the results of + find_all_arm_spe_pmus(), make it local and free the results after use. + +- Another reason is, even though SPE is micro-architecture dependent, + but so far it only supports "statistical-profiling-extension-v1" and + we have no chance to use multiple SPE's PMU events in Perf command. + +So remove the useless check code to make it clear. + +Signed-off-by: Wei Li +Reviewed-by: Mathieu Poirier +Cc: Alexander Shishkin +Cc: Hanjun Guo +Cc: Jiri Olsa +Cc: Kim Phillips +Cc: Leo Yan +Cc: Mark Rutland +Cc: Mike Leach +Cc: Namhyung Kim +Cc: Peter Zijlstra +Cc: Suzuki Poulouse +Cc: linux-arm-kernel@lists.infradead.org +Link: http://lore.kernel.org/lkml/20200724071111.35593-3-liwei391@huawei.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: YunYi Yang +--- + tools/perf/arch/arm/util/auxtrace.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c +index b9d471a0babd..acf3b01ff912 100644 +--- a/tools/perf/arch/arm/util/auxtrace.c ++++ b/tools/perf/arch/arm/util/auxtrace.c +@@ -55,17 +55,15 @@ struct auxtrace_record + struct perf_evsel *evsel; + bool found_etm = false; + struct perf_pmu *found_spe = NULL; +- static struct perf_pmu **arm_spe_pmus = NULL; +- static int nr_spes = 0; ++ struct perf_pmu **arm_spe_pmus = NULL; ++ int nr_spes = 0; + int i = 0; + + if (!evlist) + return NULL; + + cs_etm_pmu = perf_pmu__find(CORESIGHT_ETM_PMU_NAME); +- +- if (!arm_spe_pmus) +- arm_spe_pmus = find_all_arm_spe_pmus(&nr_spes, err); ++ arm_spe_pmus = find_all_arm_spe_pmus(&nr_spes, err); + + evlist__for_each_entry(evlist, evsel) { + if (cs_etm_pmu && +@@ -82,6 +80,7 @@ struct auxtrace_record + } + } + } ++ free(arm_spe_pmus); + + if (found_etm && found_spe) { + pr_err("Concurrent ARM Coresight ETM and SPE operation not currently supported\n"); +-- +2.27.0 + diff --git a/patches/0113-perf-auxtrace-arm-Refactor-event-list-iteration-in-a.patch b/patches/0113-perf-auxtrace-arm-Refactor-event-list-iteration-in-a.patch new file mode 100644 index 0000000000000000000000000000000000000000..66ba697d841b3fd95868d4e552e5cc8003c8fa98 --- /dev/null +++ b/patches/0113-perf-auxtrace-arm-Refactor-event-list-iteration-in-a.patch @@ -0,0 +1,144 @@ +From 530c4d8e7a61ea32ec2a3c3f3de442f3c48d8c37 Mon Sep 17 00:00:00 2001 +From: Qi Liu +Date: Thu, 27 Oct 2022 18:36:52 +0800 +Subject: [PATCH 4/7] perf auxtrace arm: Refactor event list iteration in + auxtrace_record__init() + +mainline inclusion +from mainline-v6.1-rc1 +commit 45a3975f8e4c56829ada20f7a6a29095ca05e375 +category: feature +bugzilla: https://gitee.com/openeuler/kernel/issues/I8DP81 +CVE: NA + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=45a3975f8e4c56829ada20f7a6a29095ca05e375 + +-------------------------------------------------------------------------- + +Add find_pmu_for_event() and use to simplify logic in +auxtrace_record_init(). find_pmu_for_event() will be reused in +subsequent patches. + +Reviewed-by: John Garry +Reviewed-by: Jonathan Cameron +Reviewed-by: Leo Yan +Signed-off-by: Qi Liu +Signed-off-by: Yicong Yang +Cc: Alexander Shishkin +Cc: Bjorn Helgaas +Cc: Greg Kroah-Hartman +Cc: Ingo Molnar +Cc: James Clark +Cc: Lorenzo Pieralisi +Cc: Mark Rutland +Cc: Mathieu Poirier +Cc: Mike Leach +Cc: Peter Zijlstra +Cc: Qi Liu +Cc: Shameerali Kolothum Thodi +Cc: Shaokun Zhang +Cc: Suzuki Poulouse +Cc: Will Deacon +Cc: Zeng Prime +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-pci@vger.kernel.org +Cc: linuxarm@huawei.com +Link: https://lore.kernel.org/r/20220927081400.14364-2-yangyicong@huawei.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Wangming Shao +Reviewed-by: Yang Jihong +Reviewed-by: Jay Fang +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + tools/perf/arch/arm/util/auxtrace.c +--- + tools/perf/arch/arm/util/auxtrace.c | 55 +++++++++++++++++++---------- + 1 file changed, 36 insertions(+), 19 deletions(-) + +diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c +index acf3b01ff912..33b72a4071b5 100644 +--- a/tools/perf/arch/arm/util/auxtrace.c ++++ b/tools/perf/arch/arm/util/auxtrace.c +@@ -48,16 +48,32 @@ static struct perf_pmu **find_all_arm_spe_pmus(int *nr_spes, int *err) + return arm_spe_pmus; + } + ++static struct perf_pmu *find_pmu_for_event(struct perf_pmu **pmus, ++ int pmu_nr, struct perf_evsel *evsel) ++{ ++ int i; ++ ++ if (!pmus) ++ return NULL; ++ ++ for (i = 0; i < pmu_nr; i++) { ++ if (evsel->attr.type == pmus[i]->type) ++ return pmus[i]; ++ } ++ ++ return NULL; ++} ++ + struct auxtrace_record + *auxtrace_record__init(struct perf_evlist *evlist, int *err) + { +- struct perf_pmu *cs_etm_pmu; ++ struct perf_pmu *cs_etm_pmu = NULL; ++ struct perf_pmu **arm_spe_pmus = NULL; + struct perf_evsel *evsel; +- bool found_etm = false; ++ struct perf_pmu *found_etm = NULL; + struct perf_pmu *found_spe = NULL; +- struct perf_pmu **arm_spe_pmus = NULL; ++ int auxtrace_event_cnt = 0; + int nr_spes = 0; +- int i = 0; + + if (!evlist) + return NULL; +@@ -66,24 +82,25 @@ struct auxtrace_record + arm_spe_pmus = find_all_arm_spe_pmus(&nr_spes, err); + + evlist__for_each_entry(evlist, evsel) { +- if (cs_etm_pmu && +- evsel->attr.type == cs_etm_pmu->type) +- found_etm = true; +- +- if (!nr_spes || found_spe) +- continue; +- +- for (i = 0; i < nr_spes; i++) { +- if (evsel->attr.type == arm_spe_pmus[i]->type) { +- found_spe = arm_spe_pmus[i]; +- break; +- } +- } ++ if (cs_etm_pmu && !found_etm) ++ found_etm = find_pmu_for_event(&cs_etm_pmu, 1, evsel); ++ ++ if (arm_spe_pmus && !found_spe) ++ found_spe = find_pmu_for_event(arm_spe_pmus, ++ nr_spes, ++ evsel); + } ++ + free(arm_spe_pmus); + +- if (found_etm && found_spe) { +- pr_err("Concurrent ARM Coresight ETM and SPE operation not currently supported\n"); ++ if (found_etm) ++ auxtrace_event_cnt++; ++ ++ if (found_spe) ++ auxtrace_event_cnt++; ++ ++ if (auxtrace_event_cnt > 1) { ++ pr_err("Concurrent AUX trace operation not currently supported\n"); + *err = -EOPNOTSUPP; + return NULL; + } +-- +2.27.0 + diff --git a/patches/0114-perf-auxtrace-arm64-Add-support-for-HiSilicon-PCIe-T.patch b/patches/0114-perf-auxtrace-arm64-Add-support-for-HiSilicon-PCIe-T.patch new file mode 100644 index 0000000000000000000000000000000000000000..8275dc58f9bb967e6cdc378bf652d9ea1950cdb7 --- /dev/null +++ b/patches/0114-perf-auxtrace-arm64-Add-support-for-HiSilicon-PCIe-T.patch @@ -0,0 +1,491 @@ +From 1f30e762f33f9381a1655382b7ff8511b96e75fe Mon Sep 17 00:00:00 2001 +From: Qi Liu +Date: Thu, 27 Oct 2022 18:36:53 +0800 +Subject: [PATCH 5/7] perf auxtrace arm64: Add support for HiSilicon PCIe Tune + and Trace device driver + +mainline inclusion +from mainline-v6.1-rc1 +commit 057381a7ece1b2726509ce47cdb9c1a111acfce9 +category: feature +bugzilla: https://gitee.com/openeuler/kernel/issues/I8DP81 +CVE: NA + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=057381a7ece1b2726509ce47cdb9c1a111acfce9 + +-------------------------------------------------------------------------- + +HiSilicon PCIe tune and trace device (PTT) could dynamically tune the +PCIe link's events, and trace the TLP headers). + +This patch add support for PTT device in perf tool, so users could use +'perf record' to get TLP headers trace data. + +Reviewed-by: Leo Yan +Signed-off-by: Qi Liu +Signed-off-by: Yicong Yang +Acked-by: John Garry +Cc: Alexander Shishkin +Cc: Bjorn Helgaas +Cc: Greg Kroah-Hartman +Cc: Ingo Molnar +Cc: James Clark +Cc: Jonathan Cameron +Cc: Lorenzo Pieralisi +Cc: Mark Rutland +Cc: Mathieu Poirier +Cc: Mike Leach +Cc: Peter Zijlstra +Cc: Qi Liu +Cc: Shameerali Kolothum Thodi +Cc: Shaokun Zhang +Cc: Suzuki Poulouse +Cc: Will Deacon +Cc: Zeng Prime +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-pci@vger.kernel.org +Cc: linuxarm@huawei.com +Link: https://lore.kernel.org/r/20220927081400.14364-3-yangyicong@huawei.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Wangming Shao +Reviewed-by: Yang Jihong +Reviewed-by: Jay Fang +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + tools/perf/arch/arm/util/auxtrace.c + tools/perf/arch/arm64/util/Build + tools/perf/util/auxtrace.c +--- + tools/perf/arch/arm/util/auxtrace.c | 65 +++++++++ + tools/perf/arch/arm/util/pmu.c | 3 + + tools/perf/arch/arm64/util/Build | 2 +- + tools/perf/arch/arm64/util/hisi-ptt.c | 202 ++++++++++++++++++++++++++ + tools/perf/util/auxtrace.c | 1 + + tools/perf/util/auxtrace.h | 1 + + tools/perf/util/hisi-ptt.h | 16 ++ + 7 files changed, 289 insertions(+), 1 deletion(-) + create mode 100644 tools/perf/arch/arm64/util/hisi-ptt.c + create mode 100644 tools/perf/util/hisi-ptt.h + +diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c +index 33b72a4071b5..aedd3432325b 100644 +--- a/tools/perf/arch/arm/util/auxtrace.c ++++ b/tools/perf/arch/arm/util/auxtrace.c +@@ -4,14 +4,17 @@ + * Author: Mathieu Poirier + */ + ++#include + #include + #include ++#include + + #include "../../util/auxtrace.h" + #include "../../util/evlist.h" + #include "../../util/pmu.h" + #include "cs-etm.h" + #include "arm-spe.h" ++#include "hisi-ptt.h" + + static struct perf_pmu **find_all_arm_spe_pmus(int *nr_spes, int *err) + { +@@ -48,6 +51,52 @@ static struct perf_pmu **find_all_arm_spe_pmus(int *nr_spes, int *err) + return arm_spe_pmus; + } + ++static struct perf_pmu **find_all_hisi_ptt_pmus(int *nr_ptts, int *err) ++{ ++ const char *sysfs = sysfs__mountpoint(); ++ struct perf_pmu **hisi_ptt_pmus = NULL; ++ struct dirent *dent; ++ char path[PATH_MAX]; ++ DIR *dir = NULL; ++ int idx = 0; ++ ++ snprintf(path, PATH_MAX, "%s" EVENT_SOURCE_DEVICE_PATH, sysfs); ++ dir = opendir(path); ++ if (!dir) { ++ pr_err("can't read directory '%s'\n", EVENT_SOURCE_DEVICE_PATH); ++ *err = -EINVAL; ++ return NULL; ++ } ++ ++ while ((dent = readdir(dir))) { ++ if (strstr(dent->d_name, HISI_PTT_PMU_NAME)) ++ (*nr_ptts)++; ++ } ++ ++ if (!(*nr_ptts)) ++ goto out; ++ ++ hisi_ptt_pmus = zalloc(sizeof(struct perf_pmu *) * (*nr_ptts)); ++ if (!hisi_ptt_pmus) { ++ pr_err("hisi_ptt alloc failed\n"); ++ *err = -ENOMEM; ++ goto out; ++ } ++ ++ rewinddir(dir); ++ while ((dent = readdir(dir))) { ++ if (strstr(dent->d_name, HISI_PTT_PMU_NAME) && idx < *nr_ptts) { ++ hisi_ptt_pmus[idx] = perf_pmu__find(dent->d_name); ++ if (hisi_ptt_pmus[idx]) ++ idx++; ++ } ++ } ++ ++out: ++ closedir(dir); ++ return hisi_ptt_pmus; ++} ++ + static struct perf_pmu *find_pmu_for_event(struct perf_pmu **pmus, + int pmu_nr, struct perf_evsel *evsel) + { +@@ -70,16 +119,20 @@ struct auxtrace_record + struct perf_pmu *cs_etm_pmu = NULL; + struct perf_pmu **arm_spe_pmus = NULL; + struct perf_evsel *evsel; ++ struct perf_pmu **hisi_ptt_pmus = NULL; + struct perf_pmu *found_etm = NULL; + struct perf_pmu *found_spe = NULL; ++ struct perf_pmu *found_ptt = NULL; + int auxtrace_event_cnt = 0; + int nr_spes = 0; ++ int nr_ptts = 0; + + if (!evlist) + return NULL; + + cs_etm_pmu = perf_pmu__find(CORESIGHT_ETM_PMU_NAME); + arm_spe_pmus = find_all_arm_spe_pmus(&nr_spes, err); ++ hisi_ptt_pmus = find_all_hisi_ptt_pmus(&nr_ptts, err); + + evlist__for_each_entry(evlist, evsel) { + if (cs_etm_pmu && !found_etm) +@@ -89,9 +142,15 @@ struct auxtrace_record + found_spe = find_pmu_for_event(arm_spe_pmus, + nr_spes, + evsel); ++ ++ if (hisi_ptt_pmus && !found_ptt) ++ found_ptt = find_pmu_for_event(hisi_ptt_pmus, ++ nr_ptts, ++ evsel); + } + + free(arm_spe_pmus); ++ free(hisi_ptt_pmus); + + if (found_etm) + auxtrace_event_cnt++; +@@ -99,6 +158,9 @@ struct auxtrace_record + if (found_spe) + auxtrace_event_cnt++; + ++ if (found_ptt) ++ auxtrace_event_cnt++; ++ + if (auxtrace_event_cnt > 1) { + pr_err("Concurrent AUX trace operation not currently supported\n"); + *err = -EOPNOTSUPP; +@@ -111,6 +173,9 @@ struct auxtrace_record + #if defined(__aarch64__) + if (found_spe) + return arm_spe_recording_init(err, found_spe); ++ ++ if (found_ptt) ++ return hisi_ptt_recording_init(err, found_ptt); + #endif + + /* +diff --git a/tools/perf/arch/arm/util/pmu.c b/tools/perf/arch/arm/util/pmu.c +index e047571e6080..59a2d7ac152d 100644 +--- a/tools/perf/arch/arm/util/pmu.c ++++ b/tools/perf/arch/arm/util/pmu.c +@@ -10,6 +10,7 @@ + + #include "cs-etm.h" + #include "arm-spe.h" ++#include "hisi-ptt.h" + #include "../../util/pmu.h" + + struct perf_event_attr +@@ -23,6 +24,8 @@ struct perf_event_attr + #if defined(__aarch64__) + } else if (strstarts(pmu->name, ARM_SPE_PMU_NAME)) { + return arm_spe_pmu_default_config(pmu); ++ } else if (strstarts(pmu->name, HISI_PTT_PMU_NAME)) { ++ pmu->selectable = true; + #endif + } + +diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build +index 393b9895c247..52ca178cba63 100644 +--- a/tools/perf/arch/arm64/util/Build ++++ b/tools/perf/arch/arm64/util/Build +@@ -9,4 +9,4 @@ libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o + libperf-$(CONFIG_AUXTRACE) += ../../arm/util/pmu.o \ + ../../arm/util/auxtrace.o \ + ../../arm/util/cs-etm.o \ +- arm-spe.o ++ arm-spe.o hisi-ptt.o +diff --git a/tools/perf/arch/arm64/util/hisi-ptt.c b/tools/perf/arch/arm64/util/hisi-ptt.c +new file mode 100644 +index 000000000000..6ade8e7c058a +--- /dev/null ++++ b/tools/perf/arch/arm64/util/hisi-ptt.c +@@ -0,0 +1,202 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * HiSilicon PCIe Trace and Tuning (PTT) support ++ * Copyright (c) 2022 HiSilicon Technologies Co., Ltd. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "../../../util/auxtrace.h" ++#include "../../../util/cpumap.h" ++#include "../../../util/debug.h" ++#include "../../../util/event.h" ++#include "../../../util/evlist.h" ++#include "../../../util/evsel.h" ++#include "../../../util/hisi-ptt.h" ++#include "../../../util/pmu.h" ++#include "../../../util/session.h" ++#include "../../../util/tsc.h" ++ ++#define KiB(x) ((x) * 1024) ++#define MiB(x) ((x) * 1024 * 1024) ++ ++struct hisi_ptt_recording { ++ struct auxtrace_record itr; ++ struct perf_pmu *hisi_ptt_pmu; ++ struct perf_evlist *evlist; ++}; ++ ++static size_t ++hisi_ptt_info_priv_size(struct auxtrace_record *itr __maybe_unused, ++ struct perf_evlist *evlist __maybe_unused) ++{ ++ return HISI_PTT_AUXTRACE_PRIV_SIZE; ++} ++ ++static int hisi_ptt_info_fill(struct auxtrace_record *itr, ++ struct perf_session *session, ++ struct auxtrace_info_event *auxtrace_info, ++ size_t priv_size) ++{ ++ struct hisi_ptt_recording *pttr = ++ container_of(itr, struct hisi_ptt_recording, itr); ++ struct perf_pmu *hisi_ptt_pmu = pttr->hisi_ptt_pmu; ++ ++ if (priv_size != HISI_PTT_AUXTRACE_PRIV_SIZE) ++ return -EINVAL; ++ ++ if (!session->evlist->nr_mmaps) ++ return -EINVAL; ++ ++ auxtrace_info->type = PERF_AUXTRACE_HISI_PTT; ++ auxtrace_info->priv[0] = hisi_ptt_pmu->type; ++ ++ return 0; ++} ++ ++static int hisi_ptt_set_auxtrace_mmap_page(struct record_opts *opts) ++{ ++ bool privileged = geteuid() == 0 || perf_event_paranoid() < 0; ++ ++ if (!opts->full_auxtrace) ++ return 0; ++ ++ if (opts->full_auxtrace && !opts->auxtrace_mmap_pages) { ++ if (privileged) { ++ opts->auxtrace_mmap_pages = MiB(16) / page_size; ++ } else { ++ opts->auxtrace_mmap_pages = KiB(128) / page_size; ++ if (opts->mmap_pages == UINT_MAX) ++ opts->mmap_pages = KiB(256) / page_size; ++ } ++ } ++ ++ /* Validate auxtrace_mmap_pages */ ++ if (opts->auxtrace_mmap_pages) { ++ size_t sz = opts->auxtrace_mmap_pages * (size_t)page_size; ++ size_t min_sz = KiB(8); ++ ++ if (sz < min_sz || !is_power_of_2(sz)) { ++ pr_err("Invalid mmap size for HISI PTT: must be at least %zuKiB and a power of 2\n", ++ min_sz / 1024); ++ return -EINVAL; ++ } ++ } ++ ++ return 0; ++} ++ ++static int hisi_ptt_recording_options(struct auxtrace_record *itr, ++ struct perf_evlist *evlist, ++ struct record_opts *opts) ++{ ++ struct hisi_ptt_recording *pttr = ++ container_of(itr, struct hisi_ptt_recording, itr); ++ struct perf_pmu *hisi_ptt_pmu = pttr->hisi_ptt_pmu; ++ struct perf_evsel *evsel, *hisi_ptt_evsel = NULL; ++ struct perf_evsel *tracking_evsel; ++ int err; ++ ++ pttr->evlist = evlist; ++ evlist__for_each_entry(evlist, evsel) { ++ if (evsel->attr.type == hisi_ptt_pmu->type) { ++ if (hisi_ptt_evsel) { ++ pr_err("There may be only one " ++ HISI_PTT_PMU_NAME "x event\n"); ++ return -EINVAL; ++ } ++ evsel->attr.freq = 0; ++ evsel->attr.sample_period = 1; ++ hisi_ptt_evsel = evsel; ++ opts->full_auxtrace = true; ++ } ++ } ++ ++ err = hisi_ptt_set_auxtrace_mmap_page(opts); ++ if (err) ++ return err; ++ /* ++ * To obtain the auxtrace buffer file descriptor, the auxtrace event ++ * must come first. ++ */ ++ perf_evlist__to_front(evlist, hisi_ptt_evsel); ++ perf_evsel__set_sample_bit(hisi_ptt_evsel, TIME); ++ ++ /* Add dummy event to keep tracking */ ++ err = parse_events(evlist, "dummy:u", NULL); ++ if (err) ++ return err; ++ ++ tracking_evsel = perf_evlist__last(evlist); ++ perf_evlist__set_tracking_event(evlist, tracking_evsel); ++ ++ tracking_evsel->attr.freq = 0; ++ tracking_evsel->attr.sample_period = 1; ++ perf_evsel__set_sample_bit(tracking_evsel, TIME); ++ ++ return 0; ++} ++ ++static u64 hisi_ptt_reference(struct auxtrace_record *itr __maybe_unused) ++{ ++ return rdtsc(); ++} ++ ++static void hisi_ptt_recording_free(struct auxtrace_record *itr) ++{ ++ struct hisi_ptt_recording *pttr = ++ container_of(itr, struct hisi_ptt_recording, itr); ++ ++ free(pttr); ++} ++ ++static int hisi_ptt_read_finish(struct auxtrace_record *itr, int idx) ++{ ++ struct hisi_ptt_recording *sper = ++ container_of(itr, struct hisi_ptt_recording, itr); ++ struct perf_evsel *evsel; ++ ++ evlist__for_each_entry(sper->evlist, evsel) { ++ if (evsel->attr.type == sper->hisi_ptt_pmu->type) { ++ if (evsel->terminated) ++ return 0; ++ else ++ return perf_evlist__enable_event_idx( ++ sper->evlist, evsel, idx); ++ } ++ } ++ return -EINVAL; ++} ++ ++struct auxtrace_record *hisi_ptt_recording_init(int *err, ++ struct perf_pmu *hisi_ptt_pmu) ++{ ++ struct hisi_ptt_recording *pttr; ++ ++ if (!hisi_ptt_pmu) { ++ *err = -ENODEV; ++ return NULL; ++ } ++ ++ pttr = zalloc(sizeof(*pttr)); ++ if (!pttr) { ++ *err = -ENOMEM; ++ return NULL; ++ } ++ ++ pttr->hisi_ptt_pmu = hisi_ptt_pmu; ++ pttr->itr.recording_options = hisi_ptt_recording_options; ++ pttr->itr.info_priv_size = hisi_ptt_info_priv_size; ++ pttr->itr.info_fill = hisi_ptt_info_fill; ++ pttr->itr.free = hisi_ptt_recording_free; ++ pttr->itr.reference = hisi_ptt_reference; ++ pttr->itr.read_finish = hisi_ptt_read_finish; ++ pttr->itr.alignment = 0; ++ ++ *err = 0; ++ return &pttr->itr; ++} +diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c +index aa6dff2083d6..e49cfc622258 100644 +--- a/tools/perf/util/auxtrace.c ++++ b/tools/perf/util/auxtrace.c +@@ -926,6 +926,7 @@ int perf_event__process_auxtrace_info(struct perf_tool *tool __maybe_unused, + return cs_etm__process_auxtrace_info(event, session); + case PERF_AUXTRACE_S390_CPUMSF: + return s390_cpumsf_process_auxtrace_info(event, session); ++ case PERF_AUXTRACE_HISI_PTT: + case PERF_AUXTRACE_UNKNOWN: + default: + return -EINVAL; +diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h +index 70eb94251d45..606a89b016a4 100644 +--- a/tools/perf/util/auxtrace.h ++++ b/tools/perf/util/auxtrace.h +@@ -48,6 +48,7 @@ enum auxtrace_type { + PERF_AUXTRACE_CS_ETM, + PERF_AUXTRACE_ARM_SPE, + PERF_AUXTRACE_S390_CPUMSF, ++ PERF_AUXTRACE_HISI_PTT, + }; + + enum itrace_period_type { +diff --git a/tools/perf/util/hisi-ptt.h b/tools/perf/util/hisi-ptt.h +new file mode 100644 +index 000000000000..82283c81b4c1 +--- /dev/null ++++ b/tools/perf/util/hisi-ptt.h +@@ -0,0 +1,16 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * HiSilicon PCIe Trace and Tuning (PTT) support ++ * Copyright (c) 2022 HiSilicon Technologies Co., Ltd. ++ */ ++ ++#ifndef INCLUDE__PERF_HISI_PTT_H__ ++#define INCLUDE__PERF_HISI_PTT_H__ ++ ++#define HISI_PTT_PMU_NAME "hisi_ptt" ++#define HISI_PTT_AUXTRACE_PRIV_SIZE sizeof(u64) ++ ++struct auxtrace_record *hisi_ptt_recording_init(int *err, ++ struct perf_pmu *hisi_ptt_pmu); ++ ++#endif +-- +2.27.0 + diff --git a/patches/0115-perf-auxtrace-arm64-Add-support-for-parsing-HiSilico.patch b/patches/0115-perf-auxtrace-arm64-Add-support-for-parsing-HiSilico.patch new file mode 100644 index 0000000000000000000000000000000000000000..bcf9a0cf9c905ad13020f8546449390ac88fd52a --- /dev/null +++ b/patches/0115-perf-auxtrace-arm64-Add-support-for-parsing-HiSilico.patch @@ -0,0 +1,548 @@ +From 3451a4904a12680bfea1c556b0f9973ab2f72d57 Mon Sep 17 00:00:00 2001 +From: Qi Liu +Date: Thu, 27 Oct 2022 18:36:54 +0800 +Subject: [PATCH 6/7] perf auxtrace arm64: Add support for parsing HiSilicon + PCIe Trace packet + +mainline inclusion +from mainline-v6.1-rc1 +commit 5e91e57e68090c0e8ab0acecdbb309af8417d415 +category: feature +bugzilla: https://gitee.com/openeuler/kernel/issues/I8DP81 +CVE: NA + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5e91e57e68090c0e8ab0acecdbb309af8417d415 + +-------------------------------------------------------------------------- + +Add support for using 'perf report --dump-raw-trace' to parse PTT packet. + +Example usage: + +Output will contain raw PTT data and its textual representation, such +as (8DW format): + +0 0 0x5810 [0x30]: PERF_RECORD_AUXTRACE size: 0x400000 offset: 0 +ref: 0xa5d50c725 idx: 0 tid: -1 cpu: 0 +. +. ... HISI PTT data: size 4194304 bytes +. 00000000: 00 00 00 00 Prefix +. 00000004: 08 20 00 60 Header DW0 +. 00000008: ff 02 00 01 Header DW1 +. 0000000c: 20 08 00 00 Header DW2 +. 00000010: 10 e7 44 ab Header DW3 +. 00000014: 2a a8 1e 01 Time +. 00000020: 00 00 00 00 Prefix +. 00000024: 01 00 00 60 Header DW0 +. 00000028: 0f 1e 00 01 Header DW1 +. 0000002c: 04 00 00 00 Header DW2 +. 00000030: 40 00 81 02 Header DW3 +. 00000034: ee 02 00 00 Time +.... + +This patch only add basic parsing support according to the definition of +the PTT packet described in Documentation/trace/hisi-ptt.rst. And the +fields of each packet can be further decoded following the PCIe Spec's +definition of TLP packet. + +Signed-off-by: Qi Liu +Signed-off-by: Yicong Yang +Cc: Alexander Shishkin +Cc: Bjorn Helgaas +Cc: Greg Kroah-Hartman +Cc: Ingo Molnar +Cc: James Clark +Cc: John Garry +Cc: Jonathan Cameron +Cc: Leo Yan +Cc: Lorenzo Pieralisi +Cc: Mark Rutland +Cc: Mathieu Poirier +Cc: Mike Leach +Cc: Peter Zijlstra +Cc: Qi Liu +Cc: Shameerali Kolothum Thodi +Cc: Shaokun Zhang +Cc: Suzuki Poulouse +Cc: Will Deacon +Cc: Zeng Prime +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-pci@vger.kernel.org +Cc: linuxarm@huawei.com +Link: https://lore.kernel.org/r/20220927081400.14364-4-yangyicong@huawei.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Wangming Shao +Reviewed-by: Yang Jihong +Reviewed-by: Jay Fang +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + tools/perf/util/Build +--- + tools/perf/util/Build | 2 + + tools/perf/util/auxtrace.c | 2 + + tools/perf/util/hisi-ptt-decoder/Build | 1 + + .../hisi-ptt-decoder/hisi-ptt-pkt-decoder.c | 166 ++++++++++++++++ + .../hisi-ptt-decoder/hisi-ptt-pkt-decoder.h | 32 +++ + tools/perf/util/hisi-ptt.c | 182 ++++++++++++++++++ + tools/perf/util/hisi-ptt.h | 3 + + 7 files changed, 388 insertions(+) + create mode 100644 tools/perf/util/hisi-ptt-decoder/Build + create mode 100644 tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c + create mode 100644 tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h + create mode 100644 tools/perf/util/hisi-ptt.c + +diff --git a/tools/perf/util/Build b/tools/perf/util/Build +index f4148ecffeae..63019cd94fe0 100644 +--- a/tools/perf/util/Build ++++ b/tools/perf/util/Build +@@ -88,6 +88,8 @@ libperf-$(CONFIG_AUXTRACE) += intel-pt.o + libperf-$(CONFIG_AUXTRACE) += intel-bts.o + libperf-$(CONFIG_AUXTRACE) += arm-spe.o + libperf-$(CONFIG_AUXTRACE) += arm-spe-decoder/ ++libperf-$(CONFIG_AUXTRACE) += hisi-ptt.o ++libperf-$(CONFIG_AUXTRACE) += hisi-ptt-decoder/ + libperf-$(CONFIG_AUXTRACE) += s390-cpumsf.o + + ifdef CONFIG_LIBOPENCSD +diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c +index e49cfc622258..6525946d1a1a 100644 +--- a/tools/perf/util/auxtrace.c ++++ b/tools/perf/util/auxtrace.c +@@ -56,6 +56,7 @@ + #include "intel-pt.h" + #include "intel-bts.h" + #include "arm-spe.h" ++#include "hisi-ptt.h" + #include "s390-cpumsf.h" + + #include "sane_ctype.h" +@@ -927,6 +928,7 @@ int perf_event__process_auxtrace_info(struct perf_tool *tool __maybe_unused, + case PERF_AUXTRACE_S390_CPUMSF: + return s390_cpumsf_process_auxtrace_info(event, session); + case PERF_AUXTRACE_HISI_PTT: ++ return hisi_ptt_process_auxtrace_info(event, session); + case PERF_AUXTRACE_UNKNOWN: + default: + return -EINVAL; +diff --git a/tools/perf/util/hisi-ptt-decoder/Build b/tools/perf/util/hisi-ptt-decoder/Build +new file mode 100644 +index 000000000000..da7ab5618c64 +--- /dev/null ++++ b/tools/perf/util/hisi-ptt-decoder/Build +@@ -0,0 +1 @@ ++libperf-$(CONFIG_AUXTRACE) += hisi-ptt-pkt-decoder.o +diff --git a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c +new file mode 100644 +index 000000000000..9b5c5f0d8dc4 +--- /dev/null ++++ b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c +@@ -0,0 +1,166 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * HiSilicon PCIe Trace and Tuning (PTT) support ++ * Copyright (c) 2022 HiSilicon Technologies Co., Ltd. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "../color.h" ++#include "hisi-ptt-pkt-decoder.h" ++ ++/* ++ * For 8DW format, the bit[31:11] of DW0 is always 0x1fffff, which can be ++ * used to distinguish the data format. ++ * 8DW format is like: ++ * bits [ 31:11 ][ 10:0 ] ++ * |---------------------------------------|-------------------| ++ * DW0 [ 0x1fffff ][ Reserved (0x7ff) ] ++ * DW1 [ Prefix ] ++ * DW2 [ Header DW0 ] ++ * DW3 [ Header DW1 ] ++ * DW4 [ Header DW2 ] ++ * DW5 [ Header DW3 ] ++ * DW6 [ Reserved (0x0) ] ++ * DW7 [ Time ] ++ * ++ * 4DW format is like: ++ * bits [31:30] [ 29:25 ][24][23][22][21][ 20:11 ][ 10:0 ] ++ * |-----|---------|---|---|---|---|-------------|-------------| ++ * DW0 [ Fmt ][ Type ][T9][T8][TH][SO][ Length ][ Time ] ++ * DW1 [ Header DW1 ] ++ * DW2 [ Header DW2 ] ++ * DW3 [ Header DW3 ] ++ */ ++ ++enum hisi_ptt_8dw_pkt_field_type { ++ HISI_PTT_8DW_CHK_AND_RSV0, ++ HISI_PTT_8DW_PREFIX, ++ HISI_PTT_8DW_HEAD0, ++ HISI_PTT_8DW_HEAD1, ++ HISI_PTT_8DW_HEAD2, ++ HISI_PTT_8DW_HEAD3, ++ HISI_PTT_8DW_RSV1, ++ HISI_PTT_8DW_TIME, ++ HISI_PTT_8DW_TYPE_MAX ++}; ++ ++enum hisi_ptt_4dw_pkt_field_type { ++ HISI_PTT_4DW_HEAD1, ++ HISI_PTT_4DW_HEAD2, ++ HISI_PTT_4DW_HEAD3, ++ HISI_PTT_4DW_TYPE_MAX ++}; ++ ++static const char * const hisi_ptt_8dw_pkt_field_name[] = { ++ [HISI_PTT_8DW_PREFIX] = "Prefix", ++ [HISI_PTT_8DW_HEAD0] = "Header DW0", ++ [HISI_PTT_8DW_HEAD1] = "Header DW1", ++ [HISI_PTT_8DW_HEAD2] = "Header DW2", ++ [HISI_PTT_8DW_HEAD3] = "Header DW3", ++ [HISI_PTT_8DW_TIME] = "Time" ++}; ++ ++static const char * const hisi_ptt_4dw_pkt_field_name[] = { ++ [HISI_PTT_4DW_HEAD1] = "Header DW1", ++ [HISI_PTT_4DW_HEAD2] = "Header DW2", ++ [HISI_PTT_4DW_HEAD3] = "Header DW3", ++}; ++ ++union hisi_ptt_4dw { ++ struct { ++ uint32_t format : 2; ++ uint32_t type : 5; ++ uint32_t t9 : 1; ++ uint32_t t8 : 1; ++ uint32_t th : 1; ++ uint32_t so : 1; ++ uint32_t len : 10; ++ uint32_t time : 11; ++ }; ++ uint32_t value; ++}; ++ ++static void hisi_ptt_print_pkt(const unsigned char *buf, int pos, ++ const char *desc) ++{ ++ const char *color = PERF_COLOR_BLUE; ++ int i; ++ ++ printf("."); ++ color_fprintf(stdout, color, " %08x: ", pos); ++ for (i = 0; i < HISI_PTT_FIELD_LENGTH; i++) ++ color_fprintf(stdout, color, "%02x ", buf[pos + i]); ++ for (i = 0; i < HISI_PTT_MAX_SPACE_LEN; i++) ++ color_fprintf(stdout, color, " "); ++ color_fprintf(stdout, color, " %s\n", desc); ++} ++ ++static int hisi_ptt_8dw_kpt_desc(const unsigned char *buf, int pos) ++{ ++ int i; ++ ++ for (i = 0; i < HISI_PTT_8DW_TYPE_MAX; i++) { ++ /* Do not show 8DW check field and reserved fields */ ++ if (i == HISI_PTT_8DW_CHK_AND_RSV0 || i == HISI_PTT_8DW_RSV1) { ++ pos += HISI_PTT_FIELD_LENGTH; ++ continue; ++ } ++ ++ hisi_ptt_print_pkt(buf, pos, hisi_ptt_8dw_pkt_field_name[i]); ++ pos += HISI_PTT_FIELD_LENGTH; ++ } ++ ++ return hisi_ptt_pkt_size[HISI_PTT_8DW_PKT]; ++} ++ ++static void hisi_ptt_4dw_print_dw0(const unsigned char *buf, int pos) ++{ ++ const char *color = PERF_COLOR_BLUE; ++ union hisi_ptt_4dw dw0; ++ int i; ++ ++ dw0.value = *(uint32_t *)(buf + pos); ++ printf("."); ++ color_fprintf(stdout, color, " %08x: ", pos); ++ for (i = 0; i < HISI_PTT_FIELD_LENGTH; i++) ++ color_fprintf(stdout, color, "%02x ", buf[pos + i]); ++ for (i = 0; i < HISI_PTT_MAX_SPACE_LEN; i++) ++ color_fprintf(stdout, color, " "); ++ ++ color_fprintf(stdout, color, ++ " %s %x %s %x %s %x %s %x %s %x %s %x %s %x %s %x\n", ++ "Format", dw0.format, "Type", dw0.type, "T9", dw0.t9, ++ "T8", dw0.t8, "TH", dw0.th, "SO", dw0.so, "Length", ++ dw0.len, "Time", dw0.time); ++} ++ ++static int hisi_ptt_4dw_kpt_desc(const unsigned char *buf, int pos) ++{ ++ int i; ++ ++ hisi_ptt_4dw_print_dw0(buf, pos); ++ pos += HISI_PTT_FIELD_LENGTH; ++ ++ for (i = 0; i < HISI_PTT_4DW_TYPE_MAX; i++) { ++ hisi_ptt_print_pkt(buf, pos, hisi_ptt_4dw_pkt_field_name[i]); ++ pos += HISI_PTT_FIELD_LENGTH; ++ } ++ ++ return hisi_ptt_pkt_size[HISI_PTT_4DW_PKT]; ++} ++ ++int hisi_ptt_pkt_desc(const unsigned char *buf, int pos, ++ enum hisi_ptt_pkt_type type) ++{ ++ if (type == HISI_PTT_8DW_PKT) ++ return hisi_ptt_8dw_kpt_desc(buf, pos); ++ ++ return hisi_ptt_4dw_kpt_desc(buf, pos); ++} +diff --git a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h +new file mode 100644 +index 000000000000..198b6f274586 +--- /dev/null ++++ b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h +@@ -0,0 +1,32 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * HiSilicon PCIe Trace and Tuning (PTT) support ++ * Copyright (c) 2022 HiSilicon Technologies Co., Ltd. ++ */ ++ ++#ifndef INCLUDE__HISI_PTT_PKT_DECODER_H__ ++#define INCLUDE__HISI_PTT_PKT_DECODER_H__ ++ ++#include ++#include ++ ++#define HISI_PTT_8DW_CHECK_MASK GENMASK(31, 11) ++#define HISI_PTT_IS_8DW_PKT GENMASK(31, 11) ++#define HISI_PTT_MAX_SPACE_LEN 10 ++#define HISI_PTT_FIELD_LENGTH 4 ++ ++enum hisi_ptt_pkt_type { ++ HISI_PTT_4DW_PKT, ++ HISI_PTT_8DW_PKT, ++ HISI_PTT_PKT_MAX ++}; ++ ++static int hisi_ptt_pkt_size[] = { ++ [HISI_PTT_4DW_PKT] = 16, ++ [HISI_PTT_8DW_PKT] = 32, ++}; ++ ++int hisi_ptt_pkt_desc(const unsigned char *buf, int pos, ++ enum hisi_ptt_pkt_type type); ++ ++#endif +diff --git a/tools/perf/util/hisi-ptt.c b/tools/perf/util/hisi-ptt.c +new file mode 100644 +index 000000000000..29cfa02aa93d +--- /dev/null ++++ b/tools/perf/util/hisi-ptt.c +@@ -0,0 +1,182 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * HiSilicon PCIe Trace and Tuning (PTT) support ++ * Copyright (c) 2022 HiSilicon Technologies Co., Ltd. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "auxtrace.h" ++#include "color.h" ++#include "debug.h" ++#include "evsel.h" ++#include "util.h" ++#include "hisi-ptt.h" ++#include "hisi-ptt-decoder/hisi-ptt-pkt-decoder.h" ++#include "machine.h" ++#include "session.h" ++#include "tool.h" ++ ++struct hisi_ptt { ++ struct auxtrace auxtrace; ++ u32 auxtrace_type; ++ struct perf_session *session; ++ struct machine *machine; ++ u32 pmu_type; ++}; ++ ++struct hisi_ptt_queue { ++ struct hisi_ptt *ptt; ++ struct auxtrace_buffer *buffer; ++}; ++ ++static enum hisi_ptt_pkt_type hisi_ptt_check_packet_type(unsigned char *buf) ++{ ++ uint32_t head = *(uint32_t *)buf; ++ ++ if ((HISI_PTT_8DW_CHECK_MASK & head) == HISI_PTT_IS_8DW_PKT) ++ return HISI_PTT_8DW_PKT; ++ ++ return HISI_PTT_4DW_PKT; ++} ++ ++static void hisi_ptt_dump(struct hisi_ptt *ptt __maybe_unused, ++ unsigned char *buf, size_t len) ++{ ++ const char *color = PERF_COLOR_BLUE; ++ enum hisi_ptt_pkt_type type; ++ size_t pos = 0; ++ int pkt_len; ++ ++ type = hisi_ptt_check_packet_type(buf); ++ len = round_down(len, hisi_ptt_pkt_size[type]); ++ color_fprintf(stdout, color, ". ... HISI PTT data: size %zu bytes\n", ++ len); ++ ++ while (len > 0) { ++ pkt_len = hisi_ptt_pkt_desc(buf, pos, type); ++ if (!pkt_len) ++ color_fprintf(stdout, color, " Bad packet!\n"); ++ ++ pos += pkt_len; ++ len -= pkt_len; ++ } ++} ++ ++static void hisi_ptt_dump_event(struct hisi_ptt *ptt, unsigned char *buf, ++ size_t len) ++{ ++ printf(".\n"); ++ ++ hisi_ptt_dump(ptt, buf, len); ++} ++ ++static int hisi_ptt_process_event(struct perf_session *session __maybe_unused, ++ union perf_event *event __maybe_unused, ++ struct perf_sample *sample __maybe_unused, ++ struct perf_tool *tool __maybe_unused) ++{ ++ return 0; ++} ++ ++static int hisi_ptt_process_auxtrace_event(struct perf_session *session, ++ union perf_event *event, ++ struct perf_tool *tool __maybe_unused) ++{ ++ struct hisi_ptt *ptt = container_of(session->auxtrace, struct hisi_ptt, ++ auxtrace); ++ int fd = perf_data__fd(session->data); ++ int size = event->auxtrace.size; ++ void *data = malloc(size); ++ off_t data_offset; ++ int err; ++ ++ if (!data) ++ return -errno; ++ ++ if (perf_data__is_pipe(session->data)) { ++ data_offset = 0; ++ } else { ++ data_offset = lseek(fd, 0, SEEK_CUR); ++ if (data_offset == -1) ++ return -errno; ++ } ++ ++ err = readn(fd, data, size); ++ if (err != (ssize_t)size) { ++ free(data); ++ return -errno; ++ } ++ ++ if (dump_trace) ++ hisi_ptt_dump_event(ptt, data, size); ++ ++ return 0; ++} ++ ++static int hisi_ptt_flush(struct perf_session *session __maybe_unused, ++ struct perf_tool *tool __maybe_unused) ++{ ++ return 0; ++} ++ ++static void hisi_ptt_free_events(struct perf_session *session __maybe_unused) ++{ ++} ++ ++static void hisi_ptt_free(struct perf_session *session) ++{ ++ struct hisi_ptt *ptt = container_of(session->auxtrace, struct hisi_ptt, ++ auxtrace); ++ ++ session->auxtrace = NULL; ++ free(ptt); ++} ++ ++static void hisi_ptt_print_info(__u64 type) ++{ ++ if (!dump_trace) ++ return; ++ ++ fprintf(stdout, " PMU Type %" PRId64 "\n", (s64) type); ++} ++ ++int hisi_ptt_process_auxtrace_info(union perf_event *event, ++ struct perf_session *session) ++{ ++ struct auxtrace_info_event *auxtrace_info = &event->auxtrace_info; ++ struct hisi_ptt *ptt; ++ ++ if (auxtrace_info->header.size < HISI_PTT_AUXTRACE_PRIV_SIZE + ++ sizeof(struct auxtrace_info_event)) ++ return -EINVAL; ++ ++ ptt = zalloc(sizeof(*ptt)); ++ if (!ptt) ++ return -ENOMEM; ++ ++ ptt->session = session; ++ ptt->machine = &session->machines.host; /* No kvm support */ ++ ptt->auxtrace_type = auxtrace_info->type; ++ ptt->pmu_type = auxtrace_info->priv[0]; ++ ++ ptt->auxtrace.process_event = hisi_ptt_process_event; ++ ptt->auxtrace.process_auxtrace_event = hisi_ptt_process_auxtrace_event; ++ ptt->auxtrace.flush_events = hisi_ptt_flush; ++ ptt->auxtrace.free_events = hisi_ptt_free_events; ++ ptt->auxtrace.free = hisi_ptt_free; ++ session->auxtrace = &ptt->auxtrace; ++ ++ hisi_ptt_print_info(auxtrace_info->priv[0]); ++ ++ return 0; ++} +diff --git a/tools/perf/util/hisi-ptt.h b/tools/perf/util/hisi-ptt.h +index 82283c81b4c1..2db9b4056214 100644 +--- a/tools/perf/util/hisi-ptt.h ++++ b/tools/perf/util/hisi-ptt.h +@@ -13,4 +13,7 @@ + struct auxtrace_record *hisi_ptt_recording_init(int *err, + struct perf_pmu *hisi_ptt_pmu); + ++int hisi_ptt_process_auxtrace_info(union perf_event *event, ++ struct perf_session *session); ++ + #endif +-- +2.27.0 + diff --git a/patches/0116-Fix-the-header-file-location-error-and-adjust-the-fu.patch b/patches/0116-Fix-the-header-file-location-error-and-adjust-the-fu.patch new file mode 100644 index 0000000000000000000000000000000000000000..16c8be97d851d77baa85019ca94df755d9f2a6f9 --- /dev/null +++ b/patches/0116-Fix-the-header-file-location-error-and-adjust-the-fu.patch @@ -0,0 +1,62 @@ +From 73ebe810ed48cfe846ad739db1587e6ad81eb84e Mon Sep 17 00:00:00 2001 +From: Wangming Shao +Date: Tue, 8 Nov 2022 18:12:23 +0800 +Subject: [PATCH 7/7] Fix the header file location error and adjust the + function and structure version. + +driver inclusion +category: bugfix +bugzilla: https://gitee.com/openeuler/kernel/issues/I8DP81 + +------------------------------------------------------------------- + +Fixed the header file location error. +Rectify the missing member and function name errors in the structure. + +Signed-off-by: Wangming Shao +Reviewed-by: Yicong Yang +Reviewed-by: Yang Jihong +Signed-off-by: Zheng Zengkai +Signed-off-by: YunYi Yang + + Conflicts: + tools/perf/arch/arm/util/auxtrace.c + tools/perf/arch/arm64/util/hisi-ptt.c +--- + tools/perf/arch/arm/util/auxtrace.c | 5 +++-- + tools/perf/arch/arm/util/pmu.c | 2 +- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c +index aedd3432325b..552233cb0cef 100644 +--- a/tools/perf/arch/arm/util/auxtrace.c ++++ b/tools/perf/arch/arm/util/auxtrace.c +@@ -9,9 +9,10 @@ + #include + #include + +-#include "../../util/auxtrace.h" ++#include "../../../util/auxtrace.h" ++#include "../../../util/debug.h" + #include "../../util/evlist.h" +-#include "../../util/pmu.h" ++#include "../../../util/pmu.h" + #include "cs-etm.h" + #include "arm-spe.h" + #include "hisi-ptt.h" +diff --git a/tools/perf/arch/arm/util/pmu.c b/tools/perf/arch/arm/util/pmu.c +index 59a2d7ac152d..711e77e792a2 100644 +--- a/tools/perf/arch/arm/util/pmu.c ++++ b/tools/perf/arch/arm/util/pmu.c +@@ -11,7 +11,7 @@ + #include "cs-etm.h" + #include "arm-spe.h" + #include "hisi-ptt.h" +-#include "../../util/pmu.h" ++#include "../../../util/pmu.h" + + struct perf_event_attr + *perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused) +-- +2.27.0 + diff --git a/series.conf b/series.conf index 5f1ee1869220e59ca1ef4bc5b052f60a39457603..c02d844c9922fd9b5625c48c1fea5f9c65b390a6 100644 --- a/series.conf +++ b/series.conf @@ -110,3 +110,10 @@ patches/0106-spi-Add-HiSilicon-SPI-Controller-Driver-for-Kunpeng-.patch patches/0107-spi-hisi-kunpeng-Fix-Woverflow-warning-on-conversion.patch patches/0108-spi-hisi-kunpeng-Add-debugfs-support.patch patches/0109-spi-hisi-kunpeng-Fix-the-debugfs-directory-name-inco.patch +patches/0110-perf-pmu-Move-EVENT_SOURCE_DEVICE_PATH-to-PMU-header.patch +patches/0111-perf-tools-Fix-record-failure-when-mixed-with-ARM-SP.patch +patches/0112-perf-tools-No-need-to-cache-the-PMUs-in-ARM-SPE-auxt.patch +patches/0113-perf-auxtrace-arm-Refactor-event-list-iteration-in-a.patch +patches/0114-perf-auxtrace-arm64-Add-support-for-HiSilicon-PCIe-T.patch +patches/0115-perf-auxtrace-arm64-Add-support-for-parsing-HiSilico.patch +patches/0116-Fix-the-header-file-location-error-and-adjust-the-fu.patch