Skip to content
Draft
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
13 changes: 11 additions & 2 deletions src/audio/component.c
Original file line number Diff line number Diff line change
Expand Up @@ -640,13 +640,18 @@ void comp_init_performance_data(struct comp_dev *dev)
{
struct perf_data_item_comp *item = dev->perf_data.perf_data_item;

if (item)
if (item) {
perf_data_item_comp_init(item, dev->ipc_config.id, 0);
perf_data_update_module_resources(dev);
}
}

/* returns true if budget violation occurred */
static bool update_peak_of_measured_cpc(struct comp_dev *dev, size_t measured_cpc)
{
if (dev->cpc && measured_cpc > dev->cpc)
perf_data_inc_cpc_violation(dev);

if (measured_cpc <= dev->perf_data.peak_of_measured_cpc)
return false;
dev->perf_data.peak_of_measured_cpc = measured_cpc;
Expand All @@ -657,7 +662,8 @@ bool comp_update_performance_data(struct comp_dev *dev, uint32_t cycles_used)
{
struct perf_data_item_comp *item = dev->perf_data.perf_data_item;

if (perf_meas_get_state() == IPC4_PERF_MEASUREMENTS_STARTED) {
if (perf_meas_get_state() == IPC4_PERF_MEASUREMENTS_STARTED ||
IS_ENABLED(CONFIG_SOF_TELEMETRY_MODULE_RESOURCES)) {
/* we divide by ibs so we need to check if its set */
if (item && dev->ibs != 0) {
item->total_iteration_count++;
Expand Down Expand Up @@ -720,6 +726,9 @@ void comp_update_ibs_obs_cpc(struct comp_dev *dev)
dev->obs = dev_cfg.obs;
dev->ibs = dev_cfg.ibs;
dev->cpc = dev_cfg.cpc;
#ifdef CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS
perf_data_update_module_resources(dev);
#endif
#else
/* set neutral values */
dev->ll_chunk_size = 0;
Expand Down
9 changes: 9 additions & 0 deletions src/audio/dai-zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <sof/audio/component_ext.h>
#include <sof/audio/format.h>
#include <sof/audio/pipeline.h>
#include <sof/debug/telemetry/telemetry.h>
#include <module/module/base.h>
#include <sof/common.h>
#include <rtos/panic.h>
Expand Down Expand Up @@ -357,6 +358,7 @@ dai_dma_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes,
/* fill buffer with silence */
buffer_zero(dd->dma_buffer);

telemetry_update_dai_hot(dd, dev);
return dma_status;
}

Expand Down Expand Up @@ -502,6 +504,7 @@ dai_dma_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes,
/* Increment performance counters */
io_perf_monitor_update_data(dd->io_perf_dai_byte_count, bytes);
#endif
telemetry_update_dai_hot(dd, dev);

return dma_status;
}
Expand Down Expand Up @@ -532,6 +535,7 @@ dai_dma_multi_endpoint_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t fr
/* fill buffer with silence */
buffer_zero(dd->dma_buffer);

telemetry_update_dai_hot(dd, dev);
return dma_status;
}

Expand Down Expand Up @@ -564,6 +568,7 @@ dai_dma_multi_endpoint_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t fr

/* update host position (in bytes offset) for drivers */
dd->total_data_processed += bytes;
telemetry_update_dai_hot(dd, dev);

return dma_status;
}
Expand Down Expand Up @@ -656,6 +661,7 @@ __cold int dai_common_new(struct dai_data *dd, struct comp_dev *dev,
io_perf_monitor_init_data(&dd->io_perf_dai_byte_count, &init_data);
}
#endif
telemetry_register_dai(dd, dev);

return 0;
}
Expand Down Expand Up @@ -790,6 +796,7 @@ __cold void dai_common_free(struct dai_data *dd)
#ifdef CONFIG_SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS
io_perf_monitor_release_slot(dd->io_perf_dai_byte_count);
#endif
telemetry_unregister_dai(dd);

if (dd->group)
dai_group_put(dd->group);
Expand Down Expand Up @@ -1293,6 +1300,7 @@ int dai_common_params(struct dai_data *dd, struct comp_dev *dev,
goto out;
}

