All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
To: James Morse <james.morse@arm.com>
Cc: <linux-kernel@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	"Rob Herring" <robh@kernel.org>, Ben Horgan <ben.horgan@arm.com>,
	Rohit Mathew <rohit.mathew@arm.com>,
	Shanker Donthineni <sdonthineni@nvidia.com>,
	"Zeng Heng" <zengheng4@huawei.com>,
	Lecopzer Chen <lecopzerc@nvidia.com>,
	"Carl Worth" <carl@os.amperecomputing.com>,
	<shameerali.kolothum.thodi@huawei.com>,
	D Scott Phillips OS <scott@os.amperecomputing.com>,
	<lcherian@marvell.com>, <bobo.shaobowang@huawei.com>,
	<tan.shaopeng@fujitsu.com>, <baolin.wang@linux.alibaba.com>,
	Jamie Iles <quic_jiles@quicinc.com>,
	Xin Hao <xhao@linux.alibaba.com>, <peternewman@google.com>,
	<dfustini@baylibre.com>, <amitsinght@marvell.com>,
	David Hildenbrand <david@redhat.com>,
	Rex Nie <rex.nie@jaguarmicro.com>,
	Dave Martin <dave.martin@arm.com>, Koba Ko <kobak@nvidia.com>,
	Sudeep Holla <sudeep.holla@arm.com>
Subject: Re: [RFC PATCH 07/36] ACPI / PPTT: Find cache level by cache-idUIRE
Date: Wed, 16 Jul 2025 17:21:44 +0100	[thread overview]
Message-ID: <20250716172144.00000715@huawei.com> (raw)
In-Reply-To: <20250711183648.30766-8-james.morse@arm.com>

On Fri, 11 Jul 2025 18:36:19 +0000
James Morse <james.morse@arm.com> wrote:

> 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.
> 
> acpi_count_levels() expects its levels parameter to be initialised to
> zero as it passes it to acpi_find_cache_level() as starting_level.
> The existing callers do this. Document it.
> 
> Signed-off-by: James Morse <james.morse@arm.com>
> Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>

A few suggestions inline.  Mostly driven by the number of missing table
puts I've seen in ACPI code. You don't have any missing here but with a
bit of restructuring you can make that easy to see.

