Commit 9559d580 authored by Huacai Chen's avatar Huacai Chen
Browse files

LoongArch: Increase max supported CPUs up to 2048



Increase max supported CPUs up to 2048, including:
1. Increase CSR.CPUID register's effective width;
2. Define MAX_CORE_PIC (a.k.a. max physical ID) to 2048;
3. Allow NR_CPUS (a.k.a. max logical ID) to be as large as 2048;
4. Introduce acpi_numa_x2apic_affinity_init() to handle ACPI SRAT
   for CPUID >= 256.

Note: The reason of increasing to 2048 rather than 4096/8192 is because
      the IPI hardware can only support 2048 as a maximum.

Reviewed-by: default avatarYanteng Si <si.yanteng@linux.dev>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent a45728fd
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -496,10 +496,10 @@ config HOTPLUG_CPU
	  Say N if you want to disable CPU hotplug.

config NR_CPUS
	int "Maximum number of CPUs (2-256)"
	range 2 256
	int "Maximum number of CPUs (2-2048)"
	range 2 2048
	default "2048"
	depends on SMP
	default "64"
	help
	  This allows you to specify the maximum number of CPUs which this
	  kernel will support.
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ static inline bool acpi_has_cpu_in_madt(void)
	return true;
}

#define MAX_CORE_PIC 256
#define MAX_CORE_PIC 2048

extern struct list_head acpi_wakeup_device_list;
extern struct acpi_madt_core_pic acpi_core_pic[MAX_CORE_PIC];
+2 −2
Original line number Diff line number Diff line
@@ -411,8 +411,8 @@

/* Config CSR registers */
#define LOONGARCH_CSR_CPUID		0x20	/* CPU core id */
#define  CSR_CPUID_COREID_WIDTH		9
#define  CSR_CPUID_COREID		_ULCAST_(0x1ff)
#define  CSR_CPUID_COREID_WIDTH		11
#define  CSR_CPUID_COREID		_ULCAST_(0x7ff)

#define LOONGARCH_CSR_PRCFG1		0x21	/* Config1 */
#define  CSR_CONF1_VSMAX_SHIFT		12
+35 −6
Original line number Diff line number Diff line
@@ -244,11 +244,6 @@ void __init acpi_boot_table_init(void)

#ifdef CONFIG_ACPI_NUMA

static __init int setup_node(int pxm)
{
	return acpi_map_pxm_to_node(pxm);
}

void __init numa_set_distance(int from, int to, int distance)
{
	if ((u8)distance != distance || (from == to && distance != LOCAL_DISTANCE)) {
@@ -280,7 +275,41 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
		pxm |= (pa->proximity_domain_hi[1] << 16);
		pxm |= (pa->proximity_domain_hi[2] << 24);
	}
	node = setup_node(pxm);
	node = acpi_map_pxm_to_node(pxm);
	if (node < 0) {
		pr_err("SRAT: Too many proximity domains %x\n", pxm);
		bad_srat();
		return;
	}

	if (pa->apic_id >= CONFIG_NR_CPUS) {
		pr_info("SRAT: PXM %u -> CPU 0x%02x -> Node %u skipped apicid that is too big\n",
				pxm, pa->apic_id, node);
		return;
	}

	early_numa_add_cpu(pa->apic_id, node);

	set_cpuid_to_node(pa->apic_id, node);
	node_set(node, numa_nodes_parsed);
	pr_info("SRAT: PXM %u -> CPU 0x%02x -> Node %u\n", pxm, pa->apic_id, node);
}

void __init
acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
{
	int pxm, node;

	if (srat_disabled())
		return;
	if (pa->header.length < sizeof(struct acpi_srat_x2apic_cpu_affinity)) {
		bad_srat();
		return;
	}
	if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0)
		return;
	pxm = pa->proximity_domain;
	node = acpi_map_pxm_to_node(pxm);
	if (node < 0) {
		pr_err("SRAT: Too many proximity domains %x\n", pxm);
		bad_srat();