diff --git a/doc/reference/kernel/memory/slabs.rst b/doc/reference/kernel/memory/slabs.rst index a446353d8e3..ee18aadf5ef 100644 --- a/doc/reference/kernel/memory/slabs.rst +++ b/doc/reference/kernel/memory/slabs.rst @@ -139,7 +139,7 @@ Configuration Options Related configuration options: -* None +* :option:`CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION` API Reference ************* diff --git a/include/kernel.h b/include/kernel.h index ba03eefd653..cfa064edc7e 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -4260,6 +4260,9 @@ struct k_mem_slab { char *buffer; char *free_list; uint32_t num_used; +#ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION + uint32_t max_used; +#endif _OBJECT_TRACING_NEXT_PTR(k_mem_slab) _OBJECT_TRACING_LINKED_FLAG @@ -4388,6 +4391,26 @@ static inline uint32_t k_mem_slab_num_used_get(struct k_mem_slab *slab) return slab->num_used; } +/** + * @brief Get the number of maximum used blocks so far in a memory slab. + * + * This routine gets the maximum number of memory blocks that were + * allocated in @a slab. + * + * @param slab Address of the memory slab. + * + * @return Maximum number of allocated memory blocks. + */ +static inline uint32_t k_mem_slab_max_used_get(struct k_mem_slab *slab) +{ +#ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION + return slab->max_used; +#else + ARG_UNUSED(slab); + return 0; +#endif +} + /** * @brief Get the number of unused blocks in a memory slab. * diff --git a/kernel/Kconfig b/kernel/Kconfig index e39067d7010..f34211056bd 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -464,6 +464,12 @@ endmenu menu "Other Kernel Object Options" +config MEM_SLAB_TRACE_MAX_UTILIZATION + bool "Enable getting maximum slab utilization" + help + This adds variable to the k_mem_slab structure to hold + maximum utilization of the slab. + config NUM_MBOX_ASYNC_MSGS int "Maximum number of in-flight asynchronous mailbox messages" default 10 diff --git a/kernel/mem_slab.c b/kernel/mem_slab.c index f070939c1e1..767353587d6 100644 --- a/kernel/mem_slab.c +++ b/kernel/mem_slab.c @@ -88,6 +88,11 @@ int k_mem_slab_init(struct k_mem_slab *slab, void *buffer, slab->block_size = block_size; slab->buffer = buffer; slab->num_used = 0U; + +#ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION + slab->max_used = 0U; +#endif + rc = create_free_list(slab); if (rc < 0) { goto out; @@ -111,6 +116,11 @@ int k_mem_slab_alloc(struct k_mem_slab *slab, void **mem, k_timeout_t timeout) *mem = slab->free_list; slab->free_list = *(char **)(slab->free_list); slab->num_used++; + +#ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION + slab->max_used = MAX(slab->num_used, slab->max_used); +#endif + result = 0; } else if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { /* don't wait for a free block to become available */