mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
perf/x86/intel/pt: Add sampling support
Add AUX sampling support to the PT PMU: implement an NMI-safe callback that takes a snapshot of the buffer without touching the event states. This is done for PT events that don't use PMIs, that is, snapshot mode (RO mapping of the AUX area). Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Stephane Eranian <eranian@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vince Weaver <vincent.weaver@maine.edu> Cc: adrian.hunter@intel.com Cc: mathieu.poirier@linaro.org Link: https://lkml.kernel.org/r/20191025140835.53665-4-alexander.shishkin@linux.intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
8e105a1fc2
commit
25e8920b30
@ -1208,6 +1208,13 @@ pt_buffer_setup_aux(struct perf_event *event, void **pages,
|
||||
if (!nr_pages)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Only support AUX sampling in snapshot mode, where we don't
|
||||
* generate NMIs.
|
||||
*/
|
||||
if (event->attr.aux_sample_size && !snapshot)
|
||||
return NULL;
|
||||
|
||||
if (cpu == -1)
|
||||
cpu = raw_smp_processor_id();
|
||||
node = cpu_to_node(cpu);
|
||||
@ -1506,6 +1513,52 @@ static void pt_event_stop(struct perf_event *event, int mode)
|
||||
}
|
||||
}
|
||||
|
||||
static long pt_event_snapshot_aux(struct perf_event *event,
|
||||
struct perf_output_handle *handle,
|
||||
unsigned long size)
|
||||
{
|
||||
struct pt *pt = this_cpu_ptr(&pt_ctx);
|
||||
struct pt_buffer *buf = perf_get_aux(&pt->handle);
|
||||
unsigned long from = 0, to;
|
||||
long ret;
|
||||
|
||||
if (WARN_ON_ONCE(!buf))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Sampling is only allowed on snapshot events;
|
||||
* see pt_buffer_setup_aux().
|
||||
*/
|
||||
if (WARN_ON_ONCE(!buf->snapshot))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Here, handle_nmi tells us if the tracing is on
|
||||
*/
|
||||
if (READ_ONCE(pt->handle_nmi))
|
||||
pt_config_stop(event);
|
||||
|
||||
pt_read_offset(buf);
|
||||
pt_update_head(pt);
|
||||
|
||||
to = local_read(&buf->data_size);
|
||||
if (to < size)
|
||||
from = buf->nr_pages << PAGE_SHIFT;
|
||||
from += to - size;
|
||||
|
||||
ret = perf_output_copy_aux(&pt->handle, handle, from, to);
|
||||
|
||||
/*
|
||||
* If the tracing was on when we turned up, restart it.
|
||||
* Compiler barrier not needed as we couldn't have been
|
||||
* preempted by anything that touches pt->handle_nmi.
|
||||
*/
|
||||
if (pt->handle_nmi)
|
||||
pt_config_start(event);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pt_event_del(struct perf_event *event, int mode)
|
||||
{
|
||||
pt_event_stop(event, PERF_EF_UPDATE);
|
||||
@ -1625,6 +1678,7 @@ static __init int pt_init(void)
|
||||
pt_pmu.pmu.del = pt_event_del;
|
||||
pt_pmu.pmu.start = pt_event_start;
|
||||
pt_pmu.pmu.stop = pt_event_stop;
|
||||
pt_pmu.pmu.snapshot_aux = pt_event_snapshot_aux;
|
||||
pt_pmu.pmu.read = pt_event_read;
|
||||
pt_pmu.pmu.setup_aux = pt_buffer_setup_aux;
|
||||
pt_pmu.pmu.free_aux = pt_buffer_free_aux;
|
||||
|
Loading…
Reference in New Issue
Block a user