Skip to content

Commit 1d078cc

Browse files
Alexey Budankovacmel
authored andcommitted
perf record: Introduce --control fd:ctl-fd[,ack-fd] options
Introduce --control fd:ctl-fd[,ack-fd] options to pass open file descriptors numbers from command line. Extend perf-record.txt file with --control fd:ctl-fd[,ack-fd] options description. Document possible usage model introduced by --control fd:ctl-fd[,ack-fd] options by providing example bash shell script. Signed-off-by: Alexey Budankov <[email protected]> Acked-by: Jiri Olsa <[email protected]> Acked-by: Namhyung Kim <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: http://lore.kernel.org/lkml/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent acce022 commit 1d078cc

File tree

3 files changed

+78
-0
lines changed

3 files changed

+78
-0
lines changed

tools/perf/Documentation/perf-record.txt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,45 @@ option. The -e option and this one can be mixed and matched. Events
627627
can be grouped using the {} notation.
628628
endif::HAVE_LIBPFM[]
629629

630+
--control fd:ctl-fd[,ack-fd]
631+
Listen on ctl-fd descriptor for command to control measurement ('enable': enable events,
632+
'disable': disable events). Measurements can be started with events disabled using
633+
--delay=-1 option. Optionally send control command completion ('ack\n') to ack-fd descriptor
634+
to synchronize with the controlling process. Example of bash shell script to enable and
635+
disable events during measurements:
636+
637+
#!/bin/bash
638+
639+
ctl_dir=/tmp/
640+
641+
ctl_fifo=${ctl_dir}perf_ctl.fifo
642+
test -p ${ctl_fifo} && unlink ${ctl_fifo}
643+
mkfifo ${ctl_fifo}
644+
exec {ctl_fd}<>${ctl_fifo}
645+
646+
ctl_ack_fifo=${ctl_dir}perf_ctl_ack.fifo
647+
test -p ${ctl_ack_fifo} && unlink ${ctl_ack_fifo}
648+
mkfifo ${ctl_ack_fifo}
649+
exec {ctl_fd_ack}<>${ctl_ack_fifo}
650+
651+
perf record -D -1 -e cpu-cycles -a \
652+
--control fd:${ctl_fd},${ctl_fd_ack} \
653+
-- sleep 30 &
654+
perf_pid=$!
655+
656+
sleep 5 && echo 'enable' >&${ctl_fd} && read -u ${ctl_fd_ack} e1 && echo "enabled(${e1})"
657+
sleep 10 && echo 'disable' >&${ctl_fd} && read -u ${ctl_fd_ack} d1 && echo "disabled(${d1})"
658+
659+
exec {ctl_fd_ack}>&-
660+
unlink ${ctl_ack_fifo}
661+
662+
exec {ctl_fd}>&-
663+
unlink ${ctl_fifo}
664+
665+
wait -n ${perf_pid}
666+
exit $?
667+
668+
630669
SEE ALSO
631670
--------
632671
linkperf:perf-stat[1], linkperf:perf-list[1], linkperf:perf-intel-pt[1]

tools/perf/builtin-record.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1786,6 +1786,9 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
17861786
perf_evlist__start_workload(rec->evlist);
17871787
}
17881788

1789+
if (evlist__initialize_ctlfd(rec->evlist, opts->ctl_fd, opts->ctl_fd_ack))
1790+
goto out_child;
1791+
17891792
if (opts->initial_delay) {
17901793
pr_info(EVLIST_DISABLED_MSG);
17911794
if (opts->initial_delay > 0) {
@@ -1932,6 +1935,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
19321935
record__synthesize_workload(rec, true);
19331936

19341937
out_child:
1938+
evlist__finalize_ctlfd(rec->evlist);
19351939
record__mmap_read_all(rec, true);
19361940
record__aio_mmap_read_sync(rec);
19371941

@@ -2281,6 +2285,33 @@ static int record__parse_mmap_pages(const struct option *opt,
22812285
return ret;
22822286
}
22832287

2288+
static int parse_control_option(const struct option *opt,
2289+
const char *str,
2290+
int unset __maybe_unused)
2291+
{
2292+
char *comma = NULL, *endptr = NULL;
2293+
struct record_opts *config = (struct record_opts *)opt->value;
2294+
2295+
if (strncmp(str, "fd:", 3))
2296+
return -EINVAL;
2297+
2298+
config->ctl_fd = strtoul(&str[3], &endptr, 0);
2299+
if (endptr == &str[3])
2300+
return -EINVAL;
2301+
2302+
comma = strchr(str, ',');
2303+
if (comma) {
2304+
if (endptr != comma)
2305+
return -EINVAL;
2306+
2307+
config->ctl_fd_ack = strtoul(comma + 1, &endptr, 0);
2308+
if (endptr == comma + 1 || *endptr != '\0')
2309+
return -EINVAL;
2310+
}
2311+
2312+
return 0;
2313+
}
2314+
22842315
static void switch_output_size_warn(struct record *rec)
22852316
{
22862317
u64 wakeup_size = evlist__mmap_size(rec->opts.mmap_pages);
@@ -2417,6 +2448,8 @@ static struct record record = {
24172448
},
24182449
.mmap_flush = MMAP_FLUSH_DEFAULT,
24192450
.nr_threads_synthesize = 1,
2451+
.ctl_fd = -1,
2452+
.ctl_fd_ack = -1,
24202453
},
24212454
.tool = {
24222455
.sample = process_sample_event,
@@ -2618,6 +2651,10 @@ static struct option __record_options[] = {
26182651
"libpfm4 event selector. use 'perf list' to list available events",
26192652
parse_libpfm_events_option),
26202653
#endif
2654+
OPT_CALLBACK(0, "control", &record.opts, "fd:ctl-fd[,ack-fd]",
2655+
"Listen on ctl-fd descriptor for command to control measurement ('enable': enable events, 'disable': disable events).\n"
2656+
"\t\t\t Optionally send control command completion ('ack\\n') to ack-fd descriptor.",
2657+
parse_control_option),
26212658
OPT_END()
26222659
};
26232660

tools/perf/util/record.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ struct record_opts {
7171
int mmap_flush;
7272
unsigned int comp_level;
7373
unsigned int nr_threads_synthesize;
74+
int ctl_fd;
75+
int ctl_fd_ack;
7476
};
7577

7678
extern const char * const *record_usage;

0 commit comments

Comments
 (0)