telemetry_register_dai(dd, dev);
out:
/*
* Make sure to free all allocated items, all functions
Expand Down Expand Up @@ -1559,6 +1567,7 @@ static int dai_comp_trigger_internal(struct dai_data *dd, struct comp_dev *dev,
case COMP_TRIGGER_XRUN:
comp_info(dev, "XRUN");
dd->xrun = 1;
telemetry_update_dai_hot(dd, dev);

COMPILER_FALLTHROUGH;
case COMP_TRIGGER_STOP:
Expand Down
5 changes: 5 additions & 0 deletions src/audio/host-zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <sof/ut.h>
#include <sof/trace/trace.h>
#include <sof/debug/telemetry/performance_monitor.h>
#include <sof/debug/telemetry/telemetry.h>
#include <sof/schedule/ll_schedule_domain.h> /* zephyr_ll_user_heap() */
#include <ipc/stream.h>
#include <ipc/topology.h>
Expand Down Expand Up @@ -269,6 +270,7 @@ void host_common_update(struct host_data *hd, struct comp_dev *dev, uint32_t byt
#endif

hd->total_data_processed += bytes;
telemetry_update_host_hot(hd, dev);

/* new local period, update host buffer position blks
* local_pos is queried by the ops.position() API
Expand Down Expand Up @@ -533,6 +535,7 @@ static uint32_t host_get_copy_bytes_normal(struct host_data *hd, struct comp_dev
avail_samples, free_samples);
}
hd->n_skipped++;
telemetry_update_host_hot(hd, dev);
}
}

Expand Down Expand Up @@ -842,6 +845,7 @@ __cold void host_common_free(struct host_data *hd)
hd->io_perf_host_byte_count = NULL;
}
#endif
telemetry_unregister_host(hd);

/* release DMA channel if not already done by reset */
if (hd->chan_index >= 0) {
Expand Down Expand Up @@ -1173,6 +1177,7 @@ int host_common_params(struct host_data *hd, struct comp_dev *dev,
io_perf_monitor_init_data(&hd->io_perf_host_byte_count, &init_data);
}
#endif
telemetry_register_host(hd, dev);

return 0;

Expand Down
6 changes: 6 additions & 0 deletions src/audio/module_adapter/module/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <sof/objpool.h>
#include <sof/audio/module_adapter/module/generic.h>
#include <sof/audio/data_blob.h>
#include <sof/debug/telemetry/performance_monitor.h>
#include <sof/lib/cold.h>
#include <sof/lib/fast-get.h>
#include <sof/lib/vregion.h>
Expand Down Expand Up @@ -231,6 +232,7 @@ void *z_impl_mod_balloc_align(struct processing_module *mod, size_t size, size_t
res->heap_high_water_mark = res->heap_usage;

k_mutex_unlock(&mod_res_lock);
perf_data_update_module_resources(mod->dev);
return ptr;
}
EXPORT_SYMBOL(z_impl_mod_balloc_align);
Expand Down Expand Up @@ -284,6 +286,7 @@ void *z_impl_mod_alloc_ext(struct processing_module *mod, uint32_t flags, size_t
res->heap_high_water_mark = res->heap_usage;

k_mutex_unlock(&mod_res_lock);
perf_data_update_module_resources(mod->dev);
return ptr;
}
EXPORT_SYMBOL(z_impl_mod_alloc_ext);
Expand Down Expand Up @@ -486,6 +489,8 @@ int z_impl_mod_free(struct processing_module *mod, const void *ptr)

if (ret < 0)
comp_err(mod->dev, "error: could not find memory pointed by %p", ptr);
else
perf_data_update_module_resources(mod->dev);

return ret;
}
Expand Down Expand Up @@ -791,6 +796,7 @@ __cold void z_impl_mod_free_all(struct processing_module *mod)

/* Make sure resource lists and accounting are reset */
mod_resource_init(mod);
perf_data_update_module_resources(mod->dev);
}

