git: 9801e7c275f6 - main - smp_topo: dynamically allocate group array

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Tue, 09 May 2023 15:30:15 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=9801e7c275f6ec42a44b98a2e2e1a8ac4674a096

commit 9801e7c275f6ec42a44b98a2e2e1a8ac4674a096
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2023-05-05 20:24:22 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-05-09 15:30:07 +0000

    smp_topo: dynamically allocate group array
    
    Limit its size to mp_maxid + 1 times MAX_CACHE_LEVELS instead MAXCPU.
    Allocate the array on a first call into smp_topo(9) functions, where
    the mp_maxid is already known.
    
    Make the array private to smp_topo_alloc(), assuming that the callers
    that allocate top-level group do it once.
    
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D39981
---
 sys/kern/subr_smp.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c
index 745b1554371e..df82d948afb0 100644
--- a/sys/kern/subr_smp.c
+++ b/sys/kern/subr_smp.c
@@ -630,8 +630,6 @@ smp_rendezvous(void (* setup_func)(void *),
 	smp_rendezvous_cpus(all_cpus, setup_func, action_func, teardown_func, arg);
 }
 
-static struct cpu_group group[MAXCPU * MAX_CACHE_LEVELS + 1];
-
 static void
 smp_topo_fill(struct cpu_group *cg)
 {
@@ -713,9 +711,14 @@ smp_topo(void)
 struct cpu_group *
 smp_topo_alloc(u_int count)
 {
+	static struct cpu_group *group = NULL;
 	static u_int index;
 	u_int curr;
 
+	if (group == NULL) {
+		group = mallocarray((mp_maxid + 1) * MAX_CACHE_LEVELS + 1,
+		    sizeof(*group), M_DEVBUF, M_WAITOK | M_ZERO);
+	}
 	curr = index;
 	index += count;
 	return (&group[curr]);
@@ -726,7 +729,7 @@ smp_topo_none(void)
 {
 	struct cpu_group *top;
 
-	top = &group[0];
+	top = smp_topo_alloc(1);
 	top->cg_parent = NULL;
 	top->cg_child = NULL;
 	top->cg_mask = all_cpus;
@@ -780,9 +783,9 @@ smp_topo_1level(int share, int count, int flags)
 	int i;
 
 	cpu = 0;
-	top = &group[0];
+	top = smp_topo_alloc(1);
 	packages = mp_ncpus / count;
-	top->cg_child = child = &group[1];
+	top->cg_child = child = top + 1;
 	top->cg_level = CG_SHARE_NONE;
 	for (i = 0; i < packages; i++, child++)
 		cpu = smp_topo_addleaf(top, child, share, count, flags, cpu);
@@ -801,8 +804,8 @@ smp_topo_2level(int l2share, int l2count, int l1share, int l1count,
 	int j;
 
 	cpu = 0;
-	top = &group[0];
-	l2g = &group[1];
+	top = smp_topo_alloc(1);
+	l2g = top + 1;
 	top->cg_child = l2g;
 	top->cg_level = CG_SHARE_NONE;
 	top->cg_children = mp_ncpus / (l2count * l1count);