Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CPC: fix 0 CPC module clock scaling #9319

Merged
merged 8 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/boards/intel_adsp_cavs25.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ CONFIG_LP_MEMORY_BANKS=1
CONFIG_HP_MEMORY_BANKS=30
CONFIG_MM_DRV=y
CONFIG_INTEL_MODULES=y
CONFIG_LIBRARY_MANAGER=y
CONFIG_LIBRARY_MANAGER=n
CONFIG_RIMAGE_SIGNING_SCHEMA="tgl"

CONFIG_DEBUG_COREDUMP=y
Expand Down
2 changes: 1 addition & 1 deletion app/boards/intel_adsp_cavs25_tgph.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ CONFIG_LP_MEMORY_BANKS=1
CONFIG_HP_MEMORY_BANKS=30
CONFIG_MM_DRV=y
CONFIG_INTEL_MODULES=y
CONFIG_LIBRARY_MANAGER=y
CONFIG_LIBRARY_MANAGER=n
CONFIG_RIMAGE_SIGNING_SCHEMA="tgl-h"

CONFIG_DEBUG_COREDUMP=y
Expand Down
15 changes: 9 additions & 6 deletions src/audio/drc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
add_local_sources(sof drc.c)
add_local_sources(sof drc_generic.c)
add_local_sources(sof drc_hifi3.c)
add_local_sources(sof drc_hifi4.c)
add_local_sources(sof drc_math_generic.c)
add_local_sources(sof drc_math_hifi3.c)
add_local_sources(sof
drc.c
drc_generic.c
drc_hifi3.c
drc_hifi4.c
drc_math_generic.c
drc_math_hifi3.c
drc_log.c
)
7 changes: 3 additions & 4 deletions src/audio/drc/drc.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,10 @@
#include "drc.h"
#include "drc_algorithm.h"

LOG_MODULE_REGISTER(drc, CONFIG_SOF_LOG_LEVEL);
LOG_MODULE_DECLARE(drc, CONFIG_SOF_LOG_LEVEL);

SOF_DEFINE_REG_UUID(drc);

DECLARE_TR_CTX(drc_tr, SOF_UUID(drc_uuid), LOG_LEVEL_INFO);
extern const struct sof_uuid drc_uuid;
extern struct tr_ctx drc_tr;

void drc_reset_state(struct drc_state *state)
{
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit is optional. With it dropped log entries look like

[  140.980950] <inf> drc:

and without it like

[  326.927381] <inf>

So using this and similar log context relocation for LLEXT modules adds a bit of context when messages are dropped, but it isn't critical

Expand Down
15 changes: 15 additions & 0 deletions src/audio/drc/drc_log.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: BSD-3-Clause
//
// Copyright(c) 2024 Intel Corporation.

#include <rtos/symbol.h>
#include <sof/lib/uuid.h>
#include <sof/trace/trace.h>
#include <user/trace.h>

SOF_DEFINE_REG_UUID(drc);
LOG_MODULE_REGISTER(drc, CONFIG_SOF_LOG_LEVEL);
DECLARE_TR_CTX(drc_tr, SOF_UUID(drc_uuid), LOG_LEVEL_INFO);
EXPORT_SYMBOL(drc_tr);
EXPORT_SYMBOL(drc_uuid);
EXPORT_SYMBOL(log_const_drc);
141 changes: 56 additions & 85 deletions src/audio/pipeline/pipeline-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,9 @@ int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd)

return 0;
}
#else

#else /* CONFIG_LIBRARY */

/* only collect scheduling components */
static int pipeline_comp_list(struct comp_dev *current,
struct comp_buffer *calling_buf,
Expand Down Expand Up @@ -315,77 +317,69 @@ static void pipeline_trigger_xrun(struct pipeline *p, struct comp_dev **host)
}

