diff options
author | Andrew Turner <andrew@FreeBSD.org> | 2023-06-02 16:12:24 +0000 |
---|---|---|
committer | Andrew Turner <andrew@FreeBSD.org> | 2023-06-08 16:10:10 +0000 |
commit | d057b7aac8aedd353f2cb047cb0069f6a4db7a83 (patch) | |
tree | 0c673991a45404d50fa8e60d28d62a99188ea69a /sys/arm64 | |
parent | 732786a25fd7e9b48b1d64f51c41c80129e37563 (diff) | |
download | src-d057b7aac8aedd353f2cb047cb0069f6a4db7a83.tar.gz src-d057b7aac8aedd353f2cb047cb0069f6a4db7a83.zip |
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 <zachary.leaf@arm.com>
Sponsored by: Arm Ltd
Differential Revision: https://reviews.freebsd.org/D40433
Diffstat (limited to 'sys/arm64')
-rw-r--r-- | sys/arm64/arm64/identcpu.c | 43 | ||||
-rw-r--r-- | sys/arm64/arm64/mp_machdep.c | 2 | ||||
-rw-r--r-- | 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)))) |