The branch main has been updated by andrew:

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

commit d057b7aac8aedd353f2cb047cb0069f6a4db7a83
Author:     Andrew Turner <[email protected]>
AuthorDate: 2023-06-02 16:12:24 +0000
Commit:     Andrew Turner <[email protected]>
CommitDate: 2023-06-08 16:10:10 +0000

    arm64: Malloc the cpu_desc array
    
    We only need this during boot. Allocate the array before starting CPUs
    to reduce the memory usage.
    
    Reviewed by:    Zach Leaf <[email protected]>
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D40433
---
 sys/arm64/arm64/identcpu.c   | 43 ++++++++++++++++++++++++++++++++++++++-----
 sys/arm64/arm64/mp_machdep.c |  2 ++
 sys/arm64/include/cpu.h      |  2 ++
 3 files changed, 42 insertions(+), 5 deletions(-)

diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c
index fb1c4537f216..86b669ea2f56 100644
--- a/sys/arm64/arm64/identcpu.c
+++ b/sys/arm64/arm64/identcpu.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
+#include <sys/malloc.h>
 #include <sys/pcpu.h>
 #include <sys/sbuf.h>
 #include <sys/smp.h>
@@ -47,6 +48,8 @@ __FBSDID("$FreeBSD$");
 #include <machine/md_var.h>
 #include <machine/undefined.h>
 
+static MALLOC_DEFINE(M_IDENTCPU, "CPU ID", "arm64 CPU identification memory");
+
 struct cpu_desc;
 
 static void print_cpu_midr(struct sbuf *sb, u_int cpu);
@@ -150,10 +153,22 @@ struct cpu_desc {
        bool            have_sve;
 };
 
-static struct cpu_desc cpu_desc[MAXCPU];
+static struct cpu_desc cpu_desc0;
+static struct cpu_desc *cpu_desc;
 static struct cpu_desc kern_cpu_desc;
 static struct cpu_desc user_cpu_desc;
 
+static struct cpu_desc *
+get_cpu_desc(u_int cpu)
+{
+       /* The cpu_desc for CPU 0 is used before the allocator is ready. */
+       if (cpu == 0)
+               return (&cpu_desc0);
+
+       MPASS(cpu_desc != NULL);
+       return (&cpu_desc[cpu - 1]);
+}
+
 struct cpu_parts {
        u_int           part_id;
        const char      *part_name;
@@ -1803,7 +1818,7 @@ update_special_regs(u_int cpu)
                user_cpu_desc.id_aa64dfr0 = ID_AA64DFR0_DebugVer_8;
        }
 
-       desc = &cpu_desc[cpu];
+       desc = get_cpu_desc(cpu);
        for (i = 0; i < nitems(user_regs); i++) {
                value = CPU_DESC_FIELD(*desc, i);
                if (cpu == 0) {
@@ -1839,6 +1854,22 @@ update_special_regs(u_int cpu)
        }
 }
 
+void
+cpu_desc_init(void)
+{
+       if (mp_ncpus == 1)
+               return;
+
+       /*
+        * Allocate memory for the non-boot CPUs to store their registers.
+        * As this is indexed by CPU ID we need to allocate space for CPUs
+        * 1 to mp_maxid. Because of this mp_maxid is already the correct
+        * number of elements.
+        */
+       cpu_desc = mallocarray(mp_maxid, sizeof(*cpu_desc), M_IDENTCPU,
+           M_ZERO | M_WAITOK);
+}
+
 /* HWCAP */
 bool __read_frequently lse_supported = false;
 
@@ -1896,7 +1927,7 @@ identify_cpu_sysinit(void *dummy __unused)
 
        prev_desc = NULL;
        CPU_FOREACH(cpu) {
-               desc = &cpu_desc[cpu];
+               desc = get_cpu_desc(cpu);
                if (cpu != 0) {
                        check_cpu_regs(cpu, desc, prev_desc);
                        update_special_regs(cpu);
@@ -1950,7 +1981,7 @@ cpu_features_sysinit(void *dummy __unused)
 
        prev_desc = NULL;
        CPU_FOREACH(cpu) {
-               desc = &cpu_desc[cpu];
+               desc = get_cpu_desc(cpu);
                print_cpu_features(cpu, desc, prev_desc);
                prev_desc = desc;
        }
@@ -1961,6 +1992,8 @@ cpu_features_sysinit(void *dummy __unused)
 
        sbuf_finish(&sb);
        sbuf_delete(&sb);
+
+       free(cpu_desc, M_IDENTCPU);
 }
 /* Log features before APs are released and start printing to the dmesg. */
 SYSINIT(cpu_features, SI_SUB_SMP - 1, SI_ORDER_ANY, cpu_features_sysinit, 
NULL);
@@ -2390,7 +2423,7 @@ identify_cpu(u_int cpu)
        struct cpu_desc *desc;
        uint64_t clidr;
 
-       desc = &cpu_desc[cpu];
+       desc = get_cpu_desc(cpu);
        /* Save affinity for current CPU */
        desc->mpidr = get_mpidr();
        CPU_AFFINITY(cpu) = desc->mpidr & CPU_AFF_MASK;
diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c
index 9dd1182e5721..babeee331be0 100644
--- a/sys/arm64/arm64/mp_machdep.c
+++ b/sys/arm64/arm64/mp_machdep.c
@@ -779,6 +779,8 @@ cpu_mp_start(void)
        mpidr = READ_SPECIALREG(mpidr_el1) & CPU_AFF_MASK;
        cpuid_to_pcpu[0]->pc_mpidr = mpidr;
 
+       cpu_desc_init();
+
        switch(arm64_bus_method) {
 #ifdef DEV_ACPI
        case ARM64_BUS_ACPI:
diff --git a/sys/arm64/include/cpu.h b/sys/arm64/include/cpu.h
index 88a9ac18080b..1ea497756698 100644
--- a/sys/arm64/include/cpu.h
+++ b/sys/arm64/include/cpu.h
@@ -214,6 +214,8 @@ void        update_special_regs(u_int);
 bool   extract_user_id_field(u_int, u_int, uint8_t *);
 bool   get_kernel_reg(u_int, uint64_t *);
 
+void   cpu_desc_init(void);
+
 #define        CPU_AFFINITY(cpu)       __cpu_affinity[(cpu)]
 #define        CPU_CURRENT_SOCKET                              \
     (CPU_AFF2(CPU_AFFINITY(PCPU_GET(cpuid))))

Reply via email to