Skip to content
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
4 changes: 3 additions & 1 deletion src/audio/copier/host_copier.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ struct host_data {
uint16_t stream_tag;
uint16_t no_stream_position; /**< 1 means don't send stream position */
uint64_t total_data_processed;
uint8_t cont_update_posn; /**< 1 means continuous update stream position */
uint64_t nobytes_last_logged; /**< uptime, when "no bytes" was last logged */
unsigned int n_skipped; /**< number of "no bytes" skipped */
uint8_t cont_update_posn; /**< 1 means continuous update stream position */

/* host component attributes */
enum comp_copy_type copy_type; /**< Current host copy type */
Expand Down
27 changes: 24 additions & 3 deletions src/audio/host-zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,9 @@ static void host_dma_cb(struct comp_dev *dev, size_t bytes)
host_common_one_shot(hd, bytes);
}

/* Minimum time between 2 consecutive "no bytes to copy" messages in milliseconds */
#define SOF_MIN_NO_BYTES_INTERVAL_MS 20

/**
* Calculates bytes to be copied in normal mode.
* @param dev Host component device.
Expand Down Expand Up @@ -403,9 +406,26 @@ static uint32_t host_get_copy_bytes_normal(struct host_data *hd, struct comp_dev
if (!(hd->ipc_host.feature_mask & BIT(IPC4_COPIER_FAST_MODE)))
dma_copy_bytes = MIN(hd->period_bytes, dma_copy_bytes);

if (!dma_copy_bytes)
comp_info(dev, "no bytes to copy, available samples: %d, free_samples: %d",
avail_samples, free_samples);
bool reset_skipped = false;
uint64_t now = k_uptime_get();
uint64_t delta = now - hd->nobytes_last_logged;

if (!dma_copy_bytes) {
if (delta > SOF_MIN_NO_BYTES_INTERVAL_MS) {
hd->nobytes_last_logged = now;
comp_warn(dev, "no bytes to copy, available samples: %d, free_samples: %d",
avail_samples, free_samples);
Copy link
Contributor

Choose a reason for hiding this comment

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

Idea: add a counter. Log how many messages have been hidden like
"no bytes to copy, %u such events in last %u ms, available samples: %d, free_samples: %d",

reset_skipped = true;
} else {
hd->n_skipped++;
}
}

if (hd->n_skipped && (reset_skipped || dma_copy_bytes)) {
comp_warn(dev, "Skipped %u no-bytes events in last %llu ms",
hd->n_skipped, delta);
hd->n_skipped = 0;
}

/* dma_copy_bytes should be aligned to minimum possible chunk of
* data to be copied by dma.
Expand Down Expand Up @@ -659,6 +679,7 @@ static struct comp_dev *host_new(const struct comp_driver *drv,
if (!hd)
goto e_data;

hd->nobytes_last_logged = k_uptime_get();
comp_set_drvdata(dev, hd);

ret = host_common_new(hd, dev, ipc_host, dev->ipc_config.id);
Expand Down
2 changes: 0 additions & 2 deletions src/include/sof/ipc/topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ typedef uint32_t ipc_comp;
struct ipc_comp_dev;
const struct comp_driver *ipc4_get_comp_drv(uint32_t module_id);
struct comp_dev *ipc4_get_comp_dev(uint32_t comp_id);
int ipc4_add_comp_dev(struct comp_dev *dev);
const struct comp_driver *ipc4_get_drv(const void *uuid);
int ipc4_chain_manager_create(struct ipc4_chain_dma *cdma);
int ipc4_chain_dma_state(struct comp_dev *dev, struct ipc4_chain_dma *cdma);
int ipc4_create_chain_dma(struct ipc *ipc, struct ipc4_chain_dma *cdma);
Expand Down
9 changes: 7 additions & 2 deletions src/ipc/ipc-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <rtos/cache.h>
#include <sof/lib/cpu.h>
#include <sof/lib/mailbox.h>
#include <sof/lib/memory.h>
#include <sof/list.h>
#include <sof/platform.h>
#include <rtos/sof.h>
Expand Down Expand Up @@ -188,12 +189,14 @@ static void schedule_ipc_worker(void)
#endif
}

void ipc_msg_send_direct(struct ipc_msg *msg, void *data)
__cold void ipc_msg_send_direct(struct ipc_msg *msg, void *data)
{
struct ipc *ipc = ipc_get();
k_spinlock_key_t key;
int ret;

assert_can_be_cold();

key = k_spin_lock(&ipc->lock);

/* copy mailbox data to message if not already copied */
Expand Down Expand Up @@ -280,8 +283,10 @@ void ipc_schedule_process(struct ipc *ipc)
#endif
}

