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
This commit is contained in:
Andrew Turner 2023-06-02 17:12:24 +01:00
parent 732786a25f
commit d057b7aac8
3 changed files with 42 additions and 5 deletions

View file

@ -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;

View file

@ -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:

View file

@ -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))))