From nobody Thu Oct 2 22:39:56 2025 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C80B12FFDD7; Wed, 10 Sep 2025 20:43:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757537026; cv=none; b=hh2OZDWamlppjU8v4iZ8TQcRJ3juoSvj6JhspgoTlEmmhC+B/Eo7pNHK2jsz4bNh1oHAu4iWOqYC2nqnK5TtEvjUm6D9e0+s+/xTT7+fQEcQJirlvzVaTB0ReY2xtaXmZNecynt7VzhbacS1qScAAH3SvP1NX5k4QbTeR1CDyJ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757537026; c=relaxed/simple; bh=gBE6N6A/djmpRHltVB4CBWxBxh2eVJE7nJXFynkAxoA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=sbO25K7TzpnHQGFx+3MuRcEWUC/Q4Zs0TFIBlxNy0N1AZ0YHf7PC+zDhiWZDxNv10D9pKXCJpV3uLxOEspyLaLS0w0DwvKie0CzgqGOf/sTyPbK1YcO84lrAnfGuOb5ZNEJKcv+50pDywREuO6RrnTHuf5EPmkYD32tx/2apB4s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id DDD251D34; Wed, 10 Sep 2025 13:43:35 -0700 (PDT) Received: from merodach.members.linode.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 981623F63F; Wed, 10 Sep 2025 13:43:39 -0700 (PDT) From: James Morse To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-acpi@vger.kernel.org Cc: James Morse , D Scott Phillips OS , carl@os.amperecomputing.com, lcherian@marvell.com, bobo.shaobowang@huawei.com, tan.shaopeng@fujitsu.com, baolin.wang@linux.alibaba.com, Jamie Iles , Xin Hao , peternewman@google.com, dfustini@baylibre.com, amitsinght@marvell.com, David Hildenbrand , Dave Martin , Koba Ko , Shanker Donthineni , fenghuay@nvidia.com, baisheng.gao@unisoc.com, Jonathan Cameron , Rob Herring , Rohit Mathew , Rafael Wysocki , Len Brown , Lorenzo Pieralisi , Hanjun Guo , Sudeep Holla , Catalin Marinas , Will Deacon , Greg Kroah-Hartman , Danilo Krummrich Subject: [PATCH v2 03/29] ACPI / PPTT: Find cache level by cache-id Date: Wed, 10 Sep 2025 20:42:43 +0000 Message-Id: <20250910204309.20751-4-james.morse@arm.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20250910204309.20751-1-james.morse@arm.com> References: <20250910204309.20751-1-james.morse@arm.com> 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" The MPAM table identifies caches by id. The MPAM driver also wants to know the cache level to determine if the platform is of the shape that can be managed via resctrl. Cacheinfo has this information, but only for CPUs that are online. Waiting for all CPUs to come online is a problem for platforms where CPUs are brought online late by user-space. Add a helper that walks every possible cache, until it finds the one identified by cache-id, then return the level. Signed-off-by: James Morse Reviewed-by: Fenghua Yu Reviewed-by: Lorenzo Pieralisi --- Changes since v1: * Droppeed the cleanup based table freeing, use acpi_get_pptt() instead. * Removed a confusing comment. * Clarified the kernel doc. Changes since RFC: * acpi_count_levels() now returns a value. * Converted the table-get stuff to use Jonathan's cleanup helper. * Dropped Sudeep's Review tag due to the cleanup change. --- drivers/acpi/pptt.c | 62 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/acpi.h | 5 ++++ 2 files changed, 67 insertions(+) diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c index 7af7d62597df..c5f2a51d280b 100644 --- a/drivers/acpi/pptt.c +++ b/drivers/acpi/pptt.c @@ -904,3 +904,65 @@ void acpi_pptt_get_cpus_from_container(u32 acpi_cpu_id= , cpumask_t *cpus) entry->length); } } + +/* + * find_acpi_cache_level_from_id() - Get the level of the specified cache + * @cache_id: The id field of the unified cache + * + * Determine the level relative to any CPU for the unified cache identifie= d by + * cache_id. This allows the property to be found even if the CPUs are off= line. + * + * The returned level can be used to group unified caches that are peers. + * + * The PPTT table must be rev 3 or later, + * + * If one CPUs L2 is shared with another as L3, this function will return + * an unpredictable value. + * + * Return: -ENOENT if the PPTT doesn't exist, the revision isn't supported= or + * the cache cannot be found. + * Otherwise returns a value which represents the level of the specified c= ache. + */ +int find_acpi_cache_level_from_id(u32 cache_id) +{ + u32 acpi_cpu_id; + int level, cpu, num_levels; + struct acpi_pptt_cache *cache; + struct acpi_table_header *table; + struct acpi_pptt_cache_v1 *cache_v1; + struct acpi_pptt_processor *cpu_node; + + table =3D acpi_get_pptt(); + if (!table) + return -ENOENT; + + if (table->revision < 3) + return -ENOENT; + + for_each_possible_cpu(cpu) { + acpi_cpu_id =3D get_acpi_id_for_cpu(cpu); + cpu_node =3D acpi_find_processor_node(table, acpi_cpu_id); + if (!cpu_node) + return -ENOENT; + num_levels =3D acpi_count_levels(table, cpu_node, NULL); + + /* Start at 1 for L1 */ + for (level =3D 1; level <=3D num_levels; level++) { + cache =3D acpi_find_cache_node(table, acpi_cpu_id, + ACPI_PPTT_CACHE_TYPE_UNIFIED, + level, &cpu_node); + if (!cache) + continue; + + cache_v1 =3D ACPI_ADD_PTR(struct acpi_pptt_cache_v1, + cache, + sizeof(struct acpi_pptt_cache)); + + if (cache->flags & ACPI_PPTT_CACHE_ID_VALID && + cache_v1->cache_id =3D=3D cache_id) + return level; + } + } + + return -ENOENT; +} diff --git a/include/linux/acpi.h b/include/linux/acpi.h index f97a9ff678cc..5bdca5546697 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -1542,6 +1542,7 @@ int find_acpi_cpu_topology_cluster(unsigned int cpu); int find_acpi_cpu_topology_package(unsigned int cpu); int find_acpi_cpu_topology_hetero_id(unsigned int cpu); void acpi_pptt_get_cpus_from_container(u32 acpi_cpu_id, cpumask_t *cpus); +int find_acpi_cache_level_from_id(u32 cache_id); #else static inline int acpi_pptt_cpu_is_thread(unsigned int cpu) { @@ -1565,6 +1566,10 @@ static inline int find_acpi_cpu_topology_hetero_id(u= nsigned int cpu) } static inline void acpi_pptt_get_cpus_from_container(u32 acpi_cpu_id, cpumask_t *cpus) { } +static inline int find_acpi_cache_level_from_id(u32 cache_id) +{ + return -EINVAL; +} #endif =20 void acpi_arch_init(void); --=20 2.39.5