Skip to content

Commit

Permalink
Merge branch 'pm-cpufreq'
Browse files Browse the repository at this point in the history
* pm-cpufreq:
  cpufreq: intel_pstate: Use most recent guaranteed performance values
  cpufreq: intel_pstate: Implement the ->adjust_perf() callback
  cpufreq: Add special-purpose fast-switching callback for drivers
  cpufreq: schedutil: Add util to struct sg_cpu
  cppc_cpufreq: replace per-cpu data array with a list
  cppc_cpufreq: expose information on frequency domains
  cppc_cpufreq: clarify support for coordination types
  cppc_cpufreq: use policy->cpu as driver of frequency setting
  ACPI: processor: fix NONE coordination for domain mapping failure
  ACPI: processor: Drop duplicate setting of shared_cpu_map
  • Loading branch information
rafaeljw committed Dec 22, 2020
2 parents b4ec805 + e40ad84 commit c3a74f8
Show file tree
Hide file tree
Showing 10 changed files with 388 additions and 220 deletions.
3 changes: 2 additions & 1 deletion Documentation/ABI/testing/sysfs-devices-system-cpu
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,8 @@ Description: Discover CPUs in the same CPU frequency coordination domain
attribute is useful for user space DVFS controllers to get better
power/performance results for platforms using acpi-cpufreq.

This file is only present if the acpi-cpufreq driver is in use.
This file is only present if the acpi-cpufreq or the cppc-cpufreq
drivers are in use.


What: /sys/devices/system/cpu/cpu*/cache/index3/cache_disable_{0,1}
Expand Down
141 changes: 60 additions & 81 deletions drivers/acpi/cppc_acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,109 +414,88 @@ 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_possible_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.
* acpi_get_psd_map - Map the CPUs in the freq domain of a given cpu
* @cpu: Find all CPUs that share a domain with cpu.
* @cpu_data: Pointer to CPU specific CPPC data including PSD info.
*
* Return: 0 for success or negative value for err.
*/
int acpi_get_psd_map(struct cppc_cpudata **all_cpu_data)
int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data)
{
int count_target;
int retval = 0;
unsigned int i, j;
cpumask_var_t covered_cpus;
struct cppc_cpudata *pr, *match_pr;
struct acpi_psd_package *pdomain;
struct acpi_psd_package *match_pdomain;
struct cpc_desc *cpc_ptr, *match_cpc_ptr;

if (!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL))
return -ENOMEM;
struct acpi_psd_package *match_pdomain;
struct acpi_psd_package *pdomain;
int count_target, i;

/*
* Now that we have _PSD data from all CPUs, let's setup P-state
* domain info.
*/
for_each_possible_cpu(i) {
if (cpumask_test_cpu(i, covered_cpus))
continue;

pr = all_cpu_data[i];
cpc_ptr = per_cpu(cpc_desc_ptr, i);
if (!cpc_ptr) {
retval = -EFAULT;
goto err_ret;
}
cpc_ptr = per_cpu(cpc_desc_ptr, cpu);
if (!cpc_ptr)
return -EFAULT;

pdomain = &(cpc_ptr->domain_info);
cpumask_set_cpu(i, pr->shared_cpu_map);
cpumask_set_cpu(i, covered_cpus);
if (pdomain->num_processors <= 1)
continue;
pdomain = &(cpc_ptr->domain_info);
cpumask_set_cpu(cpu, cpu_data->shared_cpu_map);
if (pdomain->num_processors <= 1)
return 0;

/* Validate the Domain info */
count_target = pdomain->num_processors;
if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL)
pr->shared_type = CPUFREQ_SHARED_TYPE_ALL;
else if (pdomain->coord_type == DOMAIN_COORD_TYPE_HW_ALL)
pr->shared_type = CPUFREQ_SHARED_TYPE_HW;
else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY)
pr->shared_type = CPUFREQ_SHARED_TYPE_ANY;

for_each_possible_cpu(j) {
if (i == j)
continue;

match_cpc_ptr = per_cpu(cpc_desc_ptr, j);
if (!match_cpc_ptr) {
retval = -EFAULT;
goto err_ret;
}
/* Validate the Domain info */
count_target = pdomain->num_processors;
if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL)
cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ALL;
else if (pdomain->coord_type == DOMAIN_COORD_TYPE_HW_ALL)
cpu_data->shared_type = CPUFREQ_SHARED_TYPE_HW;
else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY)
cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY;

match_pdomain = &(match_cpc_ptr->domain_info);
if (match_pdomain->domain != pdomain->domain)
continue;
for_each_possible_cpu(i) {
if (i == cpu)
continue;

/* Here i and j are in the same domain */
if (match_pdomain->num_processors != count_target) {
retval = -EFAULT;
goto err_ret;
}
match_cpc_ptr = per_cpu(cpc_desc_ptr, i);
if (!match_cpc_ptr)
goto err_fault;

if (pdomain->coord_type != match_pdomain->coord_type) {
retval = -EFAULT;
goto err_ret;
}
match_pdomain = &(match_cpc_ptr->domain_info);
if (match_pdomain->domain != pdomain->domain)
continue;

cpumask_set_cpu(j, covered_cpus);
cpumask_set_cpu(j, pr->shared_cpu_map);
}
/* Here i and cpu are in the same domain */
if (match_pdomain->num_processors != count_target)
goto err_fault;

for_each_cpu(j, pr->shared_cpu_map) {
if (i == j)
continue;
if (pdomain->coord_type != match_pdomain->coord_type)
goto err_fault;

match_pr = all_cpu_data[j];
match_pr->shared_type = pr->shared_type;
cpumask_copy(match_pr->shared_cpu_map,
pr->shared_cpu_map);
}
cpumask_set_cpu(i, cpu_data->shared_cpu_map);
}
goto out;

err_ret:
for_each_possible_cpu(i) {
pr = all_cpu_data[i];
return 0;

/* Assume no coordination on any error parsing domain info */
cpumask_clear(pr->shared_cpu_map);
cpumask_set_cpu(i, pr->shared_cpu_map);
pr->shared_type = CPUFREQ_SHARED_TYPE_ALL;
}
out:
free_cpumask_var(covered_cpus);
return retval;
err_fault:
/* Assume no coordination on any error parsing domain info */
cpumask_clear(cpu_data->shared_cpu_map);
cpumask_set_cpu(cpu, cpu_data->shared_cpu_map);
cpu_data->shared_type = CPUFREQ_SHARED_TYPE_NONE;

return -EFAULT;
}
EXPORT_SYMBOL_GPL(acpi_get_psd_map);

Expand Down
3 changes: 1 addition & 2 deletions drivers/acpi/processor_perflib.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,6 @@ int acpi_processor_preregister_performance(
continue;

pr->performance = per_cpu_ptr(performance, i);
cpumask_set_cpu(i, pr->performance->shared_cpu_map);
pdomain = &(pr->performance->domain_info);
if (acpi_processor_get_psd(pr->handle, pdomain)) {
retval = -EINVAL;
Expand Down Expand Up @@ -710,7 +709,7 @@ int acpi_processor_preregister_performance(
if (retval) {
cpumask_clear(pr->performance->shared_cpu_map);
cpumask_set_cpu(i, pr->performance->shared_cpu_map);
pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ALL;
pr->performance->shared_type = CPUFREQ_SHARED_TYPE_NONE;
}
pr->performance = NULL; /* Will be set for real in register */
}
Expand Down
Loading

0 comments on commit c3a74f8

Please sign in to comment.