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
8 changes: 8 additions & 0 deletions Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,14 @@ config DEBUG_HEAP
help
Select for enable heap alloc debugging

config DEBUG_MEMORY_USAGE_SCAN
bool "Memory usage scan"
default y
help
It enables memory usage scan at demand in runtime.
This feature does not affect standard memory operations,
especially allocation and deallocation.

config DEBUG_BLOCK_FREE
bool "Blocks freeing debug"
default n
Expand Down
1 change: 1 addition & 0 deletions src/arch/xtensa/configs/baytrail_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ CONFIG_COMP_ASRC=n
CONFIG_COMP_TDFB=n
CONFIG_OPTIMIZE_FOR_SIZE=y
CONFIG_HAVE_AGENT=n
CONFIG_DEBUG_MEMORY_USAGE_SCAN=n
1 change: 1 addition & 0 deletions src/arch/xtensa/configs/baytrail_gcc_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ CONFIG_COMP_SRC=n
CONFIG_COMP_ASRC=n
CONFIG_COMP_TDFB=n
CONFIG_HAVE_AGENT=n
CONFIG_DEBUG_MEMORY_USAGE_SCAN=n
1 change: 1 addition & 0 deletions src/arch/xtensa/configs/cherrytrail_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ CONFIG_COMP_SRC=n
CONFIG_COMP_TDFB=n
CONFIG_OPTIMIZE_FOR_SIZE=y
CONFIG_HAVE_AGENT=n
CONFIG_DEBUG_MEMORY_USAGE_SCAN=n
1 change: 1 addition & 0 deletions src/arch/xtensa/configs/cherrytrail_gcc_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ CONFIG_COMP_SRC=n
CONFIG_COMP_ASRC=n
CONFIG_COMP_TDFB=n
CONFIG_HAVE_AGENT=n
CONFIG_DEBUG_MEMORY_USAGE_SCAN=n
39 changes: 39 additions & 0 deletions src/include/ipc/debug.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright(c) 2020 Intel Corporation. All rights reserved.
*
* Author: Author: Karol Trzcinski <karolx.trzcinski@linux.intel.com>
*/

#ifndef __IPC_DEBUG_H__
#define __IPC_DEBUG_H__

#include <ipc/header.h>
#include <stdint.h>

/** ABI3.18 */
enum sof_ipc_dbg_mem_zone {
SOF_IPC_MEM_ZONE_SYS = 0, /**< System zone */
SOF_IPC_MEM_ZONE_SYS_RUNTIME = 1, /**< System-runtime zone */
SOF_IPC_MEM_ZONE_RUNTIME = 2, /**< Runtime zone */
SOF_IPC_MEM_ZONE_BUFFER = 3, /**< Buffer zone */
};

/** ABI3.18 */
struct sof_ipc_dbg_mem_usage_elem {
uint32_t zone; /**< see sof_ipc_dbg_mem_zone */
uint32_t id; /**< heap index within zone */
uint32_t used; /**< number of bytes used in zone */
uint32_t free; /**< number of bytes free to use within zone */
uint32_t reserved; /**< reserved for future use */
} __attribute__((packed));

/** ABI3.18 */
struct sof_ipc_dbg_mem_usage {
struct sof_ipc_reply rhdr; /**< generic IPC reply header */
uint32_t reserved[4]; /**< reserved for future use */
uint32_t num_elems; /**< elems[] counter */
struct sof_ipc_dbg_mem_usage_elem elems[]; /**< memory usage information */
} __attribute__((packed));

#endif /* __IPC_DEBUG_H__ */
9 changes: 9 additions & 0 deletions src/include/ipc/header.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@
#define SOF_IPC_GLB_GDB_DEBUG SOF_GLB_TYPE(0xAU)
#define SOF_IPC_GLB_TEST SOF_GLB_TYPE(0xBU)
#define SOF_IPC_GLB_PROBE SOF_GLB_TYPE(0xCU)
#define SOF_IPC_GLB_DEBUG SOF_GLB_TYPE(0xDU)

/** @} */

Expand Down Expand Up @@ -285,6 +286,14 @@

/** @} */

/** \name DSP Command: Debug - additional services
* @{
*/

#define SOF_IPC_DEBUG_MEM_USAGE SOF_CMD_TYPE(0x001)

/** @} */

/** \name DSP Command: Test - Debug build only
* @{
*/
Expand Down
2 changes: 1 addition & 1 deletion src/include/kernel/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

