From dfc2bbcd3c3d2ba22f50ce494bd6fd30b4e183b4 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Sun, 16 Jun 2019 09:22:21 -0400 Subject: [PATCH] kernel: mem_slab: error handling Add runtime error checking for k_mem_slab_init and replace asserts with returning error codes. Signed-off-by: Anas Nashif --- include/kernel.h | 7 +++++-- kernel/mem_slab.c | 33 +++++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/include/kernel.h b/include/kernel.h index 4272e15578f..4e451259bd8 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -4333,10 +4333,12 @@ struct k_mem_slab { * @param block_size Size of each memory block (in bytes). * @param num_blocks Number of memory blocks. * - * @return N/A + * @retval 0 on success + * @retval -EINVAL invalid data supplied + * * @req K-MSLAB-002 */ -extern void k_mem_slab_init(struct k_mem_slab *slab, void *buffer, +extern int k_mem_slab_init(struct k_mem_slab *slab, void *buffer, size_t block_size, u32_t num_blocks); /** @@ -4354,6 +4356,7 @@ extern void k_mem_slab_init(struct k_mem_slab *slab, void *buffer, * is set to the starting address of the memory block. * @retval -ENOMEM Returned without waiting. * @retval -EAGAIN Waiting period timed out. + * @retval -EINVAL Invalid data supplied * @req K-MSLAB-002 */ extern int k_mem_slab_alloc(struct k_mem_slab *slab, void **mem, diff --git a/kernel/mem_slab.c b/kernel/mem_slab.c index f22a04f8ca0..df83d6402f5 100644 --- a/kernel/mem_slab.c +++ b/kernel/mem_slab.c @@ -13,6 +13,7 @@ #include #include #include +#include static struct k_spinlock lock; @@ -28,15 +29,16 @@ struct k_mem_slab *_trace_list_k_mem_slab; * * @return N/A */ -static void create_free_list(struct k_mem_slab *slab) +static int create_free_list(struct k_mem_slab *slab) { u32_t j; char *p; /* blocks must be word aligned */ - __ASSERT(((slab->block_size | (uintptr_t)slab->buffer) - & (sizeof(void *) - 1)) == 0, - "slab at %p not word aligned", slab); + CHECKIF(((slab->block_size | (uintptr_t)slab->buffer) & + (sizeof(void *) - 1)) != 0) { + return -EINVAL; + } slab->free_list = NULL; p = slab->buffer; @@ -46,6 +48,7 @@ static void create_free_list(struct k_mem_slab *slab) slab->free_list = p; p += slab->block_size; } + return 0; } /** @@ -57,31 +60,45 @@ static void create_free_list(struct k_mem_slab *slab) */ static int init_mem_slab_module(struct device *dev) { + int rc = 0; ARG_UNUSED(dev); Z_STRUCT_SECTION_FOREACH(k_mem_slab, slab) { - create_free_list(slab); + rc = create_free_list(slab); + if (rc < 0) { + goto out; + } SYS_TRACING_OBJ_INIT(k_mem_slab, slab); z_object_init(slab); } - return 0; + +out: + return rc; } SYS_INIT(init_mem_slab_module, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); -void k_mem_slab_init(struct k_mem_slab *slab, void *buffer, +int k_mem_slab_init(struct k_mem_slab *slab, void *buffer, size_t block_size, u32_t num_blocks) { + int rc = 0; + slab->num_blocks = num_blocks; slab->block_size = block_size; slab->buffer = buffer; slab->num_used = 0U; - create_free_list(slab); + rc = create_free_list(slab); + if (rc < 0) { + goto out; + } z_waitq_init(&slab->wait_q); SYS_TRACING_OBJ_INIT(k_mem_slab, slab); z_object_init(slab); + +out: + return rc; } int k_mem_slab_alloc(struct k_mem_slab *slab, void **mem, s32_t timeout)