__cold int module_free(struct processing_module *mod)
Expand Down
9 changes: 8 additions & 1 deletion src/audio/pipeline/pipeline-schedule.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <sof/audio/buffer.h>
#include <sof/audio/component_ext.h>
#include <sof/audio/pipeline.h>
#include <sof/debug/telemetry/telemetry.h>
#include <rtos/alloc.h>
#include <rtos/interrupt.h>
#include <sof/lib/agent.h>
Expand Down Expand Up @@ -107,6 +108,7 @@ static enum task_state pipeline_task_cmd(struct pipeline *p,
}

p->trigger.aborted = false;
telemetry_notify_pipeline_change();
return ret;
}

Expand Down Expand Up @@ -144,8 +146,10 @@ static enum task_state pipeline_task_cmd(struct pipeline *p,
}
} else if (p->trigger.cmd != cmd) {
/* PRE stage completed */
if (p->trigger.delay)
if (p->trigger.delay) {
telemetry_notify_pipeline_change();
return SOF_TASK_STATE_RESCHEDULE;
}
/* No delay: the final stage has already run too */
err = SOF_TASK_STATE_RESCHEDULE;
} else if (p->status == COMP_STATE_PAUSED) {
Expand All @@ -163,6 +167,7 @@ static enum task_state pipeline_task_cmd(struct pipeline *p,
}

p->trigger.cmd = COMP_TRIGGER_NO_ACTION;
telemetry_notify_pipeline_change();

ipc_msg_reply(reply);

Expand Down Expand Up @@ -240,6 +245,7 @@ static enum task_state ipc3_pipeline_task(void *arg)
err = pipeline_xrun_recover(p);
if (err < 0) {
pipe_err(p, "xrun recovery failed! pipeline is stopped.");
telemetry_notify_pipeline_change();
/* failed - host will stop this pipeline */
return SOF_TASK_STATE_COMPLETED;
}
Expand Down Expand Up @@ -332,6 +338,7 @@ static enum task_state ipc4_pipeline_copy_task(void *arg)
err = pipeline_xrun_recover(p);
if (err < 0) {
pipe_err(p, "xrun recovery failed! pipeline is stopped.");
telemetry_notify_pipeline_change();
/* failed - host will stop this pipeline */
return SOF_TASK_STATE_COMPLETED;
}
Expand Down
8 changes: 7 additions & 1 deletion src/audio/pipeline/pipeline-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <sof/audio/buffer.h>
#include <sof/audio/component_ext.h>
#include <sof/audio/pipeline.h>
#include <sof/debug/telemetry/telemetry.h>
#include <sof/lib/dai.h>
#include <rtos/timer.h>
#include <sof/list.h>
Expand Down Expand Up @@ -401,7 +402,10 @@ int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd)
if (p->status == COMP_STATE_PAUSED || p->xrun_bytes) {
/* The task isn't running, trigger inline */
ret = pipeline_trigger_run(p, host, cmd);
return ret < 0 ? ret : 0;
if (ret < 0)
return ret;
telemetry_notify_pipeline_change();
return 0;
}

COMPILER_FALLTHROUGH;
Expand Down Expand Up @@ -432,9 +436,11 @@ int pipeline_trigger(struct pipeline *p, struct comp_dev *host, int cmd)
irq_unlock(flags);
#endif
/* IPC response will be sent from the task, unless it was paused */
telemetry_notify_pipeline_change();
return PPL_STATUS_SCHEDULED;
}

telemetry_notify_pipeline_change();
return 0;
}

