diff --git a/tools/tracing/rtla/src/common.c b/tools/tracing/rtla/src/common.c index 20fae1f19cac..2a5333270e03 100644 --- a/tools/tracing/rtla/src/common.c +++ b/tools/tracing/rtla/src/common.c @@ -62,11 +62,22 @@ static void unset_signals(struct common_params *params) int common_apply_config(struct osnoise_tool *tool, struct common_params *params) { - int retval, i; + int retval, i, tracer_cpus; if (!params->sleep_time) params->sleep_time = 1; + tracer_cpus = osnoise_get_cpu_count(); + if (tracer_cpus < 0) { + err_msg("Failed to get tracer cpu count from osnoise/cpus\n"); + goto out_err; + } + if (tracer_cpus != nr_cpus) { + err_msg("Kernel reports %d cpus but rtla sees %d\n", + tracer_cpus, nr_cpus); + goto out_err; + } + retval = osnoise_set_cpus(tool->context, params->cpus ? params->cpus : "all"); if (retval) { err_msg("Failed to apply CPUs config\n"); diff --git a/tools/tracing/rtla/src/common.h b/tools/tracing/rtla/src/common.h index 051d56182276..a7a9063c302b 100644 --- a/tools/tracing/rtla/src/common.h +++ b/tools/tracing/rtla/src/common.h @@ -168,6 +168,7 @@ should_continue_tracing(const struct common_params *params) int common_threshold_handler(const struct osnoise_tool *tool); +int osnoise_get_cpu_count(void); int osnoise_set_cpus(struct osnoise_context *context, char *cpus); void osnoise_restore_cpus(struct osnoise_context *context); diff --git a/tools/tracing/rtla/src/osnoise.c b/tools/tracing/rtla/src/osnoise.c index b9bcbf9ee430..5a746bc11f03 100644 --- a/tools/tracing/rtla/src/osnoise.c +++ b/tools/tracing/rtla/src/osnoise.c @@ -124,6 +124,50 @@ void osnoise_put_cpus(struct osnoise_context *context) context->orig_cpus = NULL; } +/* + * osnoise_get_cpu_count - get the number of CPUs as seen by the osnoise tracer + * + * Write "all" to osnoise/cpus and read back the real kernel-side list + * of all possible cpus. Restore the original value afterwards. + * + * Returns the number of CPUs, or -1 on error. + */ +int osnoise_get_cpu_count(void) +{ + char *orig, *readback; + int max_cpu; + + orig = tracefs_instance_file_read(NULL, "osnoise/cpus", NULL); + if (!orig) + return -1; + + if (tracefs_instance_file_write(NULL, "osnoise/cpus", "all\n") < 0) { + free(orig); + return -1; + } + + readback = tracefs_instance_file_read(NULL, "osnoise/cpus", NULL); + if (!readback) { + tracefs_instance_file_write(NULL, "osnoise/cpus", orig); + free(orig); + return -1; + } + + max_cpu = get_max_cpu_from_list(readback); + free(readback); + + if (tracefs_instance_file_write(NULL, "osnoise/cpus", orig) < 0) { + free(orig); + return -1; + } + free(orig); + + if (max_cpu < 0) + return -1; + + return max_cpu + 1; +} + /* * osnoise_read_ll_config - read a long long value from a config * diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c index d65de511be9e..5d91c9151aa4 100644 --- a/tools/tracing/rtla/src/utils.c +++ b/tools/tracing/rtla/src/utils.c @@ -161,6 +161,22 @@ static int max_cpu_callback(int i, void *data) return 0; } +/* + * get_max_cpu_from_list - get the maximum CPU in a CPU list + * + * Returns maximum CPU number, or -1 on error + */ +int get_max_cpu_from_list(const char *cpu_list) +{ + int max_cpu = -1; + + if (cpu_list_iterate(cpu_list, max_cpu_callback, &max_cpu) < 0) + return -1; + + return max_cpu; +} + + static int tmp_cpu_set_callback(int i, void *data) { bool *cpu_set = data; diff --git a/tools/tracing/rtla/src/utils.h b/tools/tracing/rtla/src/utils.h index 2579e7fa08be..44b450645ffb 100644 --- a/tools/tracing/rtla/src/utils.h +++ b/tools/tracing/rtla/src/utils.h @@ -50,6 +50,7 @@ long parse_seconds_duration(char *val); void get_duration(time_t start_time, char *output, int output_size); int cpu_list_iterate(const char *cpu_list, int (*callback)(int, void *), void *data); +int get_max_cpu_from_list(const char *cpu_list); int get_possible_cpus(void); long long get_llong_from_str(char *start);