perf sched: Fix record failure when CONFIG_SCHEDSTATS is not set
The tracepoints trace_sched_stat_{wait, sleep, iowait} are not exposed to user
if CONFIG_SCHEDSTATS is not set, "perf sched record" records the three events.
As a result, the command fails.
Before:
#perf sched record sleep 1
event syntax error: 'sched:sched_stat_wait'
\___ unknown tracepoint
Error: File /sys/kernel/tracing/events/sched/sched_stat_wait not found.
Hint: Perhaps this kernel misses some CONFIG_ setting to enable this feature?.
Run 'perf list' for a list of valid events
Usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]
-e, --event <event> event selector. use 'perf list' to list available events
Solution:
Check whether schedstat tracepoints are exposed. If no, these events are not recorded.
After:
# perf sched record sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.163 MB perf.data (1091 samples) ]
# perf sched report
run measurement overhead: 4736 nsecs
sleep measurement overhead: 9059979 nsecs
the run test took 999854 nsecs
the sleep test took 8945271 nsecs
nr_run_events: 716
nr_sleep_events: 785
nr_wakeup_events: 0
...
------------------------------------------------------------
Fixes: 2a09b5de23
("sched/fair: do not expose some tracepoints to user if CONFIG_SCHEDSTATS is not set")
Signed-off-by: Yang Jihong <yangjihong1@huawei.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt (VMware) <rostedt@goodmis.org>
Cc: Yafang Shao <laoar.shao@gmail.com>
Link: http://lore.kernel.org/lkml/20210713112358.194693-1-yangjihong1@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
22a665513b
commit
b0f008551f
|
@ -3335,6 +3335,16 @@ static void setup_sorting(struct perf_sched *sched, const struct option *options
|
|||
sort_dimension__add("pid", &sched->cmp_pid);
|
||||
}
|
||||
|
||||
static bool schedstat_events_exposed(void)
|
||||
{
|
||||
/*
|
||||
* Select "sched:sched_stat_wait" event to check
|
||||
* whether schedstat tracepoints are exposed.
|
||||
*/
|
||||
return IS_ERR(trace_event__tp_format("sched", "sched_stat_wait")) ?
|
||||
false : true;
|
||||
}
|
||||
|
||||
static int __cmd_record(int argc, const char **argv)
|
||||
{
|
||||
unsigned int rec_argc, i, j;
|
||||
|
@ -3346,21 +3356,33 @@ static int __cmd_record(int argc, const char **argv)
|
|||
"-m", "1024",
|
||||
"-c", "1",
|
||||
"-e", "sched:sched_switch",
|
||||
"-e", "sched:sched_stat_wait",
|
||||
"-e", "sched:sched_stat_sleep",
|
||||
"-e", "sched:sched_stat_iowait",
|
||||
"-e", "sched:sched_stat_runtime",
|
||||
"-e", "sched:sched_process_fork",
|
||||
"-e", "sched:sched_wakeup_new",
|
||||
"-e", "sched:sched_migrate_task",
|
||||
};
|
||||
|
||||
/*
|
||||
* The tracepoints trace_sched_stat_{wait, sleep, iowait}
|
||||
* are not exposed to user if CONFIG_SCHEDSTATS is not set,
|
||||
* to prevent "perf sched record" execution failure, determine
|
||||
* whether to record schedstat events according to actual situation.
|
||||
*/
|
||||
const char * const schedstat_args[] = {
|
||||
"-e", "sched:sched_stat_wait",
|
||||
"-e", "sched:sched_stat_sleep",
|
||||
"-e", "sched:sched_stat_iowait",
|
||||
};
|
||||
unsigned int schedstat_argc = schedstat_events_exposed() ?
|
||||
ARRAY_SIZE(schedstat_args) : 0;
|
||||
|
||||
struct tep_event *waking_event;
|
||||
|
||||
/*
|
||||
* +2 for either "-e", "sched:sched_wakeup" or
|
||||
* "-e", "sched:sched_waking"
|
||||
*/
|
||||
rec_argc = ARRAY_SIZE(record_args) + 2 + argc - 1;
|
||||
rec_argc = ARRAY_SIZE(record_args) + 2 + schedstat_argc + argc - 1;
|
||||
rec_argv = calloc(rec_argc + 1, sizeof(char *));
|
||||
|
||||
if (rec_argv == NULL)
|
||||
|
@ -3376,6 +3398,9 @@ static int __cmd_record(int argc, const char **argv)
|
|||
else
|
||||
rec_argv[i++] = strdup("sched:sched_wakeup");
|
||||
|
||||
for (j = 0; j < schedstat_argc; j++)
|
||||
rec_argv[i++] = strdup(schedstat_args[j]);
|
||||
|
||||
for (j = 1; j < (unsigned int)argc; j++, i++)
|
||||
rec_argv[i] = argv[j];
|
||||
|
||||
|
|
Loading…
Reference in New Issue