From 85602e9ab83081475c0710ec04431dec920cc9b2 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 2 Oct 2025 10:57:05 -0700 Subject: [PATCH] kernel: mem_domain: keep track of threads only if needed Adds a new kconfig CONFIG_MEM_DOMAIN_HAS_THREAD_LIST so that only the architectures requiring to keep track of threads in memory domains will have the necessary list struct inside the memory domain structs. Saves a few bytes for those arch not needing this. Also rename the struct fields to be most descriptive of what they are. Signed-off-by: Daniel Leung --- arch/Kconfig | 1 + arch/arm64/core/cortex_r/arm_mpu.c | 4 ++-- include/zephyr/app_memory/mem_domain.h | 9 +++++++-- include/zephyr/kernel/thread.h | 4 +++- kernel/Kconfig.mem_domain | 9 +++++++++ kernel/mem_domain.c | 18 ++++++++++++++---- 6 files changed, 36 insertions(+), 9 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 7bcfb4d3ffd8d..4fca0c3c60262 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -57,6 +57,7 @@ config ARM64 select ARCH_HAS_DEMAND_MAPPING select ARCH_SUPPORTS_EVICTION_TRACKING select EVICTION_TRACKING if DEMAND_PAGING + select MEM_DOMAIN_HAS_THREAD_LIST if ARM_MPU help ARM64 (AArch64) architecture diff --git a/arch/arm64/core/cortex_r/arm_mpu.c b/arch/arm64/core/cortex_r/arm_mpu.c index 3053d90cb75f6..69fc72acda35a 100644 --- a/arch/arm64/core/cortex_r/arm_mpu.c +++ b/arch/arm64/core/cortex_r/arm_mpu.c @@ -760,8 +760,8 @@ static int configure_domain_partitions(struct k_mem_domain *domain) struct k_thread *thread; int ret; - SYS_DLIST_FOR_EACH_CONTAINER(&domain->mem_domain_q, thread, - mem_domain_info.mem_domain_q_node) { + SYS_DLIST_FOR_EACH_CONTAINER(&domain->thread_mem_domain_list, thread, + mem_domain_info.thread_mem_domain_node) { ret = configure_dynamic_mpu_regions(thread); if (ret != 0) { return ret; diff --git a/include/zephyr/app_memory/mem_domain.h b/include/zephyr/app_memory/mem_domain.h index 1b97ab4d333ff..977d6b2aaec12 100644 --- a/include/zephyr/app_memory/mem_domain.h +++ b/include/zephyr/app_memory/mem_domain.h @@ -83,8 +83,13 @@ struct k_mem_domain { #endif /* CONFIG_ARCH_MEM_DOMAIN_DATA */ /** partitions in the domain */ struct k_mem_partition partitions[CONFIG_MAX_DOMAIN_PARTITIONS]; - /** Doubly linked list of member threads */ - sys_dlist_t mem_domain_q; +#ifdef CONFIG_MEM_DOMAIN_HAS_THREAD_LIST + /** Doubly linked list of member threads, + * pointer to the thread_mem_domain_node inside + * each thread's memory domain info struct. + */ + sys_dlist_t thread_mem_domain_list; +#endif /* CONFIG_MEM_DOMAIN_HAS_THREAD_LIST */ /** number of active partitions in the domain */ uint8_t num_partitions; }; diff --git a/include/zephyr/kernel/thread.h b/include/zephyr/kernel/thread.h index 43721f1249534..db7713d6d407d 100644 --- a/include/zephyr/kernel/thread.h +++ b/include/zephyr/kernel/thread.h @@ -178,8 +178,10 @@ typedef struct _thread_stack_info _thread_stack_info_t; #if defined(CONFIG_USERSPACE) struct _mem_domain_info { +#ifdef CONFIG_MEM_DOMAIN_HAS_THREAD_LIST /** memory domain queue node */ - sys_dnode_t mem_domain_q_node; + sys_dnode_t thread_mem_domain_node; +#endif /* CONFIG_MEM_DOMAIN_HAS_THREAD_LIST */ /** memory domain of the thread */ struct k_mem_domain *mem_domain; }; diff --git a/kernel/Kconfig.mem_domain b/kernel/Kconfig.mem_domain index ddf8a4cc57a6d..03d6e1239261c 100644 --- a/kernel/Kconfig.mem_domain +++ b/kernel/Kconfig.mem_domain @@ -76,4 +76,13 @@ config MEM_DOMAIN_ISOLATED_STACKS Regardless of this settings, threads cannot access the stacks of threads outside of their domains. +config MEM_DOMAIN_HAS_THREAD_LIST + bool + help + If enabled, there is a doubly linked list in each memory domain + struct to keep track of the threads associated with this + particular memory domain. + + This is selected by architecture needing this to function. + endmenu diff --git a/kernel/mem_domain.c b/kernel/mem_domain.c index 16b337acf011d..dc1cfe01126a1 100644 --- a/kernel/mem_domain.c +++ b/kernel/mem_domain.c @@ -113,7 +113,10 @@ int k_mem_domain_init(struct k_mem_domain *domain, uint8_t num_parts, domain->num_partitions = 0U; (void)memset(domain->partitions, 0, sizeof(domain->partitions)); - sys_dlist_init(&domain->mem_domain_q); + +#ifdef CONFIG_MEM_DOMAIN_HAS_THREAD_LIST + sys_dlist_init(&domain->thread_mem_domain_list); +#endif /* CONFIG_MEM_DOMAIN_HAS_THREAD_LIST */ #ifdef CONFIG_ARCH_MEM_DOMAIN_DATA ret = arch_mem_domain_init(domain); @@ -265,8 +268,12 @@ static int add_thread_locked(struct k_mem_domain *domain, __ASSERT_NO_MSG(thread != NULL); LOG_DBG("add thread %p to domain %p\n", thread, domain); - sys_dlist_append(&domain->mem_domain_q, - &thread->mem_domain_info.mem_domain_q_node); + +#ifdef CONFIG_MEM_DOMAIN_HAS_THREAD_LIST + sys_dlist_append(&domain->thread_mem_domain_list, + &thread->mem_domain_info.thread_mem_domain_node); +#endif /* CONFIG_MEM_DOMAIN_HAS_THREAD_LIST */ + thread->mem_domain_info.mem_domain = domain; #ifdef CONFIG_ARCH_MEM_DOMAIN_SYNCHRONOUS_API @@ -283,7 +290,10 @@ static int remove_thread_locked(struct k_thread *thread) __ASSERT_NO_MSG(thread != NULL); LOG_DBG("remove thread %p from memory domain %p\n", thread, thread->mem_domain_info.mem_domain); - sys_dlist_remove(&thread->mem_domain_info.mem_domain_q_node); + +#ifdef CONFIG_MEM_DOMAIN_HAS_THREAD_LIST + sys_dlist_remove(&thread->mem_domain_info.thread_mem_domain_node); +#endif /* CONFIG_MEM_DOMAIN_HAS_THREAD_LIST */ #ifdef CONFIG_ARCH_MEM_DOMAIN_SYNCHRONOUS_API ret = arch_mem_domain_thread_remove(thread);