Skip to content

Commit

Permalink
Merge tag 'pm-5.11-rc1-2' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/rafael/linux-pm

Pull more power management updates from Rafael Wysocki:
 "These update the CPPC cpufreq driver and intel_pstate (which involves
  updating the cpufreq core and the schedutil governor) and make
  janitorial changes in the ACPI code handling processor objects.

  Specifics:

   - Rework the passive-mode "fast switch" path in the intel_pstate
     driver to allow it receive the minimum (required) and target
     (desired) performance information from the schedutil governor so as
     to avoid running some workloads too fast (Rafael Wysocki).

   - Make the intel_pstate driver allow the policy max limit to be
     increased after the guaranteed performance value for the given CPU
     has increased (Rafael Wysocki).

   - Clean up the handling of CPU coordination types in the CPPC cpufreq
     driver and make it export frequency domains information to user
     space via sysfs (Ionela Voinescu).

   - Fix the ACPI code handling processor objects to use a correct
     coordination type when it fails to map frequency domains and drop a
     redundant CPU map initialization from it (Ionela Voinescu, Punit
     Agrawal)"

* tag 'pm-5.11-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  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
  • Loading branch information
torvalds committed Dec 22, 2020
2 parents 2762db7 + c3a74f8 commit 4960821
Show file tree
Hide file tree
Showing 10 changed files with 388 additions and 219 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
2 changes: 1 addition & 1 deletion drivers/acpi/processor_perflib.c
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,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 4960821

Please sign in to comment.