This series is a backport of the ACPI PPTT 6.3 thread flag feature for supporting arm64 systems.
The background is that some arm64 implementations are broken, in that they incorrectly advertise that a CPU is mutli-threaded, when it is not - the HiSilicon Taishanv110 rev 2, aka tsv110, being an example.
This leads to the system topology being incorrect. The reason being that arm64 topology code uses a combination of ACPI PPTT (Processor Properties Topology Table) and the system MPIDR (Multiprocessor Affinity Register) MT bit to determine the topology.
Until ACPI 6.3, the PPTT did not have any method to determine whether a CPU was multi-threaded, so only the MT bit is used - hence the broken topology for some systems.
In ACPI 6.3, a PPTT thread flag was introduced, which - when supported - would be used by the kernel to determine really if a CPU is multi-threaded or not, so that we don't get incorrect topology.
RFC originally sent for 4.19: https://lkml.org/lkml/2019/10/10/724 Jeremy Linton (2): ACPI/PPTT: Add support for ACPI 6.3 thread flag arm64: topology: Use PPTT to determine if PE is a thread
arch/arm64/kernel/topology.c | 19 ++++++++++--- drivers/acpi/pptt.c | 52 ++++++++++++++++++++++++++++++++++++ include/linux/acpi.h | 5 ++++ 3 files changed, 72 insertions(+), 4 deletions(-)
From: Jeremy Linton jeremy.linton@arm.com
Commit bbd1b70639f785a970d998f35155c713f975e3ac upstream.
ACPI 6.3 adds a flag to the CPU node to indicate whether the given PE is a thread. Add a function to return that information for a given linux logical CPU.
Signed-off-by: Jeremy Linton jeremy.linton@arm.com Reviewed-by: Sudeep Holla sudeep.holla@arm.com Reviewed-by: Robert Richter rrichter@marvell.com Acked-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: John Garry john.garry@huawei.com --- drivers/acpi/pptt.c | 52 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/acpi.h | 5 +++++ 2 files changed, 57 insertions(+)
diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c index 1e7ac0bd0d3a..9497298018a9 100644 --- a/drivers/acpi/pptt.c +++ b/drivers/acpi/pptt.c @@ -540,6 +540,44 @@ static int find_acpi_cpu_topology_tag(unsigned int cpu, int level, int flag) return retval; }
+/** + * check_acpi_cpu_flag() - Determine if CPU node has a flag set + * @cpu: Kernel logical CPU number + * @rev: The minimum PPTT revision defining the flag + * @flag: The flag itself + * + * Check the node representing a CPU for a given flag. + * + * Return: -ENOENT if the PPTT doesn't exist, the CPU cannot be found or + * the table revision isn't new enough. + * 1, any passed flag set + * 0, flag unset + */ +static int check_acpi_cpu_flag(unsigned int cpu, int rev, u32 flag) +{ + struct acpi_table_header *table; + acpi_status status; + u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu); + struct acpi_pptt_processor *cpu_node = NULL; + int ret = -ENOENT; + + status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); + if (ACPI_FAILURE(status)) { + acpi_pptt_warn_missing(); + return ret; + } + + if (table->revision >= rev) + cpu_node = acpi_find_processor_node(table, acpi_cpu_id); + + if (cpu_node) + ret = (cpu_node->flags & flag) != 0; + + acpi_put_table(table); + + return ret; +} + /** * acpi_find_last_cache_level() - Determines the number of cache levels for a PE * @cpu: Kernel logical CPU number @@ -604,6 +642,20 @@ int cache_setup_acpi(unsigned int cpu) return status; }
+/** + * acpi_pptt_cpu_is_thread() - Determine if CPU is a thread + * @cpu: Kernel logical CPU number + * + * Return: 1, a thread + * 0, not a thread + * -ENOENT ,if the PPTT doesn't exist, the CPU cannot be found or + * the table revision isn't new enough. + */ +int acpi_pptt_cpu_is_thread(unsigned int cpu) +{ + return check_acpi_cpu_flag(cpu, 2, ACPI_PPTT_ACPI_PROCESSOR_IS_THREAD); +} + /** * find_acpi_cpu_topology() - Determine a unique topology value for a given CPU * @cpu: Kernel logical CPU number diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 9426b9aaed86..9d0e20a2ac83 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -1302,11 +1302,16 @@ static inline int lpit_read_residency_count_address(u64 *address) #endif
#ifdef CONFIG_ACPI_PPTT +int acpi_pptt_cpu_is_thread(unsigned int cpu); int find_acpi_cpu_topology(unsigned int cpu, int level); int find_acpi_cpu_topology_package(unsigned int cpu); int find_acpi_cpu_topology_hetero_id(unsigned int cpu); int find_acpi_cpu_cache_topology(unsigned int cpu, int level); #else +static inline int acpi_pptt_cpu_is_thread(unsigned int cpu) +{ + return -EINVAL; +} static inline int find_acpi_cpu_topology(unsigned int cpu, int level) { return -EINVAL;
On Mon, Oct 14, 2019 at 07:56:01PM +0800, John Garry wrote:
From: Jeremy Linton jeremy.linton@arm.com
Commit bbd1b70639f785a970d998f35155c713f975e3ac upstream.
ACPI 6.3 adds a flag to the CPU node to indicate whether the given PE is a thread. Add a function to return that information for a given linux logical CPU.
Signed-off-by: Jeremy Linton jeremy.linton@arm.com Reviewed-by: Sudeep Holla sudeep.holla@arm.com Reviewed-by: Robert Richter rrichter@marvell.com Acked-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: John Garry john.garry@huawei.com
How far back should these patches be backported?
On 15/10/2019 00:29, Sasha Levin wrote:
On Mon, Oct 14, 2019 at 07:56:01PM +0800, John Garry wrote:
From: Jeremy Linton jeremy.linton@arm.com
Commit bbd1b70639f785a970d998f35155c713f975e3ac upstream.
ACPI 6.3 adds a flag to the CPU node to indicate whether the given PE is a thread. Add a function to return that information for a given linux logical CPU.
Signed-off-by: Jeremy Linton jeremy.linton@arm.com Reviewed-by: Sudeep Holla sudeep.holla@arm.com Reviewed-by: Robert Richter rrichter@marvell.com Acked-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: John Garry john.garry@huawei.com
How far back should these patches be backported?
Hi Sasha,
This patchset is for 5.3, and I sent a separate patchset for 4.19, since the backport is a little different and required some hand modification -
https://lore.kernel.org/linux-arm-kernel/1571046986-231263-1-git-send-email-.... 4.19 is as far back as we want.
Please note that the patches in this 5.3 series are relevant for 5.2 also, but since 5.2 is EOL, I didn't mention it. We did test 5.2, so you can add there also.
Please let me know if any more questions.
All the best, John
On Tue, Oct 15, 2019 at 09:16:13AM +0100, John Garry wrote:
On 15/10/2019 00:29, Sasha Levin wrote:
On Mon, Oct 14, 2019 at 07:56:01PM +0800, John Garry wrote:
From: Jeremy Linton jeremy.linton@arm.com
Commit bbd1b70639f785a970d998f35155c713f975e3ac upstream.
ACPI 6.3 adds a flag to the CPU node to indicate whether the given PE is a thread. Add a function to return that information for a given linux logical CPU.
Signed-off-by: Jeremy Linton jeremy.linton@arm.com Reviewed-by: Sudeep Holla sudeep.holla@arm.com Reviewed-by: Robert Richter rrichter@marvell.com Acked-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: John Garry john.garry@huawei.com
How far back should these patches be backported?
Hi Sasha,
This patchset is for 5.3, and I sent a separate patchset for 4.19, since the backport is a little different and required some hand modification -
https://lore.kernel.org/linux-arm-kernel/1571046986-231263-1-git-send-email-.... 4.19 is as far back as we want.
Please note that the patches in this 5.3 series are relevant for 5.2 also, but since 5.2 is EOL, I didn't mention it. We did test 5.2, so you can add there also.
Please let me know if any more questions.
I've queued this and the 4.19 patches, thanks!
From: Jeremy Linton jeremy.linton@arm.com
Commit 98dc19902a0b2e5348e43d6a2c39a0a7d0fc639e upstream.
ACPI 6.3 adds a thread flag to represent if a CPU/PE is actually a thread. Given that the MPIDR_MT bit may not represent this information consistently on homogeneous machines we should prefer the PPTT flag if its available.
Signed-off-by: Jeremy Linton jeremy.linton@arm.com Reviewed-by: Sudeep Holla sudeep.holla@arm.com Reviewed-by: Robert Richter rrichter@marvell.com [will: made acpi_cpu_is_threaded() return 'bool'] Signed-off-by: Will Deacon will@kernel.org Signed-off-by: John Garry john.garry@huawei.com --- arch/arm64/kernel/topology.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c index 0825c4a856e3..6106c49f84bc 100644 --- a/arch/arm64/kernel/topology.c +++ b/arch/arm64/kernel/topology.c @@ -340,17 +340,28 @@ void remove_cpu_topology(unsigned int cpu) }
#ifdef CONFIG_ACPI +static bool __init acpi_cpu_is_threaded(int cpu) +{ + int is_threaded = acpi_pptt_cpu_is_thread(cpu); + + /* + * if the PPTT doesn't have thread information, assume a homogeneous + * machine and return the current CPU's thread state. + */ + if (is_threaded < 0) + is_threaded = read_cpuid_mpidr() & MPIDR_MT_BITMASK; + + return !!is_threaded; +} + /* * Propagate the topology information of the processor_topology_node tree to the * cpu_topology array. */ static int __init parse_acpi_topology(void) { - bool is_threaded; int cpu, topology_id;
- is_threaded = read_cpuid_mpidr() & MPIDR_MT_BITMASK; - for_each_possible_cpu(cpu) { int i, cache_id;
@@ -358,7 +369,7 @@ static int __init parse_acpi_topology(void) if (topology_id < 0) return topology_id;
- if (is_threaded) { + if (acpi_cpu_is_threaded(cpu)) { cpu_topology[cpu].thread_id = topology_id; topology_id = find_acpi_cpu_topology(cpu, 1); cpu_topology[cpu].core_id = topology_id;
linux-stable-mirror@lists.linaro.org