From b350405e06e5f6f395970acf67363b3a66f854b9 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Tue, 10 Mar 2026 13:01:12 -0400 Subject: [PATCH] kernel/smp: Refactor smp_msg structure allocation. The SMP_MAX_CPUS * 4 fixed pool size apparently goes all the way back to NewOS, which supported only 4 CPUs max. As ours is now 64, this means the fixed pool size was very large even on systems with only a few cores. So, instead, allocate 4 messages per CPU (though often more, due to rounding up to the page size; e.g. on x86_64, 1 page fits 56 smp_msgs.) Also, put them a dedicated area, to keep them a bit more segmented from the kernel heap, in case of problems. --- src/system/kernel/smp.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/system/kernel/smp.cpp b/src/system/kernel/smp.cpp index b197f396a1..f54e25027e 100644 --- a/src/system/kernel/smp.cpp +++ b/src/system/kernel/smp.cpp @@ -59,7 +59,7 @@ #undef release_read_seqlock -#define MSG_POOL_SIZE (SMP_MAX_CPUS * 4) +#define MSG_ALLOCATE_PER_CPU (4) // These macros define the number of unsuccessful iterations in // acquire_spinlock() and acquire_spinlock_nocheck() after which the functions @@ -1323,21 +1323,24 @@ smp_init(kernel_args* args) "Dumps info on an ICI message.\n", 0); if (args->num_cpus > 1) { - sFreeMessages = NULL; - sFreeMessageCount = 0; - for (int i = 0; i < MSG_POOL_SIZE; i++) { - struct smp_msg* msg - = (struct smp_msg*)malloc(sizeof(struct smp_msg)); - if (msg == NULL) { - panic("error creating smp mailboxes\n"); - return B_ERROR; - } - memset((void*)msg, 0, sizeof(struct smp_msg)); + sNumCPUs = args->num_cpus; + + struct smp_msg* messages; + size_t size = ROUNDUP(sNumCPUs * MSG_ALLOCATE_PER_CPU * sizeof(smp_msg), B_PAGE_SIZE); + area_id area = create_area("smp ici msgs", (void**)&messages, B_ANY_KERNEL_ADDRESS, + size, B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); + if (area < 0) { + panic("error creating smp msgs"); + return area; + } + memset((void*)messages, 0, size); + + for (size_t i = 0; i < (size / sizeof(smp_msg)); i++) { + struct smp_msg* msg = &messages[i]; msg->next = sFreeMessages; sFreeMessages = msg; sFreeMessageCount++; } - sNumCPUs = args->num_cpus; } TRACE("smp_init: calling arch_smp_init\n");