| From 93e0db86dd4062835dbbb6da142ce0a25c941016 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 13 Jul 2021 19:23:58 +0800 |
| Subject: perf sched: Fix record failure when CONFIG_SCHEDSTATS is not set |
| |
| From: Yang Jihong <yangjihong1@huawei.com> |
| |
| [ Upstream commit b0f008551f0bf4d5f6db9b5f0e071b02790d6a2e ] |
| |
| 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: 2a09b5de235a6 ("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> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| tools/perf/builtin-sched.c | 33 +++++++++++++++++++++++++++++---- |
| 1 file changed, 29 insertions(+), 4 deletions(-) |
| |
| diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c |
| index 954ce2f594e9..3e5b7faf0c16 100644 |
| --- a/tools/perf/builtin-sched.c |
| +++ b/tools/perf/builtin-sched.c |
| @@ -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]; |
| |
| -- |
| 2.30.2 |
| |