mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 18:41:58 +09:00
perf/x86/intel/pt: Fix sampling synchronization
commit d92792a4b26e50b96ab734cbe203d8a4c932a7a9 upstream.
pt_event_snapshot_aux() uses pt->handle_nmi to determine if tracing
needs to be stopped, however tracing can still be going because
pt->handle_nmi is set to zero before tracing is stopped in pt_event_stop,
whereas pt_event_snapshot_aux() requires that tracing must be stopped in
order to copy a sample of trace from the buffer.
Instead call pt_config_stop() always, which anyway checks config for
RTIT_CTL_TRACEEN and does nothing if it is already clear.
Note pt_event_snapshot_aux() can continue to use pt->handle_nmi to
determine if the trace needs to be restarted afterwards.
Fixes: 25e8920b30 ("perf/x86/intel/pt: Add sampling support")
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: stable@vger.kernel.org
Link: https://lkml.kernel.org/r/20240715160712.127117-2-adrian.hunter@intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
5b22c038fb
commit
89debcc2aa
@@ -1602,6 +1602,7 @@ static void pt_event_stop(struct perf_event *event, int mode)
|
|||||||
* see comment in intel_pt_interrupt().
|
* see comment in intel_pt_interrupt().
|
||||||
*/
|
*/
|
||||||
WRITE_ONCE(pt->handle_nmi, 0);
|
WRITE_ONCE(pt->handle_nmi, 0);
|
||||||
|
barrier();
|
||||||
|
|
||||||
pt_config_stop(event);
|
pt_config_stop(event);
|
||||||
|
|
||||||
@@ -1653,11 +1654,10 @@ static long pt_event_snapshot_aux(struct perf_event *event,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Here, handle_nmi tells us if the tracing is on
|
* There is no PT interrupt in this mode, so stop the trace and it will
|
||||||
|
* remain stopped while the buffer is copied.
|
||||||
*/
|
*/
|
||||||
if (READ_ONCE(pt->handle_nmi))
|
pt_config_stop(event);
|
||||||
pt_config_stop(event);
|
|
||||||
|
|
||||||
pt_read_offset(buf);
|
pt_read_offset(buf);
|
||||||
pt_update_head(pt);
|
pt_update_head(pt);
|
||||||
|
|
||||||
@@ -1669,11 +1669,10 @@ static long pt_event_snapshot_aux(struct perf_event *event,
|
|||||||
ret = perf_output_copy_aux(&pt->handle, handle, from, to);
|
ret = perf_output_copy_aux(&pt->handle, handle, from, to);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the tracing was on when we turned up, restart it.
|
* Here, handle_nmi tells us if the tracing was on.
|
||||||
* Compiler barrier not needed as we couldn't have been
|
* If the tracing was on, restart it.
|
||||||
* preempted by anything that touches pt->handle_nmi.
|
|
||||||
*/
|
*/
|
||||||
if (pt->handle_nmi)
|
if (READ_ONCE(pt->handle_nmi))
|
||||||
pt_config_start(event);
|
pt_config_start(event);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
Reference in New Issue
Block a user