/** \brief SOF ABI version major, minor and patch numbers */
#define SOF_ABI_MAJOR 3
#define SOF_ABI_MINOR 17
#define SOF_ABI_MINOR 18
#define SOF_ABI_PATCH 0

/** \brief SOF ABI version number. Format within 32bit word is MMmmmppp */
Expand Down
1 change: 1 addition & 0 deletions src/include/kernel/ext_manifest.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ enum ext_man_elem_type {
/* EXT_MAN_ELEM_CONFIG_DATA elements identificators */
enum config_elem_type {
EXT_MAN_CONFIG_IPC_MSG_SIZE = 1,
EXT_MAN_CONFIG_MEMORY_USAGE_SCAN = 2, /**< ABI3.18 */
EXT_MAN_CONFIG_LAST_ELEM, /**< keep it at the end of enum list */
};

Expand Down
10 changes: 10 additions & 0 deletions src/include/sof/lib/mm_heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ void free_heap(enum mem_zone zone);
void heap_trace_all(int force);
void heap_trace(struct mm_heap *heap, int size);

#if CONFIG_DEBUG_MEMORY_USAGE_SCAN
/** Fetch runtime information about heap, like used and free memory space
* @param zone to check, see enum mem_zone.
* @param index heap index, eg. cpu core index for any *SYS* zone
* @param out output variable
* @return error code or zero
*/
int heap_info(enum mem_zone zone, int index, struct mm_info *out);
#endif

/* retrieve memory map pointer */
static inline struct mm *memmap_get(void)
{
Expand Down
1 change: 1 addition & 0 deletions src/init/ext_manifest.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,6 @@ const struct ext_man_config_data ext_man_config
EXT_MAN_ALIGN),
.elems = {
{EXT_MAN_CONFIG_IPC_MSG_SIZE, SOF_IPC_MSG_MAX_SIZE},
{EXT_MAN_CONFIG_MEMORY_USAGE_SCAN, IS_ENABLED(CONFIG_DEBUG_MEMORY_USAGE_SCAN)},
},
};
79 changes: 76 additions & 3 deletions src/ipc/handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <sof/lib/dma.h>
#include <sof/lib/mailbox.h>
#include <sof/lib/memory.h>
#include <sof/lib/mm_heap.h>
#include <sof/lib/pm_runtime.h>
#include <sof/list.h>
#include <sof/math/numbers.h>
Expand All @@ -42,6 +43,7 @@
#include <sof/trace/trace.h>
#include <ipc/control.h>
#include <ipc/dai.h>
#include <ipc/debug.h>
#include <ipc/header.h>
#include <ipc/pm.h>
#include <ipc/stream.h>
Expand Down Expand Up @@ -796,7 +798,7 @@ static int ipc_trace_filter_update(uint32_t header)
return ret;
}

static int ipc_glb_debug_message(uint32_t header)
static int ipc_glb_trace_message(uint32_t header)
{
uint32_t cmd = iCS(header);

Expand All @@ -814,7 +816,7 @@ static int ipc_glb_debug_message(uint32_t header)
}
}
#else
static int ipc_glb_debug_message(uint32_t header)
static int ipc_glb_trace_message(uint32_t header)
{
/* traces are disabled - CONFIG_TRACE is not set */

Expand Down Expand Up @@ -1281,6 +1283,74 @@ static int ipc_glb_tplg_message(uint32_t header)
}
}

#if CONFIG_DEBUG_MEMORY_USAGE_SCAN
static int fill_mem_usage_elems(int zone, int elem_number,
struct sof_ipc_dbg_mem_usage_elem *elems)
{
struct mm_info info;
int ret;
int i;

for (i = 0; i < elem_number; ++i) {
ret = heap_info(zone, i, &info);
elems[i].zone = zone;
elems[i].id = i;
elems[i].used = ret < 0 ? UINT32_MAX : info.used;
elems[i].free = ret < 0 ? 0 : info.free;
}

return elem_number;
}

