Skip to content

Commit a6654a4

Browse files
committed
LoongArch: For all possible CPUs setup logical-physical CPU mapping
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 <[email protected]> Signed-off-by: Huacai Chen <[email protected]>
1 parent 2d5404c commit a6654a4

File tree

2 files changed

+55
-29
lines changed

2 files changed

+55
-29
lines changed

arch/loongarch/kernel/acpi.c

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -58,48 +58,48 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
5858
return ioremap_cache(phys, size);
5959
}
6060

61-
static int cpu_enumerated = 0;
62-
6361
#ifdef CONFIG_SMP
64-
static int set_processor_mask(u32 id, u32 flags)
62+
static int set_processor_mask(u32 id, u32 pass)
6563
{
66-
int nr_cpus;
67-
int cpu, cpuid = id;
68-
69-
if (!cpu_enumerated)
70-
nr_cpus = NR_CPUS;
71-
else
72-
nr_cpus = nr_cpu_ids;
64+
int cpu = -1, cpuid = id;
7365

74-
if (num_processors >= nr_cpus) {
66+
if (num_processors >= NR_CPUS) {
7567
pr_warn(PREFIX "nr_cpus limit of %i reached."
76-
" processor 0x%x ignored.\n", nr_cpus, cpuid);
68+
" processor 0x%x ignored.\n", NR_CPUS, cpuid);
7769

7870
return -ENODEV;
7971

8072
}
73+
8174
if (cpuid == loongson_sysconf.boot_cpu_id)
8275
cpu = 0;
83-
else
84-
cpu = find_first_zero_bit(cpumask_bits(cpu_present_mask), NR_CPUS);
85-
86-
if (!cpu_enumerated)
87-
set_cpu_possible(cpu, true);
8876

89-
if (flags & ACPI_MADT_ENABLED) {
77+
switch (pass) {
78+
case 1: /* Pass 1 handle enabled processors */
79+
if (cpu < 0)
80+
cpu = find_first_zero_bit(cpumask_bits(cpu_present_mask), NR_CPUS);
9081
num_processors++;
9182
set_cpu_present(cpu, true);
92-
__cpu_number_map[cpuid] = cpu;
93-
__cpu_logical_map[cpu] = cpuid;
94-
} else
83+
break;
84+
case 2: /* Pass 2 handle disabled processors */
85+
if (cpu < 0)
86+
cpu = find_first_zero_bit(cpumask_bits(cpu_possible_mask), NR_CPUS);
9587
disabled_cpus++;
88+
break;
89+
default:
90+
return cpu;
91+
}
92+
93+
set_cpu_possible(cpu, true);
94+
__cpu_number_map[cpuid] = cpu;
95+
__cpu_logical_map[cpu] = cpuid;
9696

9797
return cpu;
9898
}
9999
#endif
100100

101101
static int __init
102-
acpi_parse_processor(union acpi_subtable_headers *header, const unsigned long end)
102+
acpi_parse_p1_processor(union acpi_subtable_headers *header, const unsigned long end)
103103
{
104104
struct acpi_madt_core_pic *processor = NULL;
105105

@@ -110,12 +110,29 @@ acpi_parse_processor(union acpi_subtable_headers *header, const unsigned long en
110110
acpi_table_print_madt_entry(&header->common);
111111
#ifdef CONFIG_SMP
112112
acpi_core_pic[processor->core_id] = *processor;
113-
set_processor_mask(processor->core_id, processor->flags);
113+
if (processor->flags & ACPI_MADT_ENABLED)
114+
set_processor_mask(processor->core_id, 1);
114115
#endif
115116

116117
return 0;
117118
}
118119

120+
static int __init
121+
acpi_parse_p2_processor(union acpi_subtable_headers *header, const unsigned long end)
122+
{
123+
struct acpi_madt_core_pic *processor = NULL;
124+
125+
processor = (struct acpi_madt_core_pic *)header;
126+
if (BAD_MADT_ENTRY(processor, end))
127+
return -EINVAL;
128+
129+
#ifdef CONFIG_SMP
130+
if (!(processor->flags & ACPI_MADT_ENABLED))
131+
set_processor_mask(processor->core_id, 2);
132+
#endif
133+
134+
return 0;
135+
}
119136
static int __init
120137
acpi_parse_eio_master(union acpi_subtable_headers *header, const unsigned long end)
121138
{
@@ -143,12 +160,14 @@ static void __init acpi_process_madt(void)
143160
}
144161
#endif
145162
acpi_table_parse_madt(ACPI_MADT_TYPE_CORE_PIC,
146-
acpi_parse_processor, MAX_CORE_PIC);
163+
acpi_parse_p1_processor, MAX_CORE_PIC);
164+
165+
acpi_table_parse_madt(ACPI_MADT_TYPE_CORE_PIC,
166+
acpi_parse_p2_processor, MAX_CORE_PIC);
147167

148168
acpi_table_parse_madt(ACPI_MADT_TYPE_EIO_PIC,
149169
acpi_parse_eio_master, MAX_IO_PICS);
150170

151-
cpu_enumerated = 1;
152171
loongson_sysconf.nr_cpus = num_processors;
153172
}
154173

@@ -310,6 +329,10 @@ static int __ref acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
310329
int nid;
311330

312331
nid = acpi_get_node(handle);
332+
333+
if (nid != NUMA_NO_NODE)
334+
nid = early_cpu_to_node(cpu);
335+
313336
if (nid != NUMA_NO_NODE) {
314337
set_cpuid_to_node(physid, nid);
315338
node_set(nid, numa_nodes_parsed);
@@ -324,12 +347,14 @@ int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 acpi_id, int *pcpu
324347
{
325348
int cpu;
326349

327-
cpu = set_processor_mask(physid, ACPI_MADT_ENABLED);
328-
if (cpu < 0) {
350+
cpu = cpu_number_map(physid);
351+
if (cpu < 0 || cpu >= nr_cpu_ids) {
329352
pr_info(PREFIX "Unable to map lapic to logical cpu number\n");
330-
return cpu;
353+
return -ERANGE;
331354
}
332355

356+
num_processors++;
357+
set_cpu_present(cpu, true);
333358
acpi_map_cpu2node(handle, cpu, physid);
334359

335360
*pcpu = cpu;

arch/loongarch/kernel/smp.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,11 +331,11 @@ void __init loongson_prepare_cpus(unsigned int max_cpus)
331331
int i = 0;
332332

333333
parse_acpi_topology();
334+
cpu_data[0].global_id = cpu_logical_map(0);
334335

335336
for (i = 0; i < loongson_sysconf.nr_cpus; i++) {
336337
set_cpu_present(i, true);
337338
csr_mail_send(0, __cpu_logical_map[i], 0);
338-
cpu_data[i].global_id = __cpu_logical_map[i];
339339
}
340340

341341
per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
@@ -380,6 +380,7 @@ void loongson_init_secondary(void)
380380
cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
381381
cpu_data[cpu].core = pptt_enabled ? cpu_data[cpu].core :
382382
cpu_logical_map(cpu) % loongson_sysconf.cores_per_package;
383+
cpu_data[cpu].global_id = cpu_logical_map(cpu);
383384
}
384385

385386
void loongson_smp_finish(void)

0 commit comments

Comments
 (0)