#if CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL
static int pipeline_calc_cps_consumption(struct comp_dev *current,
struct comp_buffer *calling_buf,
struct pipeline_walk_context *ctx, int dir)
static struct ipc4_base_module_cfg *ipc4_get_base_cfg(struct comp_dev *comp)
{
struct pipeline_data *ppl_data = ctx->comp_data;
struct ipc4_base_module_cfg *cd;
int comp_core, kcps;

pipe_dbg(ppl_data->p, "pipeline_calc_cps_consumption(), current->comp.id = %u, dir = %u",
dev_comp_id(current), dir);
if (comp->drv->type != SOF_COMP_MODULE_ADAPTER)
return comp_get_drvdata(comp);

if (!comp_is_single_pipeline(current, ppl_data->start)) {
pipe_dbg(ppl_data->p, "pipeline_calc_cps_consumption(), current is from another pipeline");
return 0;
}
comp_core = current->ipc_config.core;

/* modules created through module adapter have different priv_data */
if (current->drv->type != SOF_COMP_MODULE_ADAPTER) {
cd = comp_get_drvdata(current);
} else {
struct processing_module *mod = comp_mod(current);
struct module_data *md = &mod->priv;
struct processing_module *mod = comp_mod(comp);
struct module_data *md = &mod->priv;

cd = &md->cfg.base_cfg;
}

if (cd->cpc == 0) {
/* Use maximum clock budget, assume 1ms chunk size */
uint32_t core_kcps = core_kcps_get(comp_core);
return &md->cfg.base_cfg;
}

if (!current->kcps_inc[comp_core]) {
current->kcps_inc[comp_core] = core_kcps;
ppl_data->kcps[comp_core] = CLK_MAX_CPU_HZ / 1000 - core_kcps;
} else {
ppl_data->kcps[comp_core] = core_kcps - current->kcps_inc[comp_core];
current->kcps_inc[comp_core] = 0;
static void pipeline_cps_rebalance(struct pipeline *p, bool starting)
{
unsigned int core_kcps[CONFIG_CORE_COUNT];
struct ipc *ipc = ipc_get();
struct ipc_comp_dev *icd;
struct list_item *clist;
const unsigned int clk_max_khz = CLK_MAX_CPU_HZ / 1000;

for (unsigned int i = 0; i < CONFIG_CORE_COUNT; i++)
core_kcps[i] = i == PLATFORM_PRIMARY_CORE_ID ? PRIMARY_CORE_BASE_CPS_USAGE :
SECONDARY_CORE_BASE_CPS_USAGE;

list_for_item(clist, &ipc->comp_list) {
icd = container_of(clist, struct ipc_comp_dev, list);
if (icd->type != COMP_TYPE_COMPONENT)
continue;

struct comp_dev *comp = icd->cd;

/*
* When a pipeline is started, its components have state PREPARE, when
* a pipeline is terminated, its components still have state ACTIVE
*/
if ((comp->state == COMP_STATE_ACTIVE &&
(starting || comp->pipeline != p)) ||
((comp->state == COMP_STATE_PREPARE || comp->state == COMP_STATE_PAUSED) &&
starting && comp->pipeline == p)) {
struct ipc4_base_module_cfg *cd = ipc4_get_base_cfg(comp);

if (cd->cpc && core_kcps[icd->core] < clk_max_khz)
core_kcps[icd->core] += cd->cpc;
else
core_kcps[icd->core] = clk_max_khz;
}
tr_warn(pipe,
"0 CPS requested for module: %#x, core: %d using safe max KCPS: %u",
current->ipc_config.id, comp_core, ppl_data->kcps[comp_core]);
}

return PPL_STATUS_PATH_STOP;
} else {
kcps = cd->cpc * 1000 / current->period;
tr_dbg(pipe, "Module: %#x KCPS consumption: %d, core: %d",
current->ipc_config.id, kcps, comp_core);
for (int i = 0; i < arch_num_cpus(); i++) {
int delta_kcps = core_kcps[i] - core_kcps_get(i);

ppl_data->kcps[comp_core] += kcps;
tr_dbg(pipe, "Proposed KCPS consumption: %d, core: %d, delta: %d",
core_kcps[i], i, delta_kcps);
if (delta_kcps)
core_kcps_adjust(i, delta_kcps);
}

return pipeline_for_each_comp(current, ctx, dir);
}
#endif
#endif /* CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL */

/* trigger pipeline in IPC context */
int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd)
{
int ret;
#if CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL
/* FIXME: this must be a platform-specific parameter or a Kconfig option */
#define DSP_MIN_KCPS 50000

struct pipeline_data data = {
.start = p->source_comp,
.p = p,
};
struct pipeline_walk_context walk_ctx = {
.comp_func = pipeline_calc_cps_consumption,
.comp_data = &data,
};
bool trigger_first = false;
uint32_t flags = 0;
#endif
Expand Down Expand Up @@ -418,16 +412,8 @@ int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd)
#if CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL
flags = irq_lock();
/* setup walking ctx for removing consumption */
if (!trigger_first) {
ret = walk_ctx.comp_func(p->source_comp, NULL, &walk_ctx, PPL_DIR_DOWNSTREAM);

for (int i = 0; i < arch_num_cpus(); i++) {
if (data.kcps[i] > 0) {
core_kcps_adjust(i, data.kcps[i]);
tr_info(pipe, "Sum of KCPS consumption: %d, core: %d", core_kcps_get(i), i);
}
}
}
if (!trigger_first)
pipeline_cps_rebalance(p, true);
#endif
ret = pipeline_trigger_list(p, host, cmd);
if (ret < 0) {
Expand All @@ -437,23 +423,8 @@ int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd)
return ret;
}
#if CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL
if (trigger_first) {
ret = walk_ctx.comp_func(p->source_comp, NULL, &walk_ctx, PPL_DIR_DOWNSTREAM);

for (int i = 0; i < arch_num_cpus(); i++) {
if (data.kcps[i] > 0) {
uint32_t core_kcps = core_kcps_get(i);

/* Tests showed, that we cannot go below 40000kcps on MTL */
if (data.kcps[i] > core_kcps - DSP_MIN_KCPS)
data.kcps[i] = core_kcps - DSP_MIN_KCPS;

core_kcps_adjust(i, -data.kcps[i]);
tr_info(pipe, "Sum of KCPS consumption: %d, core: %d",
core_kcps, i);
}
}
}
if (trigger_first)
pipeline_cps_rebalance(p, false);
irq_unlock(flags);
#endif
/* IPC response will be sent from the task, unless it was paused */
Expand All @@ -462,7 +433,7 @@ int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd)

