rtla: Simplify osnoise tracer option setting code

Each osnoise tracer option (in /sys/kernel/tracing/osnoise) used by RTLA
requires four functions to be defined:

- static osnoise_get_<opt>() - to get the current value of the option
  and save it into struct osnoise_context's orig_<opt> field,
- osnoise_set_<opt>() - to set the value of the option requested by the
  user after reading and saving the original with osnoise_get_<opt>(),
  and save it into <opt> field of struct osnoise_context,
- osnoise_restore_<opt>() - restore the value recorded in orig_<opt>,
- static osnoise_put_<opt>() - restore the value recorded in orig_<opt>
  and update <opt> to reflect that.

The logic is duplicated for all the options, except for cpus (which is
the only string option) and period/runtime (which are handled together
and feature extra checks).

Deduplicate by moving the common code in get/set/restore/put into common
helper functions local to osnoise.c. The original set/restore/put
functions are reduced to wrappers generated using a set of X macros:

- OSNOISE_LL_OPTIONS, which invokes the OSNOISE_LL_OPTION macro for all
  "long long" options,
- OSNOISE_FLAG_OPTIONS, which invokes the OSNOISE_FLAG_OPTION macro for
  all flag options (boolean values in osnoise/options file).

Those are also used to auto-generate the corresponding fields in struct
osnoise_context, plus initialization and restoration code for them.

There are a few minor changes in the refactored code:

- osnoise_set_<opt>() now distinguishes between -2 (option cannot be
  set) and -1 (option not present in kernel) for all options.
- OSNOISE_OPTION_INIT_VAL and OSNOISE_TIME_INIT_VAL are removed and
  replaced with a plain -1; all unsigned long long fields are changed to
  signed long long, consistent with pre-existing "%lld" format string in
  osnoise_write_ll_config().
- osnoise_restore_<opt>() now correctly resets the <opt> field (not
  orig_<opt>) for all options.

The change is intended to simplify adding and modifying tracer options.
It also makes the code shorter by a bit over 500 lines.

Assisted-by: Claude:claude-opus-4-6
Link: https://lore.kernel.org/r/20260929142944.1841462-1-tglozar@redhat.com
Signed-off-by: Tomas Glozar <tglozar@redhat.com>
This commit is contained in:
Tomas Glozar 2026-09-29 16:29:44 +02:00
parent adbf92c8b5
commit 5ddc449750
3 changed files with 375 additions and 836 deletions

View File

