From d09a79f23f7b492a554fcbcb81264a95267b2bc5 Mon Sep 17 00:00:00 2001 From: Tobiasz Dryjanski Date: Tue, 21 May 2024 12:43:44 +0200 Subject: [PATCH] performance measurements: extend perf meas state ipc Implement actual functionality for perf meas state ipc handling. This enables changing the state of global performance measurements. Signed-off-by: Tobiasz Dryjanski --- src/audio/base_fw.c | 17 ++-- src/debug/telemetry/telemetry.c | 88 +++++++++++++++++++++ src/include/sof/debug/telemetry/telemetry.h | 7 ++ 3 files changed, 105 insertions(+), 7 deletions(-) diff --git a/src/audio/base_fw.c b/src/audio/base_fw.c index 0a64117ddb12..50cd61695292 100644 --- a/src/audio/base_fw.c +++ b/src/audio/base_fw.c @@ -406,20 +406,23 @@ int set_perf_meas_state(const char *data) #ifdef CONFIG_SOF_TELEMETRY enum ipc4_perf_measurements_state_set state = *data; - struct telemetry_wnd_data *wnd_data = - (struct telemetry_wnd_data *)ADSP_DW->slots[SOF_DW_TELEMETRY_SLOT]; - struct system_tick_info *systick_info = - (struct system_tick_info *)wnd_data->system_tick_info; - switch (state) { case IPC4_PERF_MEASUREMENTS_DISABLED: + disable_performance_counters(); + perf_meas_set_state(IPC4_PERF_MEASUREMENTS_DISABLED); break; case IPC4_PERF_MEASUREMENTS_STOPPED: - for (int i = 0; i < CONFIG_MAX_CORE_COUNT; i++) - systick_info[i].peak_utilization = 0; + enable_performance_counters(); + reset_performance_counters(); + perf_meas_set_state(IPC4_PERF_MEASUREMENTS_STOPPED); break; case IPC4_PERF_MEASUREMENTS_STARTED: + enable_performance_counters(); + perf_meas_set_state(IPC4_PERF_MEASUREMENTS_STARTED); + break; case IPC4_PERF_MEASUREMENTS_PAUSED: + enable_performance_counters(); + perf_meas_set_state(IPC4_PERF_MEASUREMENTS_PAUSED); break; default: return -EINVAL; diff --git a/src/debug/telemetry/telemetry.c b/src/debug/telemetry/telemetry.c index 420bad8726b4..290e2f252e3e 100644 --- a/src/debug/telemetry/telemetry.c +++ b/src/debug/telemetry/telemetry.c @@ -21,6 +21,9 @@ #include #include +#include +#include + LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL); #define PERFORMANCE_DATA_ENTRIES_COUNT (CONFIG_MEMORY_WIN_3_SIZE / sizeof(struct perf_data_item_comp)) @@ -280,6 +283,91 @@ int get_extended_performance_data(struct extended_global_perf_data * const ext_g return IPC4_SUCCESS; } +enum ipc4_perf_measurements_state_set perf_meas_get_state(void) +{ + return perf_measurements_state; +} + +void perf_meas_set_state(enum ipc4_perf_measurements_state_set state) +{ + perf_measurements_state = state; +} + +void disable_performance_counters(void) +{ + for (size_t idx = 0; idx < perf_bitmap_get_size(&performance_data_bitmap); ++idx) { + if (perf_bitmap_is_bit_clear(&performance_data_bitmap, idx)) + continue; + if (perf_data_[idx].item.is_removed) + perf_data_free(&perf_data_[idx]); + } +} + +int enable_performance_counters(void) +{ + struct sof_man_module *man_module; + struct comp_dev *dev; + uint32_t comp_id; + const struct sof_man_fw_desc *desc; + + if (perf_measurements_state != IPC4_PERF_MEASUREMENTS_DISABLED) + return -EINVAL; + + for (int lib_id = 0; lib_id < LIB_MANAGER_MAX_LIBS; ++lib_id) { + if (lib_id == 0) { + desc = basefw_vendor_get_manifest(); + } else { +#if CONFIG_LIBRARY_MANAGER + desc = (struct sof_man_fw_desc *)lib_manager_get_library_manifest(lib_id); +#else + desc = NULL; +#endif + } + if (!desc) + continue; + + for (int mod_id = 0 ; mod_id < desc->header.num_module_entries; mod_id++) { + man_module = + (struct sof_man_module *)(desc + SOF_MAN_MODULE_OFFSET(mod_id)); + + for (int inst_id = 0; inst_id < man_module->instance_max_count; inst_id++) { + comp_id = IPC4_COMP_ID(mod_id, inst_id); + dev = ipc4_get_comp_dev(comp_id); + + if (dev) + comp_init_performance_data(dev); + } + } + } + + /* TODO clear totaldspcycles here once implemented */ + return IPC4_SUCCESS; +} + +int reset_performance_counters(void) +{ + if (perf_measurements_state == IPC4_PERF_MEASUREMENTS_DISABLED) + return -EINVAL; + + struct telemetry_wnd_data *wnd_data = + (struct telemetry_wnd_data *)ADSP_DW->slots[SOF_DW_TELEMETRY_SLOT]; + struct system_tick_info *systick_info = + (struct system_tick_info *)wnd_data->system_tick_info; + + for (size_t core_id = 0; core_id < CONFIG_MAX_CORE_COUNT; ++core_id) { + if (!(cpu_enabled_cores() & BIT(core_id))) + continue; + systick_info[core_id].peak_utilization = 0; + } + for (size_t idx = 0; idx < perf_bitmap_get_size(&performance_data_bitmap); ++idx) { + if (!perf_bitmap_is_bit_clear(&performance_data_bitmap, idx)) + perf_data_item_comp_reset(&perf_data_[idx]); + } + /* TODO clear totaldspcycles here once implemented */ + + return IPC4_SUCCESS; +} + /* Systic variables, one set per core */ static int telemetry_systick_counter[CONFIG_MAX_CORE_COUNT]; #ifdef CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS diff --git a/src/include/sof/debug/telemetry/telemetry.h b/src/include/sof/debug/telemetry/telemetry.h index 78d16ac75a10..a0c495430e31 100644 --- a/src/include/sof/debug/telemetry/telemetry.h +++ b/src/include/sof/debug/telemetry/telemetry.h @@ -104,4 +104,11 @@ int get_performance_data(struct global_perf_data * const global_perf_data); int get_extended_performance_data(struct extended_global_perf_data * const ext_global_perf_data); +int reset_performance_counters(void); +int enable_performance_counters(void); +void disable_performance_counters(void); + +void perf_meas_set_state(enum ipc4_perf_measurements_state_set state); +enum ipc4_perf_measurements_state_set perf_meas_get_state(void); + #endif /*__SOF_TELEMETRY_H__ */