> ---
>  drivers/acpi/pptt.c  | 73 ++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/acpi.h |  5 +++
>  2 files changed, 78 insertions(+)
> 
> diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
> index 13ca2eee3b98..f53748a5df19 100644
> --- a/drivers/acpi/pptt.c
> +++ b/drivers/acpi/pptt.c
> @@ -912,3 +912,76 @@ int find_acpi_cpu_topology_hetero_id(unsigned int cpu)
>  	return find_acpi_cpu_topology_tag(cpu, PPTT_ABORT_PACKAGE,
>  					  ACPI_PPTT_ACPI_IDENTICAL);
>  }
> +
> +/**
> + * 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 identified by
> + * cache_id. This allows the property to be found even if the CPUs are offline.
> + *
> + * 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, or the cache cannot be found.
> + * Otherwise returns a value which represents the level of the specified cache.
> + */
> +int find_acpi_cache_level_from_id(u32 cache_id)
> +{
> +	u32 acpi_cpu_id;
> +	acpi_status status;
> +	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;
> +
> +	status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
> +	if (ACPI_FAILURE(status)) {
> +		acpi_pptt_warn_missing();
> +		return -ENOENT;
> +	}
> +
> +	if (table->revision < 3) {

Maybe a unified exit path given all paths need to do
acpi_put_table() and return either error or level.

Or maybe it's time for some cleanup.h magic for acpi tables. I've
been thinking about it for a while and mostly stuck on the name ;)
(simpler suggestion follows)

static struct acpi_table_header *acpi_get_table_ret(char *signature, u32 instance)
{
	struct acpi_table_header *table;
	int status = acpi_get_table(signature, instance, &table);
	
	if (ACPI_FAILURE(status))
		return ERR_PTR(-ENOENT);
	return table;
}

DEFINE_FREE(acpi_table, struct acpi_table_header *, if (!IS_ERR(_T)) acpi_put_table(_T))

Finally in here and loads of other places we avoid chance of missing an acpi_put_table
and generally simplify the code a little.

int find_acpi_cache_level_from_id(u32 cache_id)
{
	u32 acpi_cpu_id;
	acpi_status status;
	int level, cpu, num_levels;
	struct acpi_pptt_cache *cache;
	struct acpi_pptt_cache_v1 *cache_v1;
	struct acpi_pptt_processor *cpu_node;


	struct acpi_table_header *table __free(acpi_table) =
		acpi_get_table_ret(ACPI_SIG_PPTT, 0);

	if (IS_ERR(table)
		return PTR_ERR(table);

	if (table->revision < 3)
		return -ENOENT;

	/*
	 * If we found the cache first, we'd still need to walk from each CPU
	 * to find the level...
	 */
	for_each_possible_cpu(cpu) {
		acpi_cpu_id = get_acpi_id_for_cpu(cpu);
		cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
		if (!cpu_node)
			return -ENOENT;
		acpi_count_levels(table, cpu_node, &num_levels, NULL);

		/* Start at 1 for L1 */
		for (level = 1; level <= num_levels; level++) {
			cache = acpi_find_cache_node(table, acpi_cpu_id,
						     ACPI_PPTT_CACHE_TYPE_UNIFIED,
						     level, &cpu_node);
			if (!cache)
				continue;

			cache_v1 = 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 == cache_id) {
				acpi_put_table(table);
				return level;
			}
		}
	}
	return -ENOENT;
}


A less 'fun' alternative is pull some code out as a helper to make put the get and put
near each other with no conditionals to confuse things.


static int __find_acpi_cache_level_from_id(u32 cache_id, struct acpi_table_header *head);
{
	u32 acpi_cpu_id;
	int level, cpu, num_levels;
	struct acpi_pptt_cache *cache;
	struct acpi_pptt_cache_v1 *cache_v1;
	struct acpi_pptt_processor *cpu_node;

	if (table->revision < 3)
		return -ENOENT;

	/*
	 * If we found the cache first, we'd still need to walk from each CPU
	 * to find the level...
	 */
	for_each_possible_cpu(cpu) {
		acpi_cpu_id = get_acpi_id_for_cpu(cpu);
		cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
		if (!cpu_node)
			return -ENOENT;
		acpi_count_levels(table, cpu_node, &num_levels, NULL);

		/* Start at 1 for L1 */
		for (level = 1; level <= num_levels; level++) {
			cache = acpi_find_cache_node(table, acpi_cpu_id,
						     ACPI_PPTT_CACHE_TYPE_UNIFIED,
						     level, &cpu_node);
			if (!cache)
				continue;

			cache_v1 = 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 == cache_id)
				return level;
		}
	}

	return -ENOENT;
}

int find_acpi_cache_level_from_id(u32 cache_id)
{
	int ret;
	acpi_status status;
	struct acpi_table_header *table;

	status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
	if (ACPI_FAILURE(status)) {
		acpi_pptt_warn_missing();
		return -ENOENT;
	}

	ret = __find_acpi_cache_level_from_id(cache_id, table)
	acpi_put_table(table);
	return ret;
}