int ipc_init(struct sof *sof)
__cold int ipc_init(struct sof *sof)
{
assert_can_be_cold();

tr_dbg(&ipc_tr, "ipc_init()");

/* init ipc data */
Expand Down
20 changes: 15 additions & 5 deletions src/ipc/ipc-helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <rtos/cache.h>
#include <sof/lib/cpu.h>
#include <sof/lib/mailbox.h>
#include <sof/lib/memory.h>
#include <sof/list.h>
#include <sof/platform.h>
#include <rtos/sof.h>
Expand All @@ -37,8 +38,10 @@

LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL);

static bool valid_ipc_buffer_desc(const struct sof_ipc_buffer *desc)
__cold static bool valid_ipc_buffer_desc(const struct sof_ipc_buffer *desc)
{
assert_can_be_cold();

if (desc->caps >= SOF_MEM_CAPS_LOWEST_INVALID)
return false;

Expand All @@ -47,10 +50,12 @@ static bool valid_ipc_buffer_desc(const struct sof_ipc_buffer *desc)
}

/* create a new component in the pipeline */
struct comp_buffer *buffer_new(const struct sof_ipc_buffer *desc, bool is_shared)
__cold struct comp_buffer *buffer_new(const struct sof_ipc_buffer *desc, bool is_shared)
{
struct comp_buffer *buffer;

assert_can_be_cold();

tr_info(&buffer_tr, "buffer new size 0x%x id %d.%d flags 0x%x",
desc->size, desc->comp.pipeline_id, desc->comp.id, desc->flags);

Expand All @@ -75,6 +80,7 @@ struct comp_buffer *buffer_new(const struct sof_ipc_buffer *desc, bool is_shared
return buffer;
}

/* Called from multiple locations, including ipc_get_comp_by_ppl_id(), so cannot be cold */
int32_t ipc_comp_pipe_id(const struct ipc_comp_dev *icd)
{
switch (icd->type) {
Expand Down Expand Up @@ -177,9 +183,11 @@ int comp_verify_params(struct comp_dev *dev, uint32_t flag,
}
EXPORT_SYMBOL(comp_verify_params);

int comp_buffer_connect(struct comp_dev *comp, uint32_t comp_core,
struct comp_buffer *buffer, uint32_t dir)
__cold int comp_buffer_connect(struct comp_dev *comp, uint32_t comp_core,
struct comp_buffer *buffer, uint32_t dir)
{
assert_can_be_cold();

/* check if it's a connection between cores */
if (buffer->core != comp_core) {
#if CONFIG_INCOHERENT
Expand Down Expand Up @@ -258,13 +266,15 @@ int ipc_pipeline_complete(struct ipc *ipc, uint32_t comp_id)
ipc_ppl_sink->cd);
}

int ipc_comp_free(struct ipc *ipc, uint32_t comp_id)
__cold int ipc_comp_free(struct ipc *ipc, uint32_t comp_id)
{
struct ipc_comp_dev *icd;
struct comp_buffer *buffer;
struct comp_buffer *safe;
uint32_t flags;

assert_can_be_cold();

/* check whether component exists */
icd = ipc_get_comp_by_id(ipc, comp_id);
if (!icd) {
Expand Down
Loading
Loading