From: Adrian Hunter <adrian.hunter@intel.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>,
Mark Rutland <mark.rutland@arm.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Heiko Carstens <hca@linux.ibm.com>,
Thomas Richter <tmricht@linux.ibm.com>,
Hendrik Brueckner <brueckner@linux.ibm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Mike Leach <mike.leach@linaro.org>,
James Clark <james.clark@arm.com>,
coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org,
Yicong Yang <yangyicong@hisilicon.com>,
Jonathan Cameron <jonathan.cameron@huawei.com>,
Will Deacon <will@kernel.org>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Jiri Olsa <jolsa@kernel.org>, Namhyung Kim <namhyung@kernel.org>,
Ian Rogers <irogers@google.com>,
linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org
Subject: [PATCH RFC V2 2/4] perf/x86/intel/pt: Add support for pause / resume
Date: Fri, 8 Dec 2023 19:24:47 +0200 [thread overview]
Message-ID: <20231208172449.35444-3-adrian.hunter@intel.com> (raw)
In-Reply-To: <20231208172449.35444-1-adrian.hunter@intel.com>
Prevent tracing to start if aux_paused.
Implement support for PERF_EF_PAUSE / PERF_EF_RESUME. When aux_paused, stop
tracing. When not aux_paused, only start tracing if it isn't currently
meant to be stopped.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
arch/x86/events/intel/pt.c | 63 ++++++++++++++++++++++++++++++++++++--
arch/x86/events/intel/pt.h | 4 +++
2 files changed, 64 insertions(+), 3 deletions(-)
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
index 42a55794004a..692b51849d1c 100644
--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -418,6 +418,9 @@ static void pt_config_start(struct perf_event *event)
struct pt *pt = this_cpu_ptr(&pt_ctx);
u64 ctl = event->hw.config;
+ if (READ_ONCE(event->aux_paused))
+ return;
+
ctl |= RTIT_CTL_TRACEEN;
if (READ_ONCE(pt->vmx_on))
perf_aux_output_flag(&pt->handle, PERF_AUX_FLAG_PARTIAL);
@@ -534,7 +537,20 @@ static void pt_config(struct perf_event *event)
reg |= (event->attr.config & PT_CONFIG_MASK);
event->hw.config = reg;
+
+ /*
+ * Allow resume before starting so as not to overwrite a value set by a
+ * PMI.
+ */
+ WRITE_ONCE(pt->resume_allowed, 1);
+
pt_config_start(event);
+
+ /*
+ * Allow pause after starting so its pt_config_stop() doesn't race with
+ * pt_config_start().
+ */
+ WRITE_ONCE(pt->pause_allowed, 1);
}
static void pt_config_stop(struct perf_event *event)
@@ -1507,6 +1523,7 @@ void intel_pt_interrupt(void)
buf = perf_aux_output_begin(&pt->handle, event);
if (!buf) {
event->hw.state = PERF_HES_STOPPED;
+ pt->resume_allowed = 0;
return;
}
@@ -1515,6 +1532,7 @@ void intel_pt_interrupt(void)
ret = pt_buffer_reset_markers(buf, &pt->handle);
if (ret) {
perf_aux_output_end(&pt->handle, 0);
+ pt->resume_allowed = 0;
return;
}
@@ -1569,6 +1587,26 @@ static void pt_event_start(struct perf_event *event, int mode)
struct pt *pt = this_cpu_ptr(&pt_ctx);
struct pt_buffer *buf;
+ if (mode & PERF_EF_RESUME) {
+ if (READ_ONCE(pt->resume_allowed)) {
+ u64 status;
+
+ /*
+ * Only if the trace is not active and the error and
+ * stopped bits are clear, is it safe to start, but a
+ * PMI might have just cleared these, so resume_allowed
+ * must be checked again also.
+ */
+ rdmsrl(MSR_IA32_RTIT_STATUS, status);
+ if (!(status & (RTIT_STATUS_TRIGGEREN |
+ RTIT_STATUS_ERROR |
+ RTIT_STATUS_STOPPED)) &&
+ READ_ONCE(pt->resume_allowed))
+ pt_config_start(event);
+ }
+ return;
+ }
+
buf = perf_aux_output_begin(&pt->handle, event);
if (!buf)
goto fail_stop;
@@ -1597,6 +1635,16 @@ static void pt_event_stop(struct perf_event *event, int mode)
{
struct pt *pt = this_cpu_ptr(&pt_ctx);
+ if (mode & PERF_EF_PAUSE) {
+ if (READ_ONCE(pt->pause_allowed))
+ pt_config_stop(event);
+ return;
+ }
+
+ /* Protect against racing */
+ WRITE_ONCE(pt->pause_allowed, 0);
+ WRITE_ONCE(pt->resume_allowed, 0);
+
/*
* Protect against the PMI racing with disabling wrmsr,
* see comment in intel_pt_interrupt().
@@ -1655,8 +1703,12 @@ static long pt_event_snapshot_aux(struct perf_event *event,
/*
* Here, handle_nmi tells us if the tracing is on
*/
- if (READ_ONCE(pt->handle_nmi))
+ if (READ_ONCE(pt->handle_nmi)) {
+ /* Protect against racing */
+ WRITE_ONCE(pt->pause_allowed, 0);
+ WRITE_ONCE(pt->resume_allowed, 0);
pt_config_stop(event);
+ }
pt_read_offset(buf);
pt_update_head(pt);
@@ -1673,8 +1725,11 @@ static long pt_event_snapshot_aux(struct perf_event *event,
* Compiler barrier not needed as we couldn't have been
* preempted by anything that touches pt->handle_nmi.
*/
- if (pt->handle_nmi)
+ if (pt->handle_nmi) {
+ WRITE_ONCE(pt->resume_allowed, 1);
pt_config_start(event);
+ WRITE_ONCE(pt->pause_allowed, 1);
+ }
return ret;
}
@@ -1790,7 +1845,9 @@ static __init int pt_init(void)
if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries))
pt_pmu.pmu.capabilities = PERF_PMU_CAP_AUX_NO_SG;
- pt_pmu.pmu.capabilities |= PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_ITRACE;
+ pt_pmu.pmu.capabilities |= PERF_PMU_CAP_EXCLUSIVE |
+ PERF_PMU_CAP_ITRACE |
+ PERF_PMU_CAP_AUX_PAUSE;
pt_pmu.pmu.attr_groups = pt_attr_groups;
pt_pmu.pmu.task_ctx_nr = perf_sw_context;
pt_pmu.pmu.event_init = pt_event_init;
diff --git a/arch/x86/events/intel/pt.h b/arch/x86/events/intel/pt.h
index 96906a62aacd..b9527205e028 100644
--- a/arch/x86/events/intel/pt.h
+++ b/arch/x86/events/intel/pt.h
@@ -117,6 +117,8 @@ struct pt_filters {
* @filters: last configured filters
* @handle_nmi: do handle PT PMI on this cpu, there's an active event
* @vmx_on: 1 if VMX is ON on this cpu
+ * @pause_allowed: PERF_EF_PAUSE is allowed to stop tracing
+ * @resume_allowed: PERF_EF_RESUME is allowed to start tracing
* @output_base: cached RTIT_OUTPUT_BASE MSR value
* @output_mask: cached RTIT_OUTPUT_MASK MSR value
*/
@@ -125,6 +127,8 @@ struct pt {
struct pt_filters filters;
int handle_nmi;
int vmx_on;
+ int pause_allowed;
+ int resume_allowed;
u64 output_base;
u64 output_mask;
};
--
2.34.1
WARNING: multiple messages have this Message-ID (diff)
From: Adrian Hunter <adrian.hunter@intel.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>,
Mark Rutland <mark.rutland@arm.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Heiko Carstens <hca@linux.ibm.com>,
Thomas Richter <tmricht@linux.ibm.com>,
Hendrik Brueckner <brueckner@linux.ibm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Mike Leach <mike.leach@linaro.org>,
James Clark <james.clark@arm.com>,
coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org,
Yicong Yang <yangyicong@hisilicon.com>,
Jonathan Cameron <jonathan.cameron@huawei.com>,
Will Deacon <will@kernel.org>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Jiri Olsa <jolsa@kernel.org>, Namhyung Kim <namhyung@kernel.org>,
Ian Rogers <irogers@google.com>,
linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org
Subject: [PATCH RFC V2 2/4] perf/x86/intel/pt: Add support for pause / resume
Date: Fri, 8 Dec 2023 19:24:47 +0200 [thread overview]
Message-ID: <20231208172449.35444-3-adrian.hunter@intel.com> (raw)
In-Reply-To: <20231208172449.35444-1-adrian.hunter@intel.com>
Prevent tracing to start if aux_paused.
Implement support for PERF_EF_PAUSE / PERF_EF_RESUME. When aux_paused, stop
tracing. When not aux_paused, only start tracing if it isn't currently
meant to be stopped.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
arch/x86/events/intel/pt.c | 63 ++++++++++++++++++++++++++++++++++++--
arch/x86/events/intel/pt.h | 4 +++
2 files changed, 64 insertions(+), 3 deletions(-)
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
index 42a55794004a..692b51849d1c 100644
--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -418,6 +418,9 @@ static void pt_config_start(struct perf_event *event)
struct pt *pt = this_cpu_ptr(&pt_ctx);
u64 ctl = event->hw.config;
+ if (READ_ONCE(event->aux_paused))
+ return;
+
ctl |= RTIT_CTL_TRACEEN;
if (READ_ONCE(pt->vmx_on))
perf_aux_output_flag(&pt->handle, PERF_AUX_FLAG_PARTIAL);
@@ -534,7 +537,20 @@ static void pt_config(struct perf_event *event)
reg |= (event->attr.config & PT_CONFIG_MASK);
event->hw.config = reg;
+
+ /*
+ * Allow resume before starting so as not to overwrite a value set by a
+ * PMI.
+ */
+ WRITE_ONCE(pt->resume_allowed, 1);
+
pt_config_start(event);
+
+ /*
+ * Allow pause after starting so its pt_config_stop() doesn't race with
+ * pt_config_start().
+ */
+ WRITE_ONCE(pt->pause_allowed, 1);
}
static void pt_config_stop(struct perf_event *event)
@@ -1507,6 +1523,7 @@ void intel_pt_interrupt(void)
buf = perf_aux_output_begin(&pt->handle, event);
if (!buf) {
event->hw.state = PERF_HES_STOPPED;
+ pt->resume_allowed = 0;
return;
}
@@ -1515,6 +1532,7 @@ void intel_pt_interrupt(void)
ret = pt_buffer_reset_markers(buf, &pt->handle);
if (ret) {
perf_aux_output_end(&pt->handle, 0);
+ pt->resume_allowed = 0;
return;
}
@@ -1569,6 +1587,26 @@ static void pt_event_start(struct perf_event *event, int mode)
struct pt *pt = this_cpu_ptr(&pt_ctx);
struct pt_buffer *buf;
+ if (mode & PERF_EF_RESUME) {
+ if (READ_ONCE(pt->resume_allowed)) {
+ u64 status;
+
+ /*
+ * Only if the trace is not active and the error and
+ * stopped bits are clear, is it safe to start, but a
+ * PMI might have just cleared these, so resume_allowed
+ * must be checked again also.
+ */
+ rdmsrl(MSR_IA32_RTIT_STATUS, status);
+ if (!(status & (RTIT_STATUS_TRIGGEREN |
+ RTIT_STATUS_ERROR |
+ RTIT_STATUS_STOPPED)) &&
+ READ_ONCE(pt->resume_allowed))
+ pt_config_start(event);
+ }
+ return;
+ }
+
buf = perf_aux_output_begin(&pt->handle, event);
if (!buf)
goto fail_stop;
@@ -1597,6 +1635,16 @@ static void pt_event_stop(struct perf_event *event, int mode)
{
struct pt *pt = this_cpu_ptr(&pt_ctx);
+ if (mode & PERF_EF_PAUSE) {
+ if (READ_ONCE(pt->pause_allowed))
+ pt_config_stop(event);
+ return;
+ }
+
+ /* Protect against racing */
+ WRITE_ONCE(pt->pause_allowed, 0);
+ WRITE_ONCE(pt->resume_allowed, 0);
+
/*
* Protect against the PMI racing with disabling wrmsr,
* see comment in intel_pt_interrupt().
@@ -1655,8 +1703,12 @@ static long pt_event_snapshot_aux(struct perf_event *event,
/*
* Here, handle_nmi tells us if the tracing is on
*/
- if (READ_ONCE(pt->handle_nmi))
+ if (READ_ONCE(pt->handle_nmi)) {
+ /* Protect against racing */
+ WRITE_ONCE(pt->pause_allowed, 0);
+ WRITE_ONCE(pt->resume_allowed, 0);
pt_config_stop(event);
+ }
pt_read_offset(buf);
pt_update_head(pt);
@@ -1673,8 +1725,11 @@ static long pt_event_snapshot_aux(struct perf_event *event,
* Compiler barrier not needed as we couldn't have been
* preempted by anything that touches pt->handle_nmi.
*/
- if (pt->handle_nmi)
+ if (pt->handle_nmi) {
+ WRITE_ONCE(pt->resume_allowed, 1);
pt_config_start(event);
+ WRITE_ONCE(pt->pause_allowed, 1);
+ }
return ret;
}
@@ -1790,7 +1845,9 @@ static __init int pt_init(void)
if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries))
pt_pmu.pmu.capabilities = PERF_PMU_CAP_AUX_NO_SG;
- pt_pmu.pmu.capabilities |= PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_ITRACE;
+ pt_pmu.pmu.capabilities |= PERF_PMU_CAP_EXCLUSIVE |
+ PERF_PMU_CAP_ITRACE |
+ PERF_PMU_CAP_AUX_PAUSE;
pt_pmu.pmu.attr_groups = pt_attr_groups;
pt_pmu.pmu.task_ctx_nr = perf_sw_context;
pt_pmu.pmu.event_init = pt_event_init;
diff --git a/arch/x86/events/intel/pt.h b/arch/x86/events/intel/pt.h
index 96906a62aacd..b9527205e028 100644
--- a/arch/x86/events/intel/pt.h
+++ b/arch/x86/events/intel/pt.h
@@ -117,6 +117,8 @@ struct pt_filters {
* @filters: last configured filters
* @handle_nmi: do handle PT PMI on this cpu, there's an active event
* @vmx_on: 1 if VMX is ON on this cpu
+ * @pause_allowed: PERF_EF_PAUSE is allowed to stop tracing
+ * @resume_allowed: PERF_EF_RESUME is allowed to start tracing
* @output_base: cached RTIT_OUTPUT_BASE MSR value
* @output_mask: cached RTIT_OUTPUT_MASK MSR value
*/
@@ -125,6 +127,8 @@ struct pt {
struct pt_filters filters;
int handle_nmi;
int vmx_on;
+ int pause_allowed;
+ int resume_allowed;
u64 output_base;
u64 output_mask;
};
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2023-12-08 17:25 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-08 17:24 [PATCH RFC V2 0/4] perf/core: Add ability for an event to "pause" or "resume" AUX area tracing Adrian Hunter
2023-12-08 17:24 ` Adrian Hunter
2023-12-08 17:24 ` [PATCH RFC V2 1/4] perf/core: Add aux_pause, aux_resume, aux_start_paused Adrian Hunter
2023-12-08 17:24 ` Adrian Hunter
2023-12-19 13:42 ` Arnaldo Carvalho de Melo
2023-12-19 13:42 ` Arnaldo Carvalho de Melo
2023-12-20 15:54 ` James Clark
2023-12-20 15:54 ` James Clark
2023-12-20 16:16 ` Adrian Hunter
2023-12-20 16:16 ` Adrian Hunter
2023-12-21 10:05 ` James Clark
2023-12-21 10:05 ` James Clark
2023-12-20 17:41 ` Suzuki K Poulose
2023-12-20 17:41 ` Suzuki K Poulose
2024-01-05 12:57 ` Adrian Hunter
2024-01-05 12:57 ` Adrian Hunter
2023-12-08 17:24 ` Adrian Hunter [this message]
2023-12-08 17:24 ` [PATCH RFC V2 2/4] perf/x86/intel/pt: Add support for pause / resume Adrian Hunter
2023-12-08 17:24 ` [PATCH RFC V2 3/4] perf tools: Add support for AUX area " Adrian Hunter
2023-12-08 17:24 ` Adrian Hunter
2023-12-08 17:24 ` [PATCH RFC V2 4/4] coresight: Have a stab at support for " Adrian Hunter
2023-12-08 17:24 ` Adrian Hunter
2023-12-09 17:52 ` kernel test robot
2023-12-15 6:42 ` [PATCH RFC V3 " Adrian Hunter
2023-12-15 6:42 ` Adrian Hunter
2023-12-20 15:59 ` James Clark
2023-12-20 15:59 ` James Clark
2024-01-05 12:56 ` Adrian Hunter
2024-01-05 12:56 ` Adrian Hunter
2023-12-19 6:05 ` [PATCH RFC V2 0/4] perf/core: Add ability for an event to "pause" or "resume" AUX area tracing Adrian Hunter
2023-12-19 6:05 ` Adrian Hunter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231208172449.35444-3-adrian.hunter@intel.com \
--to=adrian.hunter@intel.com \
--cc=acme@kernel.org \
--cc=alexander.shishkin@linux.intel.com \
--cc=brueckner@linux.ibm.com \
--cc=coresight@lists.linaro.org \
--cc=hca@linux.ibm.com \
--cc=irogers@google.com \
--cc=james.clark@arm.com \
--cc=jolsa@kernel.org \
--cc=jonathan.cameron@huawei.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mike.leach@linaro.org \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=suzuki.poulose@arm.com \
--cc=tmricht@linux.ibm.com \
--cc=will@kernel.org \
--cc=yangyicong@hisilicon.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.