Commit 45f06523 authored by James Morse's avatar James Morse Committed by Zeng Heng
Browse files

ACPI / PPTT: Add a helper to fill a cpumask from a processor container

maillist inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8T2RT

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git/log/?h=mpam/snapshot/v6.7-rc2



---------------------------

The ACPI table for MPAM describes a set of CPUs with the UID of a
processor container. These exist both in the namespace and the PPTT.

Using the existing for-each helpers, provide a helper to find the
specified processor container in the PPTT, and fill a cpumask
with the CPUs that belong to it.

Signed-off-by: default avatarJames Morse <james.morse@arm.com>
Signed-off-by: default avatarZeng Heng <zengheng4@huawei.com>
parent 5b5d00ab
Loading
Loading
Loading
Loading
+67 −0
Original line number Diff line number Diff line
@@ -295,6 +295,38 @@ static struct acpi_pptt_processor *acpi_find_processor_node(struct acpi_table_he
	return NULL;
}

/* parent_node points into the table, but the table isn't provided. */
static void acpi_pptt_get_child_cpus(struct acpi_pptt_processor *parent_node,
				     cpumask_t *cpus)
{
	struct acpi_pptt_processor *cpu_node;
	struct acpi_table_header *table_hdr;
	acpi_status status;
	u32 acpi_id;
	int cpu;

	status = acpi_get_table(ACPI_SIG_PPTT, 0, &table_hdr);
	if (ACPI_FAILURE(status))
		return;

	for_each_possible_cpu(cpu) {
		acpi_id = get_acpi_id_for_cpu(cpu);
		cpu_node = acpi_find_processor_node(table_hdr, acpi_id);

		while (cpu_node) {
			if (cpu_node == parent_node) {
				cpumask_set_cpu(cpu, cpus);
				break;
			}
			cpu_node = fetch_pptt_node(table_hdr, cpu_node->parent);
		}
	}

	acpi_put_table(table_hdr);

	return;
}

/**
 * acpi_pptt_for_each_container() - Iterate over all processor containers
 *
@@ -351,6 +383,41 @@ int acpi_pptt_for_each_container(acpi_pptt_cpu_callback_t callback, void *arg)
	return ret;
}

struct __cpus_from_container_arg {
	u32 acpi_cpu_id;
	cpumask_t *cpus;
};

static int __cpus_from_container(struct acpi_pptt_processor *container, void *arg)
{
	struct __cpus_from_container_arg *params = arg;

	if (container->acpi_processor_id == params->acpi_cpu_id)
		acpi_pptt_get_child_cpus(container, params->cpus);

	return 0;
}

/**
 * acpi_pptt_get_cpus_from_container() - Populate a cpumask with all CPUs in a
 * 					 processor containers
 *
 * Find the specified Processor Container, and fill cpus with all the cpus
 * below it.
 *
 * 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 __cpus_from_container_arg params;

	params.acpi_cpu_id = acpi_cpu_id;
	params.cpus = cpus;

	cpumask_clear(cpus);
	return acpi_pptt_for_each_container(&__cpus_from_container, &params);
}

static u8 acpi_cache_type(enum cache_type type)
{
	switch (type) {
+6 −0
Original line number Diff line number Diff line
@@ -1496,6 +1496,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 find_acpi_cache_level_from_id(u32 cache_id);
int acpi_pptt_get_cpus_from_container(u32 acpi_cpu_id, cpumask_t *cpus);
#else
static inline int acpi_pptt_cpu_is_thread(unsigned int cpu)
{
@@ -1521,6 +1522,11 @@ static inline int find_acpi_cache_level_from_id(u32 cache_id)
{
	return -EINVAL;
}
static inline int acpi_pptt_get_cpus_from_container(u32 acpi_cpu_id,
						    cpumask_t *cpus)
{
	return -EINVAL;
}
#endif

#ifdef CONFIG_ARM64