Expand Down
5 changes: 5 additions & 0 deletions src/audio/pipeline/pipeline-xrun.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#include <sof/audio/buffer.h>
#include <sof/audio/pipeline.h>
#include <sof/debug/telemetry/performance_monitor.h>
#include <sof/debug/telemetry/telemetry.h>
#include <sof/ipc/msg.h>
#include <sof/list.h>
#include <sof/lib/mailbox.h>
Expand Down Expand Up @@ -163,6 +165,9 @@ void pipeline_xrun(struct pipeline *p, struct comp_dev *dev,
if (dev->state != COMP_STATE_ACTIVE)
return;

telemetry_notify_pipeline_xrun(p, bytes);
perf_data_inc_xrun(dev);

/* notify all pipeline comps we are in XRUN, and stop copying */
ret = pipeline_trigger(p, p->source_comp, COMP_TRIGGER_XRUN);
if (ret < 0)
Expand Down
86 changes: 86 additions & 0 deletions src/debug/telemetry/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,89 @@ config SOF_TELEMETRY_IO_PERFORMANCE_MEASUREMENTS
Disabled by default and enabled with IPC. Measurements can be extracted also by IPC.
Interfaces measured: IPC, IDC, DMIC, I2S, SNDW, HDA, USB, GPIO, I2c, I3C, UART, SPI, CSI_2, DTF.

if SOF_TELEMETRY

config SOF_TELEMETRY_EXTENDED_WINDOW
bool "Extended telemetry directory in Memory Window 2 Slot 1"
default y
help
Places a 64-byte-aligned self-describing TEL2 directory header and
cache-line-concentrated hot counter zone after system_tick_info in
the telemetry debug window slot to expose internal SOF resources.

config SOF_TELEMETRY_HOT_CACHE_STAGING
bool "Stage LL hot-path telemetry updates in L1 D-cache lines"
depends on SOF_TELEMETRY_EXTENDED_WINDOW
default y
help
Accumulates LL hot-path counter increments in 64-byte-aligned L1 D$
lines and flushes dirty cache lines to the uncached memory window
once at the end of the LL tick.

config SOF_TELEMETRY_MEMORY
bool "Memory, k_heap, virtual heap, and SRAM page telemetry"
depends on SOF_TELEMETRY_EXTENDED_WINDOW
select SYS_HEAP_RUNTIME_STATS
default y
help
Exports live usage, free bytes, high-water marks, and allocation
failure counters for sof_heap, shared_buffer_heap, ll_user_heap,
l3_heap, virtual_buffers_heap (vmh), and fast_get in MW2 Slot 1.

config SOF_TELEMETRY_VREGION
bool "Virtual page (vpage) and virtual region (vregion) telemetry"
depends on SOF_TELEMETRY_EXTENDED_WINDOW && SOF_VREGIONS
default y
help
Tracks vpage_ctx page usage/fragmentation and per-vregion lifetime
linear allocator and interim k_heap usage in MW2 Slot 1.

config SOF_TELEMETRY_PIPELINES
bool "Pipeline and LL/DP scheduler telemetry"
depends on SOF_TELEMETRY_EXTENDED_WINDOW
default y
help
Exports active pipeline states, periods, priorities, XRUN counts,
and per-core LL/DP task counts and deadline misses in MW2 Slot 1.

config SOF_TELEMETRY_DAIS
bool "DAI and Host DMA gateway telemetry"
depends on SOF_TELEMETRY_EXTENDED_WINDOW
default y
help
Exports active DAI and Host DMA gateway state, DMA channel, buffer
fill levels, XRUN/skip counts, and total bytes processed in MW2 Slot 1.

config SOF_TELEMETRY_THREADS
bool "Compact Zephyr thread CPU and stack telemetry in MW2 Slot 1"
depends on SOF_TELEMETRY_EXTENDED_WINDOW
select THREAD_MONITOR
select THREAD_NAME
select THREAD_STACK_INFO
select INIT_STACKS
select THREAD_RUNTIME_STATS
default y
help
Periodically snapshots per-thread CPU load (%) and stack high-water
mark (%) into MW2 Slot 1 without requiring an extra 4 KB debug_stream slot.

config SOF_TELEMETRY_MODULE_RESOURCES
bool "Per-module heap usage, CPC violation, and I/O telemetry in MW3"
depends on SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS
default y
help
Partitions Memory Window 3 to include per-component module_resources
(heap_usage, heap_high_water_mark), peak CPC vs budget, and relocating
io_perf_data_items from .bss into MW3.

config SOF_TELEMETRY_MAX_COMP_ENTRIES
int "Maximum component entries in Memory Window 3"
depends on SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS
range 1 88 if SOF_TELEMETRY_MODULE_RESOURCES
range 1 170
default 88 if SOF_TELEMETRY_MODULE_RESOURCES
default 170
help
Maximum number of component performance entries in Memory Window 3.

endif # SOF_TELEMETRY
Loading
Loading