> +		acpi_put_table(table);
> +		return -ENOENT;
> +	}
> +
> +	/*
> +	 * If we found the cache first, we'd still need to walk from each CPU
> +	 * to find the level...
> +	 */
> +	for_each_possible_cpu(cpu) {
> +		acpi_cpu_id = get_acpi_id_for_cpu(cpu);
> +		cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
> +		if (!cpu_node)
> +			break;
> +		acpi_count_levels(table, cpu_node, &num_levels, NULL);
> +
> +		/* Start at 1 for L1 */
> +		for (level = 1; level <= num_levels; level++) {
> +			cache = acpi_find_cache_node(table, acpi_cpu_id,
> +						     ACPI_PPTT_CACHE_TYPE_UNIFIED,
> +						     level, &cpu_node);
> +			if (!cache)
> +				continue;
> +
> +			cache_v1 = 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 == cache_id) {
> +				acpi_put_table(table);
> +				return level;
> +			}
> +		}
> +	}
> +
> +	acpi_put_table(table);
> +	return -ENOENT;
> +}
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 8c3165c2b083..82947f6d2a43 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);
>  int 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)
>  {
> @@ -1568,6 +1569,10 @@ static inline int acpi_pptt_get_cpus_from_container(u32 acpi_cpu_id,
>  {
>  	return -EINVAL;
>  }
> +static inline int find_acpi_cache_level_from_id(u32 cache_id)
> +{
> +	return -EINVAL;
> +}
>  #endif
>  
>  void acpi_arch_init(void);



  parent reply	other threads:[~2025-07-16 16:24 UTC|newest]

Thread overview: 117+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-11 18:36 [RFC PATCH 00/36] arm_mpam: Add basic mpam driver James Morse
2025-07-11 18:36 ` [RFC PATCH 01/36] cacheinfo: Set cache 'id' based on DT data James Morse
2025-07-11 18:36 ` [RFC PATCH 02/36] cacheinfo: Add arch hook to compress CPU h/w id into 32 bits for cache-id James Morse
2025-07-11 18:36 ` [RFC PATCH 03/36] arm64: cacheinfo: Provide helper to compress MPIDR value into u32 James Morse
2025-07-11 18:36 ` [RFC PATCH 04/36] cacheinfo: Expose the code to generate a cache-id from a device_node James Morse
2025-07-14 11:40   ` Ben Horgan
2025-07-25 17:08     ` James Morse
2025-07-28  8:37       ` Ben Horgan
2025-07-11 18:36 ` [RFC PATCH 05/36] ACPI / PPTT: Add a helper to fill a cpumask from a processor container James Morse
2025-07-17  7:58   ` Shaopeng Tan (Fujitsu)
2025-07-25 17:06     ` James Morse
2025-07-22 14:28   ` Jonathan Cameron
2025-07-25 17:05     ` James Morse
2025-07-23 14:42   ` Ben Horgan
2025-07-25 17:05     ` James Morse
2025-07-11 18:36 ` [RFC PATCH 06/36] ACPI / PPTT: Stop acpi_count_levels() expecting callers to clear levels James Morse
2025-07-16 15:51   ` Jonathan Cameron
2025-07-25 17:05     ` James Morse
2025-07-11 18:36 ` [RFC PATCH 07/36] ACPI / PPTT: Find cache level by cache-id James Morse
2025-07-14 11:42   ` Ben Horgan
2025-08-05 17:06     ` James Morse
2025-07-16 16:21   ` Jonathan Cameron [this message]
2025-08-05 17:06     ` James Morse
2025-07-11 18:36 ` [RFC PATCH 08/36] ACPI / PPTT: Add a helper to fill a cpumask from a cache_id James Morse
2025-07-16 16:24   ` Jonathan Cameron
2025-08-05 17:06     ` James Morse
2025-07-11 18:36 ` [RFC PATCH 09/36] arm64: kconfig: Add Kconfig entry for MPAM James Morse
2025-07-16 16:26   ` Jonathan Cameron
2025-07-11 18:36 ` [RFC PATCH 10/36] ACPI / MPAM: Parse the MPAM table James Morse
2025-07-16 17:07   ` Jonathan Cameron
2025-07-23 16:39     ` Ben Horgan
2025-08-05 17:07       ` James Morse
2025-08-15  9:33         ` Ben Horgan
2025-07-28 10:08     ` Jonathan Cameron
2025-08-05 17:08       ` James Morse
2025-08-05 17:07     ` James Morse
2025-07-24 10:50   ` Ben Horgan
2025-08-05 17:08     ` James Morse
2025-07-11 18:36 ` [RFC PATCH 11/36] dt-bindings: arm: Add MPAM MSC binding James Morse
2025-07-11 21:43   ` Rob Herring
2025-08-05 17:08     ` James Morse
2025-07-11 18:36 ` [RFC PATCH 12/36] platform: arm64: Move ec devices to an ec subdirectory James Morse
2025-07-21 16:32   ` Jonathan Cameron
2025-08-06 18:03     ` James Morse
2025-07-24 10:56   ` Ben Horgan
2025-08-06 18:03     ` James Morse
2025-07-11 18:36 ` [RFC PATCH 13/36] arm_mpam: Add probe/remove for mpam msc driver and kbuild boiler plate James Morse
2025-07-24 11:02   ` Ben Horgan
2025-08-06 18:03     ` James Morse
2025-07-24 12:09   ` Catalin Marinas
2025-08-06 18:04     ` James Morse
2025-08-07 17:50       ` Drew Fustini
2025-07-11 18:36 ` [RFC PATCH 14/36] arm_mpam: Add support for memory controller MSC on DT platforms James Morse
2025-07-11 18:36 ` [RFC PATCH 15/36] arm_mpam: Add the class and component structures for ris firmware described James Morse
2025-07-11 18:36 ` [RFC PATCH 16/36] arm_mpam: Add MPAM MSC register layout definitions James Morse
2025-07-17  1:04   ` Shaopeng Tan (Fujitsu)
2025-08-06 18:04     ` James Morse
2025-07-24 14:02   ` Ben Horgan
2025-08-06 18:05     ` James Morse
2025-07-11 18:36 ` [RFC PATCH 17/36] arm_mpam: Add cpuhp callbacks to probe MSC hardware James Morse
2025-07-24 14:13   ` Ben Horgan
2025-08-06 18:07     ` James Morse
2025-07-29  6:11   ` Baisheng Gao
2025-08-06 18:07     ` James Morse
2025-08-05  8:46   ` Jonathan Cameron
2025-07-11 18:36 ` [RFC PATCH 18/36] arm_mpam: Probe MSCs to find the supported partid/pmg values James Morse
2025-07-11 18:36 ` [RFC PATCH 19/36] arm_mpam: Add helpers for managing the locking around the mon_sel registers James Morse
2025-07-11 18:36 ` [RFC PATCH 20/36] arm_mpam: Probe the hardware features resctrl supports James Morse
2025-07-24 15:08   ` Ben Horgan
2025-07-28 16:16     ` Jonathan Cameron
2025-08-07 18:26     ` James Morse
2025-07-28  8:56   ` Ben Horgan
2025-08-08  7:20     ` James Morse
2025-07-11 18:36 ` [RFC PATCH 21/36] arm_mpam: Merge supported features during mpam_enable() into mpam_class James Morse
2025-07-28  9:15   ` Ben Horgan
2025-07-11 18:36 ` [RFC PATCH 22/36] arm_mpam: Reset MSC controls from cpu hp callbacks James Morse
2025-07-28  9:49   ` Ben Horgan
2025-08-08  7:05     ` James Morse
2025-07-11 18:36 ` [RFC PATCH 23/36] arm_mpam: Add a helper to touch an MSC from any CPU James Morse
2025-07-11 18:36 ` [RFC PATCH 24/36] arm_mpam: Extend reset logic to allow devices to be reset any time James Morse
2025-07-28 10:22   ` Ben Horgan
2025-08-08  7:07     ` James Morse
2025-07-11 18:36 ` [RFC PATCH 25/36] arm_mpam: Register and enable IRQs James Morse
2025-07-16  7:31   ` Shaopeng Tan (Fujitsu)
2025-08-08  7:08     ` James Morse
2025-07-17  1:08   ` Shaopeng Tan (Fujitsu)
2025-08-08  7:07     ` James Morse
2025-07-22 15:06   ` Jonathan Cameron
2025-08-08  7:11     ` James Morse
2025-07-28 10:49   ` Ben Horgan
2025-08-08  7:11     ` James Morse
2025-08-04 16:53   ` Fenghua Yu
2025-08-08  7:12     ` James Morse
2025-07-11 18:36 ` [RFC PATCH 26/36] arm_mpam: Use a static key to indicate when mpam is enabled James Morse
2025-07-11 18:36 ` [RFC PATCH 27/36] arm_mpam: Allow configuration to be applied and restored during cpu online James Morse
2025-07-16  6:49   ` Shaopeng Tan (Fujitsu)
2025-08-08  7:13     ` James Morse
2025-07-28 11:59   ` Ben Horgan
2025-07-28 15:34     ` Dave Martin
2025-08-08  7:16       ` James Morse
2025-08-08  7:14     ` James Morse
2025-08-04 16:39   ` Fenghua Yu
2025-08-08  7:17     ` James Morse
2025-07-11 18:36 ` [RFC PATCH 28/36] arm_mpam: Probe and reset the rest of the features James Morse
2025-07-11 18:36 ` [RFC PATCH 29/36] arm_mpam: Add helpers to allocate monitors James Morse
2025-07-11 18:36 ` [RFC PATCH 30/36] arm_mpam: Add mpam_msmon_read() to read monitor value James Morse
2025-07-28 13:02   ` Ben Horgan
2025-07-11 18:36 ` [RFC PATCH 31/36] arm_mpam: Track bandwidth counter state for overflow and power management James Morse
2025-07-11 18:36 ` [RFC PATCH 32/36] arm_mpam: Probe for long/lwd mbwu counters James Morse
2025-07-11 18:36 ` [RFC PATCH 33/36] arm_mpam: Use long MBWU counters if supported James Morse
2025-07-28 13:46   ` Ben Horgan
2025-08-08  7:19     ` James Morse
2025-07-11 18:36 ` [RFC PATCH 34/36] arm_mpam: Add helper to reset saved mbwu state James Morse
2025-07-11 18:36 ` [RFC PATCH 35/36] arm_mpam: Add kunit test for bitmap reset James Morse
2025-07-11 18:36 ` [RFC PATCH 36/36] arm_mpam: Add kunit tests for props_mismatch() James Morse
2025-08-01 16:09 ` [RFC PATCH 00/36] arm_mpam: Add basic mpam driver Jonathan Cameron
2025-08-08  7:23   ` James Morse

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250716172144.00000715@huawei.com \
    --to=jonathan.cameron@huawei.com \
    --cc=amitsinght@marvell.com \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=ben.horgan@arm.com \
    --cc=bobo.shaobowang@huawei.com \
    --cc=carl@os.amperecomputing.com \
    --cc=dave.martin@arm.com \
    --cc=david@redhat.com \
    --cc=dfustini@baylibre.com \
    --cc=james.morse@arm.com \
    --cc=kobak@nvidia.com \
    --cc=lcherian@marvell.com \
    --cc=lecopzerc@nvidia.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peternewman@google.com \
    --cc=quic_jiles@quicinc.com \
    --cc=rex.nie@jaguarmicro.com \
    --cc=robh@kernel.org \
    --cc=rohit.mathew@arm.com \
    --cc=scott@os.amperecomputing.com \
    --cc=sdonthineni@nvidia.com \
    --cc=shameerali.kolothum.thodi@huawei.com \
    --cc=sudeep.holla@arm.com \
    --cc=tan.shaopeng@fujitsu.com \
    --cc=xhao@linux.alibaba.com \
    --cc=zengheng4@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.