@@ -1208,6 +1208,13 @@ pt_buffer_setup_aux(struct perf_event *event, void **pages,
1208
1208
if (!nr_pages )
1209
1209
return NULL ;
1210
1210
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
+
1211
1218
if (cpu == -1 )
1212
1219
cpu = raw_smp_processor_id ();
1213
1220
node = cpu_to_node (cpu );
@@ -1506,6 +1513,52 @@ static void pt_event_stop(struct perf_event *event, int mode)
1506
1513
}
1507
1514
}
1508
1515
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
+
1509
1562
static void pt_event_del (struct perf_event * event , int mode )
1510
1563
{
1511
1564
pt_event_stop (event , PERF_EF_UPDATE );
@@ -1625,6 +1678,7 @@ static __init int pt_init(void)
1625
1678
pt_pmu .pmu .del = pt_event_del ;
1626
1679
pt_pmu .pmu .start = pt_event_start ;
1627
1680
pt_pmu .pmu .stop = pt_event_stop ;
1681
+ pt_pmu .pmu .snapshot_aux = pt_event_snapshot_aux ;
1628
1682
pt_pmu .pmu .read = pt_event_read ;
1629
1683
pt_pmu .pmu .setup_aux = pt_buffer_setup_aux ;
1630
1684
pt_pmu .pmu .free_aux = pt_buffer_free_aux ;
0 commit comments