From: He Chuyue hechuyue@wxiat.com
Sunway inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I56X48
--------------------------------
Although sw64 have no per-counter usr/os/guest/host bits, we can distinguish user and kernel by sample mode.
Signed-off-by: He Chuyue hechuyue@wxiat.com
Signed-off-by: Gu Zitao guzitao@wxiat.com --- arch/sw_64/include/asm/wrperfmon.h | 4 ++++ arch/sw_64/kernel/perf_event.c | 20 +++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/arch/sw_64/include/asm/wrperfmon.h b/arch/sw_64/include/asm/wrperfmon.h index eaa6735b5a25..098702573bfc 100644 --- a/arch/sw_64/include/asm/wrperfmon.h +++ b/arch/sw_64/include/asm/wrperfmon.h @@ -38,6 +38,10 @@ #define PC1_MIN 0x0 #define PC1_MAX 0x37
+#define SW64_PERFCTRL_KM 2 +#define SW64_PERFCTRL_UM 3 +#define SW64_PERFCTRL_AM 4 + /* pc0 events */ #define PC0_INSTRUCTIONS 0x0 #define PC0_BRANCH_INSTRUCTIONS 0x3 diff --git a/arch/sw_64/kernel/perf_event.c b/arch/sw_64/kernel/perf_event.c index d2975e17f666..0d49224ba058 100644 --- a/arch/sw_64/kernel/perf_event.c +++ b/arch/sw_64/kernel/perf_event.c @@ -457,8 +457,8 @@ static void sw64_pmu_start(struct perf_event *event, int flags)
hwc->state = 0;
- /* counting in all modes, for both counters */ - wrperfmon(PERFMON_CMD_PM, 4); + /* counting in selected modes, for both counters */ + wrperfmon(PERFMON_CMD_PM, hwc->config_base); if (hwc->idx == PERFMON_PC0) { wrperfmon(PERFMON_CMD_EVENT_PC0, hwc->event_base); wrperfmon(PERFMON_CMD_ENABLE, PERFMON_ENABLE_ARGS_PC0); @@ -519,9 +519,12 @@ static int __hw_perf_event_init(struct perf_event *event) const struct sw64_perf_event *event_type;
- /* SW64 do not have per-counter usr/os/guest/host bits */ - if (event->attr.exclude_user || event->attr.exclude_kernel || - event->attr.exclude_hv || event->attr.exclude_idle || + /* + * SW64 does not have per-counter usr/os/guest/host bits, + * we can distinguish exclude_user and exclude_kernel by + * sample mode. + */ + if (event->attr.exclude_hv || event->attr.exclude_idle || event->attr.exclude_host || event->attr.exclude_guest) return -EINVAL;
@@ -553,6 +556,13 @@ static int __hw_perf_event_init(struct perf_event *event) hwc->event_base = attr->config & 0xff; /* event selector */ }
+ hwc->config_base = SW64_PERFCTRL_AM; + + if (attr->exclude_user) + hwc->config_base = SW64_PERFCTRL_KM; + if (attr->exclude_kernel) + hwc->config_base = SW64_PERFCTRL_UM; + hwc->config = attr->config;
if (!is_sampling_event(event))