return 0;
}
#endif
#endif /* CONFIG_LIBRARY */

/* Runs in IPC or in pipeline task context */
static int pipeline_comp_trigger(struct comp_dev *current,
Expand Down
2 changes: 2 additions & 0 deletions src/include/sof/lib/uuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <zephyr/sys/iterable_sections.h>
#endif

#include <stdint.h>

/** \addtogroup uuid_api UUID API
* UUID API specification.
* @{
Expand Down
15 changes: 14 additions & 1 deletion src/include/sof/llext_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,34 @@
#ifndef __SOF_LLEXT_MANAGER_H__
#define __SOF_LLEXT_MANAGER_H__

#include <stdbool.h>
#include <stdint.h>

#if CONFIG_LLEXT
#include <rimage/sof/user/manifest.h>

struct comp_dev;
struct comp_driver;
struct comp_ipc_config;

#if CONFIG_LLEXT
static inline bool module_is_llext(const struct sof_man_module *mod)
{
return mod->type.load_type == SOF_MAN_MOD_TYPE_LLEXT;
}

uintptr_t llext_manager_allocate_module(struct processing_module *proc,
const struct comp_ipc_config *ipc_config,
const void *ipc_specific_config);

int llext_manager_free_module(const uint32_t component_id);

bool comp_is_llext(struct comp_dev *comp);
#else
#define module_is_llext(mod) false
#define llext_manager_allocate_module(proc, ipc_config, ipc_specific_config) 0
#define llext_manager_free_module(component_id) 0
#define llext_unload(ext) 0
#define comp_is_llext(comp) false
#endif

#endif
10 changes: 6 additions & 4 deletions src/lib/clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,15 @@ void clock_set_freq(int clock, uint32_t hz)
idx = clock_get_nearest_freq_idx(clk_info->freqs, clk_info->freqs_num,
hz);

tr_info(&clock_tr, "clock %d set freq %dHz freq_idx %d",
clock, hz, idx);
if (clk_info->current_freq_idx != idx &&
(!clk_info->set_freq ||
clk_info->set_freq(clock, idx) == 0)) {
tr_info(&clock_tr, "clock %d set freq %dHz freq_idx %d old %d",
clock, hz, idx, clk_info->current_freq_idx);

if (!clk_info->set_freq ||
clk_info->set_freq(clock, idx) == 0)
/* update clock frequency */
clk_info->current_freq_idx = idx;
}

clock_unlock(key);
}
Expand Down
5 changes: 0 additions & 5 deletions src/library_manager/lib_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,6 @@ static int lib_manager_free_module_instance(uint32_t module_id, uint32_t instanc
return sys_mm_drv_unmap_region((__sparse_force void *)va_base, bss_size);
}

static inline bool module_is_llext(const struct sof_man_module *mod)
{
return mod->type.load_type == SOF_MAN_MOD_TYPE_LLEXT;
}

uintptr_t lib_manager_allocate_module(struct processing_module *proc,
const struct comp_ipc_config *ipc_config,
const void *ipc_specific_config)
Expand Down
10 changes: 10 additions & 0 deletions src/library_manager/llext_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,3 +363,13 @@ int llext_manager_free_module(const uint32_t component_id)

return llext_manager_unload_module(base_module_id, mod);
}

bool comp_is_llext(struct comp_dev *comp)
{
const uint32_t module_id = IPC4_MOD_ID(comp->ipc_config.id);
const unsigned int base_module_id = LIB_MANAGER_GET_LIB_ID(module_id) <<
LIB_MANAGER_LIB_ID_SHIFT;
const struct sof_man_module *mod = lib_manager_get_module_manifest(base_module_id);

return mod && module_is_llext(mod);
}
2 changes: 1 addition & 1 deletion west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ manifest:

- name: zephyr
repo-path: zephyr
revision: 795ac34f291c2f9895e7a3a03eafc053ad1d36f2
revision: 494f88070f6bb909389630264e4f89c71072ae53
remote: zephyrproject

# Import some projects listed in zephyr/west.yml@revision
Expand Down
6 changes: 6 additions & 0 deletions zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,12 @@ elseif(CONFIG_COMP_DRC)
)
endif()

if(NOT CONFIG_COMP_DRC STREQUAL "n")
zephyr_library_sources(
${SOF_AUDIO_PATH}/drc/drc_log.c
)
endif()

zephyr_library_sources_ifdef(CONFIG_COMP_MULTIBAND_DRC
${SOF_AUDIO_PATH}/multiband_drc/multiband_drc.c
${SOF_AUDIO_PATH}/multiband_drc/multiband_drc_generic.c
Expand Down
Loading