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.
This commit is contained in:
+15
-12
@@ -59,7 +59,7 @@
|
|||||||
#undef release_read_seqlock
|
#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
|
// These macros define the number of unsuccessful iterations in
|
||||||
// acquire_spinlock() and acquire_spinlock_nocheck() after which the functions
|
// 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);
|
"Dumps info on an ICI message.\n", 0);
|
||||||
|
|
||||||
if (args->num_cpus > 1) {
|
if (args->num_cpus > 1) {
|
||||||
sFreeMessages = NULL;
|
sNumCPUs = args->num_cpus;
|
||||||
sFreeMessageCount = 0;
|
|
||||||
for (int i = 0; i < MSG_POOL_SIZE; i++) {
|
struct smp_msg* messages;
|
||||||
struct smp_msg* msg
|
size_t size = ROUNDUP(sNumCPUs * MSG_ALLOCATE_PER_CPU * sizeof(smp_msg), B_PAGE_SIZE);
|
||||||
= (struct smp_msg*)malloc(sizeof(struct smp_msg));
|
area_id area = create_area("smp ici msgs", (void**)&messages, B_ANY_KERNEL_ADDRESS,
|
||||||
if (msg == NULL) {
|
size, B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
||||||
panic("error creating smp mailboxes\n");
|
if (area < 0) {
|
||||||
return B_ERROR;
|
panic("error creating smp msgs");
|
||||||
}
|
return area;
|
||||||
memset((void*)msg, 0, sizeof(struct smp_msg));
|
}
|
||||||
|
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;
|
msg->next = sFreeMessages;
|
||||||
sFreeMessages = msg;
|
sFreeMessages = msg;
|
||||||
sFreeMessageCount++;
|
sFreeMessageCount++;
|
||||||
}
|
}
|
||||||
sNumCPUs = args->num_cpus;
|
|
||||||
}
|
}
|
||||||
TRACE("smp_init: calling arch_smp_init\n");
|
TRACE("smp_init: calling arch_smp_init\n");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user