From d117581f0d0e9973d661a752873af0fce157b5f1 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 | 79 +++++++++++++++++++++ src/include/sof/debug/telemetry/telemetry.h | 19 +++++ 3 files changed, 108 insertions(+), 7 deletions(-) diff --git a/src/audio/base_fw.c b/src/audio/base_fw.c index eb3f7d5d5f00..f3c25bc65586 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 69c4695c5ced..dd4edeffc5bc 100644 --- a/src/debug/telemetry/telemetry.c +++ b/src/debug/telemetry/telemetry.c @@ -7,11 +7,14 @@ #include #include +#include #include #include +#include #include #include +#include #include #include @@ -305,6 +308,82 @@ int get_extended_performance_data(struct extended_global_perf_data * const ext_g return 0; } +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; + + /* Reinitialize performance data for all created components */ + 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 total_dsp_ycles here once implemented */ + return 0; +} + +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 0; +} + #ifdef CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS static void telemetry_perf_queue_append(struct telemetry_perf_queue *q, size_t element) { diff --git a/src/include/sof/debug/telemetry/telemetry.h b/src/include/sof/debug/telemetry/telemetry.h index f3d2dd355810..90f0c494e816 100644 --- a/src/include/sof/debug/telemetry/telemetry.h +++ b/src/include/sof/debug/telemetry/telemetry.h @@ -145,4 +145,23 @@ 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); +/** + * Reset performance data values for all records. + * + * @return 0 if succeeded, error code otherwise. + */ +int reset_performance_counters(void); + +/** + * Reinitialize performance data values for all created components; + * + * @return 0 if succeeded, error code otherwise. + */ +int enable_performance_counters(void); + +/** + * Unregister performance data records marked for removal. + */ +void disable_performance_counters(void); + #endif /*__SOF_TELEMETRY_H__ */