From nobody Wed Dec 17 12:10:53 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E3E5318BBA2; Tue, 12 Nov 2024 06:36:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731393362; cv=none; b=fOlF9rWzinmEa4pBMir9oQDqM2aM0yymyKcD9I83DFkGpPbhEZ/fBW2sBE3tu67NdaZwPBQc5wf2U0lfzAYe05qYYFecDlWV6UjziSe01Qsno4FqyTf7n5AR9uwT5unf+IsD57Y7G5VEUIMFnKfhi6kHFfLNYvnDtzbgZYtx+V0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731393362; c=relaxed/simple; bh=+Lb/mifrNg/smRm/Odip625EHRUZkjx9ViFBn6wuARY=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=nGma80tCl/WiAlMf5KmQZI1EMXfD9NfUvd+7IXdA2RFmEEOsu6k6zVKFgrcfZO7j00yVaKnRHaZ946pUyXULcU1vI26xGs67qLNrNIIXHwpDCFnSs3B9QxPLDib7aiWibThw9T1ubcGc6YyKhWiN5LULspKIkZC8Dmuvwy5z++w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 025FEC4CECD; Tue, 12 Nov 2024 06:35:58 +0000 (UTC) From: Huacai Chen To: Huacai Chen Cc: loongarch@lists.linux.dev, Xuefeng Li , Guo Ren , Xuerui Wang , Jiaxun Yang , linux-kernel@vger.kernel.org, loongson-kernel@lists.loongnix.cn, Huacai Chen , Bibo Mao Subject: [PATCH] LoongArch: For all possible CPUs setup logical-physical CPU mapping Date: Tue, 12 Nov 2024 14:35:40 +0800 Message-ID: <20241112063540.1135079-1-chenhuacai@loongson.cn> X-Mailer: git-send-email 2.43.5 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In order to support ACPI-based physical CPU hotplug, we suppose for all "possible" CPUs cpu_logical_map() can work. Because some drivers want to use cpu_logical_map() for all "possible" CPUs, while currently we only setup logical-physical mapping for "present" CPUs. This lack of mapping also causes cpu_to_node() cannot work for hot-added CPUs. All "possible" CPUs are listed in MADT, and the "present" subset is marked as ACPI_MADT_ENABLED. To setup logical-physical CPU mapping for all possible CPUs and keep present CPUs continuous in cpu_present_mask, we parse MADT twice. The first pass handles CPUs with ACPI_MADT_ENABLED and the second pass handles CPUs without ACPI_MADT_ENABLED. The global flag (cpu_enumerated) is removed because acpi_map_cpu() calls cpu_number_map() rather than set_processor_mask() now. Reported-by: Bibo Mao Signed-off-by: Huacai Chen --- arch/loongarch/kernel/acpi.c | 81 +++++++++++++++++++++++------------- arch/loongarch/kernel/smp.c | 3 +- 2 files changed, 55 insertions(+), 29 deletions(-) diff --git a/arch/loongarch/kernel/acpi.c b/arch/loongarch/kernel/acpi.c index f1a74b80f22c..382a09a7152c 100644 --- a/arch/loongarch/kernel/acpi.c +++ b/arch/loongarch/kernel/acpi.c @@ -58,48 +58,48 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phy= s, acpi_size size) return ioremap_cache(phys, size); } =20 -static int cpu_enumerated =3D 0; - #ifdef CONFIG_SMP -static int set_processor_mask(u32 id, u32 flags) +static int set_processor_mask(u32 id, u32 pass) { - int nr_cpus; - int cpu, cpuid =3D id; - - if (!cpu_enumerated) - nr_cpus =3D NR_CPUS; - else - nr_cpus =3D nr_cpu_ids; + int cpu =3D -1, cpuid =3D id; =20 - if (num_processors >=3D nr_cpus) { + if (num_processors >=3D NR_CPUS) { pr_warn(PREFIX "nr_cpus limit of %i reached." - " processor 0x%x ignored.\n", nr_cpus, cpuid); + " processor 0x%x ignored.\n", NR_CPUS, cpuid); =20 return -ENODEV; =20 } + if (cpuid =3D=3D loongson_sysconf.boot_cpu_id) cpu =3D 0; - else - cpu =3D find_first_zero_bit(cpumask_bits(cpu_present_mask), NR_CPUS); - - if (!cpu_enumerated) - set_cpu_possible(cpu, true); =20 - if (flags & ACPI_MADT_ENABLED) { + switch (pass) { + case 1: /* Pass 1 handle enabled processors */ + if (cpu < 0) + cpu =3D find_first_zero_bit(cpumask_bits(cpu_present_mask), NR_CPUS); num_processors++; set_cpu_present(cpu, true); - __cpu_number_map[cpuid] =3D cpu; - __cpu_logical_map[cpu] =3D cpuid; - } else + break; + case 2: /* Pass 2 handle disabled processors */ + if (cpu < 0) + cpu =3D find_first_zero_bit(cpumask_bits(cpu_possible_mask), NR_CPUS); disabled_cpus++; + break; + default: + return cpu; + } + + set_cpu_possible(cpu, true); + __cpu_number_map[cpuid] =3D cpu; + __cpu_logical_map[cpu] =3D cpuid; =20 return cpu; } #endif =20 static int __init -acpi_parse_processor(union acpi_subtable_headers *header, const unsigned l= ong end) +acpi_parse_p1_processor(union acpi_subtable_headers *header, const unsigne= d long end) { struct acpi_madt_core_pic *processor =3D NULL; =20 @@ -110,12 +110,29 @@ acpi_parse_processor(union acpi_subtable_headers *hea= der, const unsigned long en acpi_table_print_madt_entry(&header->common); #ifdef CONFIG_SMP acpi_core_pic[processor->core_id] =3D *processor; - set_processor_mask(processor->core_id, processor->flags); + if (processor->flags & ACPI_MADT_ENABLED) + set_processor_mask(processor->core_id, 1); #endif =20 return 0; } =20 +static int __init +acpi_parse_p2_processor(union acpi_subtable_headers *header, const unsigne= d long end) +{ + struct acpi_madt_core_pic *processor =3D NULL; + + processor =3D (struct acpi_madt_core_pic *)header; + if (BAD_MADT_ENTRY(processor, end)) + return -EINVAL; + +#ifdef CONFIG_SMP + if (!(processor->flags & ACPI_MADT_ENABLED)) + set_processor_mask(processor->core_id, 2); +#endif + + return 0; +} static int __init acpi_parse_eio_master(union acpi_subtable_headers *header, const unsigned = long end) { @@ -143,12 +160,14 @@ static void __init acpi_process_madt(void) } #endif acpi_table_parse_madt(ACPI_MADT_TYPE_CORE_PIC, - acpi_parse_processor, MAX_CORE_PIC); + acpi_parse_p1_processor, MAX_CORE_PIC); + + acpi_table_parse_madt(ACPI_MADT_TYPE_CORE_PIC, + acpi_parse_p2_processor, MAX_CORE_PIC); =20 acpi_table_parse_madt(ACPI_MADT_TYPE_EIO_PIC, acpi_parse_eio_master, MAX_IO_PICS); =20 - cpu_enumerated =3D 1; loongson_sysconf.nr_cpus =3D num_processors; } =20 @@ -310,6 +329,10 @@ static int __ref acpi_map_cpu2node(acpi_handle handle,= int cpu, int physid) int nid; =20 nid =3D acpi_get_node(handle); + + if (nid !=3D NUMA_NO_NODE) + nid =3D early_cpu_to_node(cpu); + if (nid !=3D NUMA_NO_NODE) { set_cpuid_to_node(physid, nid); node_set(nid, numa_nodes_parsed); @@ -324,12 +347,14 @@ int acpi_map_cpu(acpi_handle handle, phys_cpuid_t phy= sid, u32 acpi_id, int *pcpu { int cpu; =20 - cpu =3D set_processor_mask(physid, ACPI_MADT_ENABLED); - if (cpu < 0) { + cpu =3D cpu_number_map(physid); + if (cpu < 0 || cpu >=3D nr_cpu_ids) { pr_info(PREFIX "Unable to map lapic to logical cpu number\n"); - return cpu; + return -ERANGE; } =20 + num_processors++; + set_cpu_present(cpu, true); acpi_map_cpu2node(handle, cpu, physid); =20 *pcpu =3D cpu; diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c index 9afc2d8b3414..c0b498467ffa 100644 --- a/arch/loongarch/kernel/smp.c +++ b/arch/loongarch/kernel/smp.c @@ -331,11 +331,11 @@ void __init loongson_prepare_cpus(unsigned int max_cp= us) int i =3D 0; =20 parse_acpi_topology(); + cpu_data[0].global_id =3D cpu_logical_map(0); =20 for (i =3D 0; i < loongson_sysconf.nr_cpus; i++) { set_cpu_present(i, true); csr_mail_send(0, __cpu_logical_map[i], 0); - cpu_data[i].global_id =3D __cpu_logical_map[i]; } =20 per_cpu(cpu_state, smp_processor_id()) =3D CPU_ONLINE; @@ -380,6 +380,7 @@ void loongson_init_secondary(void) cpu_logical_map(cpu) / loongson_sysconf.cores_per_package; cpu_data[cpu].core =3D pptt_enabled ? cpu_data[cpu].core : cpu_logical_map(cpu) % loongson_sysconf.cores_per_package; + cpu_data[cpu].global_id =3D cpu_logical_map(cpu); } =20 void loongson_smp_finish(void) --=20 2.43.5