aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2023-06-02 16:12:24 +0000
committerAndrew Turner <andrew@FreeBSD.org>2023-06-08 16:10:10 +0000
commitd057b7aac8aedd353f2cb047cb0069f6a4db7a83 (patch)
tree0c673991a45404d50fa8e60d28d62a99188ea69a
parent732786a25fd7e9b48b1d64f51c41c80129e37563 (diff)
downloadsrc-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
-rw-r--r--sys/arm64/arm64/identcpu.c43
-rw-r--r--sys/arm64/arm64/mp_machdep.c2
-rw-r--r--sys/arm64/include/cpu.h2
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))))