@ -6,9 +6,42 @@
#include "trace.h"
#include "utils.h"
/*
* OSNOISE_LL_OPTIONS - list of long long options backed by tracefs files.
* OSNOISE_LL_OPTION(field_name, tracefs_path)
*
* OSNOISE_FLAG_OPTIONS - list of boolean options backed by osnoise/options.
* OSNOISE_FLAG_OPTION(field_name, option_string)
*
* These X-macro lists are invoked in four places:
* - struct osnoise_context field declarations (common.h),
* - function declarations for osnoise_set_<opt>/osnoise_restore_<opt> (common.h),
* - function definitions for set/restore/put (osnoise.c),
* - context initialization and teardown in osnoise_context_alloc() and
* osnoise_put_context() (osnoise.c).
*/
#define OSNOISE_LL_OPTIONS \
OSNOISE_LL_OPTION(stop_us, "osnoise/stop_tracing_us") \
OSNOISE_LL_OPTION(stop_total_us, "osnoise/stop_tracing_total_us") \
OSNOISE_LL_OPTION(print_stack, "osnoise/print_stack") \
OSNOISE_LL_OPTION(tracing_thresh, "tracing_thresh") \
OSNOISE_LL_OPTION(timerlat_period_us, "osnoise/timerlat_period_us") \
OSNOISE_LL_OPTION(timerlat_align_us, "osnoise/timerlat_align_us")
#define OSNOISE_FLAG_OPTIONS \
OSNOISE_FLAG_OPTION(irq_disable, "OSNOISE_IRQ_DISABLE") \
OSNOISE_FLAG_OPTION(workload, "OSNOISE_WORKLOAD") \
OSNOISE_FLAG_OPTION(timerlat_align, "TIMERLAT_ALIGN")
/*
* osnoise_context - read, store, write, restore osnoise configs.
*/
#define OSNOISE_LL_OPTION(name, path) \
long long orig_##name; \
long long name;
#define OSNOISE_FLAG_OPTION(name, option_str) \
int orig_opt_##name; \
int opt_##name;
struct osnoise_context {
int flags;
int ref;
@ -16,50 +49,17 @@ struct osnoise_context {
char *curr_cpus;
char *orig_cpus;
/* 0 as init value */
unsigned long long orig_runtime_us;
unsigned long long runtime_us;
long long orig_runtime_us;
long long runtime_us;
/* 0 as init value */
unsigned long long orig_period_us;
unsigned long long period_us;
long long orig_period_us;
long long period_us;
/* 0 as init value */
long long orig_timerlat_period_us;
long long timerlat_period_us;
/* 0 as init value */
long long orig_tracing_thresh;
long long tracing_thresh;
/* -1 as init value because 0 is disabled */
long long orig_stop_us;
long long stop_us;
/* -1 as init value because 0 is disabled */
long long orig_stop_total_us;
long long stop_total_us;
/* -1 as init value because 0 is disabled */
long long orig_print_stack;
long long print_stack;
/* -1 as init value because 0 is off */
int orig_opt_irq_disable;
int opt_irq_disable;
/* -1 as init value because 0 is off */
int orig_opt_workload;
int opt_workload;
/* -1 as init value because 0 is off */
int orig_opt_timerlat_align;
int opt_timerlat_align;
/* 0 as init value */
unsigned long long orig_timerlat_align_us;
unsigned long long timerlat_align_us;
OSNOISE_LL_OPTIONS
OSNOISE_FLAG_OPTIONS
};
#undef OSNOISE_LL_OPTION
#undef OSNOISE_FLAG_OPTION
extern volatile int stop_tracing;
@ -173,15 +173,21 @@ int osnoise_get_cpu_count(void);
int osnoise_set_cpus(struct osnoise_context *context, char *cpus);
void osnoise_restore_cpus(struct osnoise_context *context);
int osnoise_set_workload(struct osnoise_context *context, bool onoff);
#define OSNOISE_LL_OPTION(name, path) \
int osnoise_set_##name(struct osnoise_context *context, long long name); \
void osnoise_restore_##name(struct osnoise_context *context);
#define OSNOISE_FLAG_OPTION(name, option_str) \
int osnoise_set_##name(struct osnoise_context *context, bool onoff); \
void osnoise_restore_##name(struct osnoise_context *context);
OSNOISE_LL_OPTIONS
OSNOISE_FLAG_OPTIONS
#undef OSNOISE_LL_OPTION
#undef OSNOISE_FLAG_OPTION
void osnoise_destroy_tool(struct osnoise_tool *top);
struct osnoise_tool *osnoise_init_tool(char *tool_name);
struct osnoise_tool *osnoise_init_trace_tool(struct common_params *params, const char *tracer);
bool osnoise_trace_is_off(struct osnoise_tool *tool, struct osnoise_tool *record);
int osnoise_set_stop_us(struct osnoise_context *context, long long stop_us);
int osnoise_set_stop_total_us(struct osnoise_context *context,
long long stop_total_us);
int common_apply_config(struct osnoise_tool *tool, struct common_params *params);
int top_main_loop(struct osnoise_tool *tool);

File diff suppressed because it is too large Load Diff

View File

@ -18,45 +18,15 @@ struct osnoise_params {
#define to_osnoise_params(ptr) container_of(ptr, struct osnoise_params, common)
/*
* *_INIT_VALs are also invalid values, they are used to
* communicate errors.
*/
#define OSNOISE_OPTION_INIT_VAL (-1)
#define OSNOISE_TIME_INIT_VAL (0)
struct osnoise_context *osnoise_context_alloc(void);
int osnoise_get_context(struct osnoise_context *context);
void osnoise_put_context(struct osnoise_context *context);
int osnoise_set_runtime_period(struct osnoise_context *context,
unsigned long long runtime,
unsigned long long period);
long long runtime,
long long period);
void osnoise_restore_runtime_period(struct osnoise_context *context);
void osnoise_restore_stop_us(struct osnoise_context *context);
void osnoise_restore_stop_total_us(struct osnoise_context *context);
int osnoise_set_timerlat_period_us(struct osnoise_context *context,
long long timerlat_period_us);
void osnoise_restore_timerlat_period_us(struct osnoise_context *context);
int osnoise_set_tracing_thresh(struct osnoise_context *context,
long long tracing_thresh);
void osnoise_restore_tracing_thresh(struct osnoise_context *context);
void osnoise_restore_print_stack(struct osnoise_context *context);
int osnoise_set_print_stack(struct osnoise_context *context,
long long print_stack);
int osnoise_set_timerlat_align_us(struct osnoise_context *context,
long long timerlat_align_us);
void osnoise_restore_timerlat_align_us(struct osnoise_context *context);
int osnoise_set_timerlat_align(struct osnoise_context *context, bool onoff);
int osnoise_set_irq_disable(struct osnoise_context *context, bool onoff);
void osnoise_report_invalid_events(struct osnoise_tool *tool);
void osnoise_report_missed_events(struct osnoise_tool *tool);
int osnoise_apply_config(struct osnoise_tool *tool, struct osnoise_params *params);