Unverified Commit a5924d00 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!1074 arch_topology, ACPI: populate cpu capacity from CPPC

Merge Pull Request from: @liujie-248683921 
 
Ionela Voinescu (2):
  arch_topology: obtain cpu capacity using information from CPPC
  arm64, topology: enable use of init_cpu_capacity_cppc()

Jie Liu (2):
  cppc_acpi: add acpi_cpc_valid for determining _CPC is valid
  arm64, topology: add arch_init_invariance_cppc to use information from CPPC

Mario Limonciello (1):
  ACPI: CPPC: Check present CPUs for determining _CPC is valid

 arch/arm64/include/asm/topology.h |  4 +++
 drivers/acpi/cppc_acpi.c          | 22 +++++++++++++++
 drivers/base/arch_topology.c      | 45 ++++++++++++++++++++++++++++---
 include/acpi/cppc_acpi.h          |  1 +
 include/linux/arch_topology.h     |  4 +++
 5 files changed, 73 insertions(+), 3 deletions(-)

--
2.30.0
 
 
Link:https://gitee.com/openeuler/kernel/pulls/1074

 

Reviewed-by: default avatarXiongfeng Wang <wangxiongfeng2@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents c372a428 65263dae
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -32,6 +32,10 @@ void topology_scale_freq_tick(void);
#define arch_scale_freq_capacity topology_get_freq_scale
#define arch_scale_freq_invariant topology_scale_freq_invariant

#ifdef CONFIG_ACPI_CPPC_LIB
#define arch_init_invariance_cppc topology_init_cpu_capacity_cppc
#endif

/* Replace task scheduler's default cpu-invariant accounting */
#define arch_scale_cpu_capacity topology_get_cpu_scale

+22 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include <linux/ktime.h>
#include <linux/rwsem.h>
#include <linux/wait.h>
#include <linux/topology.h>

#include <acpi/cppc_acpi.h>

@@ -405,6 +406,21 @@ static int acpi_get_psd(struct cpc_desc *cpc_ptr, acpi_handle handle)
	return result;
}

bool acpi_cpc_valid(void)
{
	struct cpc_desc *cpc_ptr;
	int cpu;

	for_each_present_cpu(cpu) {
		cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
		if (!cpc_ptr)
			return false;
	}

	return true;
}
EXPORT_SYMBOL_GPL(acpi_cpc_valid);

/**
 * acpi_get_psd_map - Map the CPUs in a common freq domain.
 * @all_cpu_data: Ptrs to CPU specific CPPC data including PSD info.
@@ -725,6 +741,10 @@ static int pcc_data_alloc(int pcc_ss_id)
 *	}
 */

#ifndef arch_init_invariance_cppc
static inline void arch_init_invariance_cppc(void) { }
#endif

/**
 * acpi_cppc_processor_probe - Search for per CPU _CPC objects.
 * @pr: Ptr to acpi_processor containing this CPU's logical ID.
@@ -913,6 +933,8 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
		goto out_free;
	}

	arch_init_invariance_cppc();

	kfree(output.pointer);
	return 0;

+42 −3
Original line number Diff line number Diff line
@@ -219,6 +219,46 @@ bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
	return !ret;
}

#ifdef CONFIG_ACPI_CPPC_LIB
#include <acpi/cppc_acpi.h>

void topology_init_cpu_capacity_cppc(void)
{
	struct cppc_perf_caps perf_caps;
	int cpu;

	if (likely(acpi_disabled || !acpi_cpc_valid()))
		return;

	raw_capacity = kcalloc(num_possible_cpus(), sizeof(*raw_capacity),
			       GFP_KERNEL);
	if (!raw_capacity)
		return;

	for_each_possible_cpu(cpu) {
		if (!cppc_get_perf_caps(cpu, &perf_caps) &&
		    (perf_caps.highest_perf >= perf_caps.nominal_perf) &&
		    (perf_caps.highest_perf >= perf_caps.lowest_perf)) {
			raw_capacity[cpu] = perf_caps.highest_perf;
			pr_debug("cpu_capacity: CPU%d cpu_capacity=%u (raw).\n",
				 cpu, raw_capacity[cpu]);
			continue;
		}

		pr_err("cpu_capacity: CPU%d missing/invalid highest performance.\n", cpu);
		pr_err("cpu_capacity: partial information: fallback to 1024 for all CPUs\n");
		goto exit;
	}

	topology_normalize_cpu_scale();
	schedule_work(&update_topology_flags_work);
	pr_debug("cpu_capacity: cpu_capacity initialization done\n");

exit:
	free_raw_capacity();
}
#endif

#ifdef CONFIG_CPU_FREQ
static cpumask_var_t cpus_to_visit;
static void parsing_done_workfn(struct work_struct *work);
@@ -267,9 +307,8 @@ static int __init register_cpufreq_notifier(void)
	int ret;

	/*
	 * on ACPI-based systems we need to use the default cpu capacity
	 * until we have the necessary code to parse the cpu capacity, so
	 * skip registering cpufreq notifier.
	 * On ACPI-based systems skip registering cpufreq notifier as cpufreq
	 * information is not needed for cpu capacity initialization.
	 */
	if (!acpi_disabled || !raw_capacity)
		return -EINVAL;
+1 −0
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs);
extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls);
extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps);
extern int acpi_get_psd_map(struct cppc_cpudata **);
extern bool acpi_cpc_valid(void);
extern unsigned int cppc_get_transition_latency(int cpu);
extern bool cpc_ffh_supported(void);
extern int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val);
+4 −0
Original line number Diff line number Diff line
@@ -11,6 +11,10 @@
void topology_normalize_cpu_scale(void);
int topology_update_cpu_topology(void);

#ifdef CONFIG_ACPI_CPPC_LIB
void topology_init_cpu_capacity_cppc(void);
#endif

struct device_node;
bool topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu);