Thread (117 messages) 117 messages, 10 authors, 2025-08-15

Re: [RFC PATCH 05/36] ACPI / PPTT: Add a helper to fill a cpumask from a processor container

From: James Morse <james.morse@arm.com>
Date: 2025-07-25 17:05:56
Also in: lkml

Hi Ben,

On 23/07/2025 15:42, Ben Horgan wrote:
On 7/11/25 19:36, James Morse wrote:
quoted
The PPTT describes CPUs and caches, as well as processor containers.
The ACPI table for MPAM describes the set of CPUs that can access an MSC
with the UID of a processor container.

Add a helper to find the processor container by its id, then walk
the possible CPUs to fill a cpumask with the CPUs that have this
processor container as a parent.
quoted
diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
index 54676e3d82dd..13619b1b821b 100644
--- a/drivers/acpi/pptt.c
+++ b/drivers/acpi/pptt.c
@@ -298,6 +298,99 @@ static struct acpi_pptt_processor *acpi_find_processor_node(struct
+/**
+ * acpi_pptt_get_cpus_from_container() - Populate a cpumask with all CPUs in a
+ *                                       processor containers
+ * @acpi_cpu_id:    The UID of the processor container.
+ * @cpus        The resulting CPU mask.
+ *
+ * Find the specified Processor Container, and fill @cpus with all the cpus
+ * below it.
+ *
+ * Not all 'Processor' entries in the PPTT are either a CPU or a Processor
+ * Container, they may exist purely to describe a Private resource. CPUs
+ * have to be leaves, so a Processor Container is a non-leaf that has the
+ * 'ACPI Processor ID valid' flag set.
+ *
+ * Return: 0 for a complete walk, or an error if the mask is incomplete.
+ */
+int acpi_pptt_get_cpus_from_container(u32 acpi_cpu_id, cpumask_t *cpus)
+{
+    struct acpi_pptt_processor *cpu_node;
+    struct acpi_table_header *table_hdr;
+    struct acpi_subtable_header *entry;
+    bool leaf_flag, has_leaf_flag = false;
+    unsigned long table_end;
+    acpi_status status;
+    u32 proc_sz;
+    int ret = 0;
+
+    cpumask_clear(cpus);
+
+    status = acpi_get_table(ACPI_SIG_PPTT, 0, &table_hdr);
+    if (ACPI_FAILURE(status))
+        return 0;
+
+    if (table_hdr->revision > 1)
+        has_leaf_flag = true;
+
+    table_end = (unsigned long)table_hdr + table_hdr->length;
+    entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
+                 sizeof(struct acpi_table_pptt));
+    proc_sz = sizeof(struct acpi_pptt_processor);
+    while ((unsigned long)entry + proc_sz <= table_end) {
+        cpu_node = (struct acpi_pptt_processor *)entry;
+        if (entry->type == ACPI_PPTT_TYPE_PROCESSOR &&
+            cpu_node->flags & ACPI_PPTT_ACPI_PROCESSOR_ID_VALID) {
+            leaf_flag = cpu_node->flags & ACPI_PPTT_ACPI_LEAF_NODE;
+            if ((has_leaf_flag && !leaf_flag) ||
+                (!has_leaf_flag && !acpi_pptt_leaf_node(table_hdr, cpu_node))) {
+                if (cpu_node->acpi_processor_id == acpi_cpu_id)
+                    acpi_pptt_get_child_cpus(table_hdr, cpu_node, cpus);
+            }
acpi_pptt_leaf_node() returns early based on the leaf flag so you can just rely on that
here; remove has_leaf_flag and the corresponding extra logic.
Aha! I was only doing this to try and avoid that extra descent of the tree. I missed that
its already taken into account.


Thanks,

James
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help