@@ -88,7 +88,9 @@ struct record {
8888 struct evlist * evlist ;
8989 struct perf_session * session ;
9090 struct evlist * sb_evlist ;
91+ pthread_t thread_id ;
9192 int realtime_prio ;
93+ bool switch_output_event_set ;
9294 bool no_buildid ;
9395 bool no_buildid_set ;
9496 bool no_buildid_cache ;
@@ -1437,6 +1439,13 @@ static int record__synthesize(struct record *rec, bool tail)
14371439 return err ;
14381440}
14391441
1442+ static int record__process_signal_event (union perf_event * event __maybe_unused , void * data )
1443+ {
1444+ struct record * rec = data ;
1445+ pthread_kill (rec -> thread_id , SIGUSR2 );
1446+ return 0 ;
1447+ }
1448+
14401449static int __cmd_record (struct record * rec , int argc , const char * * argv )
14411450{
14421451 int err ;
@@ -1581,12 +1590,24 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
15811590 goto out_child ;
15821591 }
15831592
1584- if (!opts -> no_bpf_event ) {
1585- rec -> sb_evlist = evlist__new ();
1593+ if (rec -> sb_evlist != NULL ) {
1594+ /*
1595+ * We get here if --switch-output-event populated the
1596+ * sb_evlist, so associate a callback that will send a SIGUSR2
1597+ * to the main thread.
1598+ */
1599+ evlist__set_cb (rec -> sb_evlist , record__process_signal_event , rec );
1600+ rec -> thread_id = pthread_self ();
1601+ }
15861602
1603+ if (!opts -> no_bpf_event ) {
15871604 if (rec -> sb_evlist == NULL ) {
1588- pr_err ("Couldn't create side band evlist.\n." );
1589- goto out_child ;
1605+ rec -> sb_evlist = evlist__new ();
1606+
1607+ if (rec -> sb_evlist == NULL ) {
1608+ pr_err ("Couldn't create side band evlist.\n." );
1609+ goto out_child ;
1610+ }
15901611 }
15911612
15921613 if (evlist__add_bpf_sb_event (rec -> sb_evlist , & session -> header .env )) {
@@ -2180,10 +2201,19 @@ static int switch_output_setup(struct record *rec)
21802201 };
21812202 unsigned long val ;
21822203
2204+ /*
2205+ * If we're using --switch-output-events, then we imply its
2206+ * --switch-output=signal, as we'll send a SIGUSR2 from the side band
2207+ * thread to its parent.
2208+ */
2209+ if (rec -> switch_output_event_set )
2210+ goto do_signal ;
2211+
21832212 if (!s -> set )
21842213 return 0 ;
21852214
21862215 if (!strcmp (s -> str , "signal" )) {
2216+ do_signal :
21872217 s -> signal = true;
21882218 pr_debug ("switch-output with SIGUSR2 signal\n" );
21892219 goto enabled ;
@@ -2441,6 +2471,9 @@ static struct option __record_options[] = {
24412471 & record .switch_output .set , "signal or size[BKMG] or time[smhd]" ,
24422472 "Switch output when receiving SIGUSR2 (signal) or cross a size or time threshold" ,
24432473 "signal" ),
2474+ OPT_CALLBACK_SET (0 , "switch-output-event" , & record .sb_evlist , & record .switch_output_event_set , "switch output event" ,
2475+ "switch output event selector. use 'perf list' to list available events" ,
2476+ parse_events_option_new_evlist ),
24442477 OPT_INTEGER (0 , "switch-max-files" , & record .switch_output .num_files ,
24452478 "Limit number of switch output generated files" ),
24462479 OPT_BOOLEAN (0 , "dry-run" , & dry_run ,
0 commit comments