logging: Add common api for getting memory usage
Logging v2 did not support getting memory usage data. Adding this support by creating common api for getting current and maximum usage. Tracking of maximum usage is optional and can be enabled using CONFIG_LOG_MEM_UTILIZATION. Updated shell command to use common API. Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
9ea5c1e510
commit
81ce6db313
6 changed files with 103 additions and 18 deletions
|
|
@ -220,6 +220,32 @@ static inline bool log_data_pending(void)
|
|||
*/
|
||||
int log_set_tag(const char *tag);
|
||||
|
||||
/**
|
||||
* @brief Get current memory usage.
|
||||
*
|
||||
* @param[out] buf_size Capacity of the buffer used for storing log messages.
|
||||
* @param[out] usage Number of bytes currently containing pending log messages.
|
||||
*
|
||||
* @retval -EINVAL if logging mode does not use the buffer.
|
||||
* @retval 0 successfully collected usage data.
|
||||
*/
|
||||
int log_mem_get_usage(uint32_t *buf_size, uint32_t *usage);
|
||||
|
||||
/**
|
||||
* @brief Get maximum memory usage.
|
||||
*
|
||||
* Requires CONFIG_LOG_MEM_UTILIZATION option.
|
||||
*
|
||||
* @param[out] max Maximum number of bytes used for pending log messages.
|
||||
*
|
||||
* @retval -EINVAL if logging mode does not use the buffer.
|
||||
* @retval -ENOTSUP if instrumentation is not enabled.
|
||||
* not been enabled.
|
||||
*
|
||||
* @retval 0 successfully collected usage data.
|
||||
*/
|
||||
int log_mem_get_max_usage(uint32_t *max);
|
||||
|
||||
#if defined(CONFIG_LOG) && !defined(CONFIG_LOG_MODE_MINIMAL)
|
||||
#define LOG_CORE_INIT() log_core_init()
|
||||
#define LOG_INIT() log_init()
|
||||
|
|
|
|||
|
|
@ -482,7 +482,12 @@ uint32_t log_msg_mem_get_used(void);
|
|||
*/
|
||||
uint32_t log_msg_mem_get_max_used(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get slab size
|
||||
*
|
||||
* @return Size of a slab used in slab pool for log messages.
|
||||
*/
|
||||
size_t log_msg_get_slab_size(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -53,4 +53,13 @@ config LOG2_FMT_SECTION
|
|||
removing strings from final binary and should be used for dictionary
|
||||
logging.
|
||||
|
||||
config LOG_MEM_UTILIZATION
|
||||
bool "Enable tracking maximum memory utilization"
|
||||
depends on LOG_MODE_DEFERRED
|
||||
default y if LOG_CMDS
|
||||
select MEM_SLAB_TRACE_MAX_UTILIZATION if LOG1
|
||||
help
|
||||
When enabled, maximum usage of memory used for log messages in deferred
|
||||
mode is tracked. It can be used to trim LOG_BUFFER_SIZE.
|
||||
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -404,26 +404,28 @@ static int cmd_log_strdup_utilization(const struct shell *shell,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_log_memory_slabs(const struct shell *sh, size_t argc, char **argv)
|
||||
static int cmd_log_mem(const struct shell *sh, size_t argc, char **argv)
|
||||
{
|
||||
uint32_t slabs_free;
|
||||
uint32_t size;
|
||||
uint32_t used;
|
||||
uint32_t max;
|
||||
int err;
|
||||
|
||||
slabs_free = log_msg_mem_get_free();
|
||||
used = log_msg_mem_get_used();
|
||||
|
||||
shell_print(sh, "Blocks used:\t%d", used);
|
||||
shell_print(sh, "Blocks free:\t%d", slabs_free);
|
||||
if (IS_ENABLED(CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION)) {
|
||||
max = log_msg_mem_get_max_used();
|
||||
shell_print(sh, "Blocks max:\t%d", max);
|
||||
} else {
|
||||
shell_print(
|
||||
sh,
|
||||
"Enable CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION to get max memory utilization");
|
||||
err = log_mem_get_usage(&size, &used);
|
||||
if (err < 0) {
|
||||
shell_error(sh, "Failed to get usage (mode does not support it?)");
|
||||
}
|
||||
|
||||
shell_print(sh, "Log message buffer utilization report:");
|
||||
shell_print(sh, "\tCapacity: %u bytes", size);
|
||||
shell_print(sh, "\tCurrently in use: %u bytes", used);
|
||||
err = log_mem_get_max_usage(&max);
|
||||
if (err < 0) {
|
||||
shell_print(sh, "Enable CONFIG_LOG_MEM_UTILIZATION to get maximum usage");
|
||||
}
|
||||
|
||||
shell_print(sh, "\tMaximum usage: %u bytes", max);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -479,7 +481,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
|
|||
"Get utilization of string duplicates pool", cmd_log_strdup_utilization,
|
||||
1, 0),
|
||||
SHELL_COND_CMD(CONFIG_LOG_MODE_DEFERRED, mem, NULL, "Logger memory usage",
|
||||
cmd_log_memory_slabs),
|
||||
cmd_log_mem),
|
||||
SHELL_SUBCMD_SET_END);
|
||||
|
||||
SHELL_CMD_REGISTER(log, &sub_log_stat, "Commands for controlling logger",
|
||||
|
|
|
|||
|
|
@ -105,8 +105,10 @@ static const struct mpsc_pbuf_buffer_config mpsc_config = {
|
|||
.size = ARRAY_SIZE(buf32),
|
||||
.notify_drop = notify_drop,
|
||||
.get_wlen = log_msg2_generic_get_wlen,
|
||||
.flags = IS_ENABLED(CONFIG_LOG_MODE_OVERFLOW) ?
|
||||
MPSC_PBUF_MODE_OVERWRITE : 0
|
||||
.flags = (IS_ENABLED(CONFIG_LOG_MODE_OVERFLOW) ?
|
||||
MPSC_PBUF_MODE_OVERWRITE : 0) |
|
||||
(IS_ENABLED(CONFIG_LOG_MEM_UTILIZATION) ?
|
||||
MPSC_PBUF_MAX_UTILIZATION : 0)
|
||||
};
|
||||
|
||||
/* Check that default tag can fit in tag buffer. */
|
||||
|
|
@ -1259,6 +1261,42 @@ int log_set_tag(const char *str)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int log_mem_get_usage(uint32_t *buf_size, uint32_t *usage)
|
||||
{
|
||||
__ASSERT_NO_MSG(buf_size != NULL);
|
||||
__ASSERT_NO_MSG(usage != NULL);
|
||||
|
||||
if (!IS_ENABLED(CONFIG_LOG_MODE_DEFERRED)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_LOG1)) {
|
||||
*buf_size = CONFIG_LOG_BUFFER_SIZE;
|
||||
*usage = log_msg_mem_get_used() * log_msg_get_slab_size();
|
||||
return 0;
|
||||
}
|
||||
|
||||
mpsc_pbuf_get_utilization(&log_buffer, buf_size, usage);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int log_mem_get_max_usage(uint32_t *max)
|
||||
{
|
||||
__ASSERT_NO_MSG(max != NULL);
|
||||
|
||||
if (!IS_ENABLED(CONFIG_LOG_MODE_DEFERRED)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_LOG1)) {
|
||||
*max = log_msg_mem_get_max_used() * log_msg_get_slab_size();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mpsc_pbuf_get_max_utilization(&log_buffer, max);
|
||||
}
|
||||
|
||||
static void log_process_thread_timer_expiry_fn(struct k_timer *timer)
|
||||
{
|
||||
k_sem_give(&log_process_thread_sem);
|
||||
|
|
|
|||
|
|
@ -498,3 +498,8 @@ uint32_t log_msg_mem_get_max_used(void)
|
|||
{
|
||||
return k_mem_slab_max_used_get(&log_msg_pool);
|
||||
}
|
||||
|
||||
size_t log_msg_get_slab_size(void)
|
||||
{
|
||||
return MSG_SIZE;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue