Skip to content

Commit 25e8920

Browse files
virtuosoIngo Molnar
authored andcommitted
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 <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Cc: David Ahern <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Stephane Eranian <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Vince Weaver <[email protected]> Cc: [email protected] Cc: [email protected] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 8e105a1 commit 25e8920

File tree

1 file changed

+54
-0
lines changed
  • arch/x86/events/intel

1 file changed

+54
-0
lines changed

arch/x86/events/intel/pt.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,13 @@ pt_buffer_setup_aux(struct perf_event *event, void **pages,
12081208
if (!nr_pages)
12091209
return NULL;
12101210

1211+
/*
1212+
* Only support AUX sampling in snapshot mode, where we don't
1213+
* generate NMIs.
1214+
*/
1215+
if (event->attr.aux_sample_size && !snapshot)
1216+
return NULL;
1217+
12111218
if (cpu == -1)
12121219
cpu = raw_smp_processor_id();
12131220
node = cpu_to_node(cpu);
@@ -1506,6 +1513,52 @@ static void pt_event_stop(struct perf_event *event, int mode)
15061513
}
15071514
}
15081515

1516+
static long pt_event_snapshot_aux(struct perf_event *event,
1517+
struct perf_output_handle *handle,
1518+
unsigned long size)
1519+
{
1520+
struct pt *pt = this_cpu_ptr(&pt_ctx);
1521+
struct pt_buffer *buf = perf_get_aux(&pt->handle);
1522+
unsigned long from = 0, to;
1523+
long ret;
1524+
1525+
if (WARN_ON_ONCE(!buf))
1526+
return 0;
1527+
1528+
/*
1529+
* Sampling is only allowed on snapshot events;
1530+
* see pt_buffer_setup_aux().
1531+
*/
1532+
if (WARN_ON_ONCE(!buf->snapshot))
1533+
return 0;
1534+
1535+
/*
1536+
* Here, handle_nmi tells us if the tracing is on
1537+
*/
1538+
if (READ_ONCE(pt->handle_nmi))
1539+
pt_config_stop(event);
1540+
1541+
pt_read_offset(buf);
1542+
pt_update_head(pt);
1543+
1544+
to = local_read(&buf->data_size);
1545+
if (to < size)
1546+
from = buf->nr_pages << PAGE_SHIFT;
1547+
from += to - size;
1548+
1549+
ret = perf_output_copy_aux(&pt->handle, handle, from, to);
1550+
1551+
/*
1552+
* If the tracing was on when we turned up, restart it.
1553+
* Compiler barrier not needed as we couldn't have been
1554+
* preempted by anything that touches pt->handle_nmi.
1555+
*/
1556+
if (pt->handle_nmi)
1557+
pt_config_start(event);
1558+
1559+
return ret;
1560+
}
1561+
15091562
static void pt_event_del(struct perf_event *event, int mode)
15101563
{
15111564
pt_event_stop(event, PERF_EF_UPDATE);
@@ -1625,6 +1678,7 @@ static __init int pt_init(void)
16251678
pt_pmu.pmu.del = pt_event_del;
16261679
pt_pmu.pmu.start = pt_event_start;
16271680
pt_pmu.pmu.stop = pt_event_stop;
1681+
pt_pmu.pmu.snapshot_aux = pt_event_snapshot_aux;
16281682
pt_pmu.pmu.read = pt_event_read;
16291683
pt_pmu.pmu.setup_aux = pt_buffer_setup_aux;
16301684
pt_pmu.pmu.free_aux = pt_buffer_free_aux;

0 commit comments

Comments
 (0)