static int ipc_glb_test_mem_usage(uint32_t header)
{
/* count number heaps */
int elem_cnt = PLATFORM_HEAP_SYSTEM + PLATFORM_HEAP_SYSTEM_RUNTIME +
PLATFORM_HEAP_RUNTIME + PLATFORM_HEAP_BUFFER;
size_t size = sizeof(struct sof_ipc_dbg_mem_usage) +
elem_cnt * sizeof(struct sof_ipc_dbg_mem_usage_elem);
struct sof_ipc_dbg_mem_usage_elem *elems;
struct sof_ipc_dbg_mem_usage *mem_usage;

mem_usage = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, 0, size);
if (!mem_usage)
return -ENOMEM;

mem_usage->rhdr.hdr.cmd = header;
mem_usage->rhdr.hdr.size = size;
mem_usage->num_elems = elem_cnt;

/* fill list of elems */
elems = mem_usage->elems;
elems += fill_mem_usage_elems(SOF_IPC_MEM_ZONE_SYS, PLATFORM_HEAP_SYSTEM, elems);
elems += fill_mem_usage_elems(SOF_IPC_MEM_ZONE_SYS_RUNTIME, PLATFORM_HEAP_SYSTEM_RUNTIME,
elems);
elems += fill_mem_usage_elems(SOF_IPC_MEM_ZONE_RUNTIME, PLATFORM_HEAP_RUNTIME, elems);
elems += fill_mem_usage_elems(SOF_IPC_MEM_ZONE_BUFFER, PLATFORM_HEAP_BUFFER, elems);

/* write component values to the outbox */
mailbox_hostbox_write(0, mem_usage, mem_usage->rhdr.hdr.size);

rfree(mem_usage);
return 1;
}
#endif

static int ipc_glb_debug_message(uint32_t header)
{
uint32_t cmd = iCS(header);

switch (cmd) {
#if CONFIG_DEBUG_MEMORY_USAGE_SCAN
case SOF_IPC_DEBUG_MEM_USAGE:
return ipc_glb_test_mem_usage(header);
#endif
default:
tr_err(&ipc_tr, "ipc: unknown debug header 0x%x", header);
return -EINVAL;
}
}

#if CONFIG_DEBUG
static int ipc_glb_test_message(uint32_t header)
{
Expand Down Expand Up @@ -1337,14 +1407,17 @@ void ipc_cmd(struct sof_ipc_cmd_hdr *hdr)
ret = ipc_glb_dai_message(hdr->cmd);
break;
case SOF_IPC_GLB_TRACE_MSG:
ret = ipc_glb_debug_message(hdr->cmd);
ret = ipc_glb_trace_message(hdr->cmd);
break;
case SOF_IPC_GLB_GDB_DEBUG:
ret = ipc_glb_gdb_debug(hdr->cmd);
break;
case SOF_IPC_GLB_PROBE:
ret = ipc_glb_probe(hdr->cmd);
break;
case SOF_IPC_GLB_DEBUG:
ret = ipc_glb_debug_message(hdr->cmd);
break;
#if CONFIG_DEBUG
case SOF_IPC_GLB_TEST:
ret = ipc_glb_test_message(hdr->cmd);
Expand Down
45 changes: 45 additions & 0 deletions src/lib/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1069,3 +1069,48 @@ void init_heap(struct sof *sof)

platform_shared_commit(memmap, sizeof(*memmap));
}

#if CONFIG_DEBUG_MEMORY_USAGE_SCAN
int heap_info(enum mem_zone zone, int index, struct mm_info *out)
{
struct mm *memmap = memmap_get();
struct mm_heap *heap;

if (!out)
goto error;

switch (zone) {
case SOF_MEM_ZONE_SYS:
if (index >= PLATFORM_HEAP_SYSTEM)
goto error;
heap = memmap->system + index;
break;
case SOF_MEM_ZONE_SYS_RUNTIME:
if (index >= PLATFORM_HEAP_SYSTEM_RUNTIME)
goto error;
heap = memmap->system_runtime + index;
break;
case SOF_MEM_ZONE_RUNTIME:
if (index >= PLATFORM_HEAP_RUNTIME)
goto error;
heap = memmap->runtime + index;
break;
case SOF_MEM_ZONE_BUFFER:
if (index >= PLATFORM_HEAP_BUFFER)
goto error;
heap = memmap->buffer + index;
break;
default:
goto error;
}

spin_lock(&memmap->lock);
*out = heap->info;
spin_unlock(&memmap->lock);
return 0;
error:
tr_err(&mem_tr, "heap_info(): failed for zone 0x%x index %d out ptr 0x%x", zone, index,
(uint32_t)out);
return -EINVAL;
}
#endif