Merge branches 'pm-powercap' and 'pm-tools'

Merge power capping changes and power management utilities updates for
6.9-rc1:

 - Address multiple issues in the TPMI RAPL driver and add support for
   new platforms (Lunar Lake-M, Arrow Lake) to Intel RAPL (Zhang Rui).

 - Fix freq_qos_add_request() return value check in dtpm_cpu (Daniel
   Lezcano).

 - Fix kernel-doc for dtpm_create_hierarchy() (Yang Li).

 - Fix file leak in get_pkg_num() in x86_energy_perf_policy (Samasth
   Norway Ananda).

 - Fix cpupower-frequency-info.1 man page typo (Jan Kratochvil).

* pm-powercap:
  powercap: dtpm: Fix kernel-doc for dtpm_create_hierarchy() function
  powercap: dtpm_cpu: Fix error check against freq_qos_add_request()
  powercap: intel_rapl: Add support for Arrow Lake
  powercap: intel_rapl: Add support for Lunar Lake-M paltform
  powercap: intel_rapl_tpmi: Fix System Domain probing
  powercap: intel_rapl_tpmi: Fix a register bug
  powercap: intel_rapl: Fix locking in TPMI RAPL
  powercap: intel_rapl: Fix a NULL pointer dereference

* pm-tools:
  Fix cpupower-frequency-info.1 man page typo
  tools/power x86_energy_perf_policy: Fix file leak in get_pkg_num()
This commit is contained in:
Rafael J. Wysocki
2024-03-11 15:54:23 +01:00
9 changed files with 66 additions and 14 deletions

View File

@@ -522,7 +522,7 @@ static int dtpm_for_each_child(const struct dtpm_node *hierarchy,
/**
* dtpm_create_hierarchy - Create the dtpm hierarchy
* @hierarchy: An array of struct dtpm_node describing the hierarchy
* @dtpm_match_table: Pointer to the array of device ID structures
*
* The function is called by the platform specific code with the
* description of the different node in the hierarchy. It creates the

View File

@@ -219,7 +219,7 @@ static int __dtpm_cpu_setup(int cpu, struct dtpm *parent)
ret = freq_qos_add_request(&policy->constraints,
&dtpm_cpu->qos_req, FREQ_QOS_MAX,
pd->table[pd->nr_perf_states - 1].frequency);
if (ret)
if (ret < 0)
goto out_dtpm_unregister;
cpufreq_cpu_put(policy);

View File

@@ -5,6 +5,7 @@
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/cleanup.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/list.h>
@@ -759,6 +760,11 @@ static int rapl_config(struct rapl_package *rp)
default:
return -EINVAL;
}
/* defaults_msr can be NULL on unsupported platforms */
if (!rp->priv->defaults || !rp->priv->rpi)
return -ENODEV;
return 0;
}
@@ -1256,6 +1262,8 @@ static const struct x86_cpu_id rapl_ids[] __initconst = {
X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE_L, &rapl_defaults_core),
X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &rapl_defaults_spr_server),
X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X, &rapl_defaults_spr_server),
X86_MATCH_INTEL_FAM6_MODEL(LUNARLAKE_M, &rapl_defaults_core),
X86_MATCH_INTEL_FAM6_MODEL(ARROWLAKE, &rapl_defaults_core),
X86_MATCH_INTEL_FAM6_MODEL(LAKEFIELD, &rapl_defaults_core),
X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT, &rapl_defaults_byt),
@@ -1499,7 +1507,7 @@ static int rapl_detect_domains(struct rapl_package *rp)
}
/* called from CPU hotplug notifier, hotplug lock held */
void rapl_remove_package(struct rapl_package *rp)
void rapl_remove_package_cpuslocked(struct rapl_package *rp)
{
struct rapl_domain *rd, *rd_package = NULL;
@@ -1528,10 +1536,18 @@ void rapl_remove_package(struct rapl_package *rp)
list_del(&rp->plist);
kfree(rp);
}
EXPORT_SYMBOL_GPL(rapl_remove_package_cpuslocked);
void rapl_remove_package(struct rapl_package *rp)
{
guard(cpus_read_lock)();
rapl_remove_package_cpuslocked(rp);
}
EXPORT_SYMBOL_GPL(rapl_remove_package);
/* caller to ensure CPU hotplug lock is held */
struct rapl_package *rapl_find_package_domain(int id, struct rapl_if_priv *priv, bool id_is_cpu)
struct rapl_package *rapl_find_package_domain_cpuslocked(int id, struct rapl_if_priv *priv,
bool id_is_cpu)
{
struct rapl_package *rp;
int uid;
@@ -1549,10 +1565,17 @@ struct rapl_package *rapl_find_package_domain(int id, struct rapl_if_priv *priv,
return NULL;
}
EXPORT_SYMBOL_GPL(rapl_find_package_domain_cpuslocked);
struct rapl_package *rapl_find_package_domain(int id, struct rapl_if_priv *priv, bool id_is_cpu)
{
guard(cpus_read_lock)();
return rapl_find_package_domain_cpuslocked(id, priv, id_is_cpu);
}
EXPORT_SYMBOL_GPL(rapl_find_package_domain);
/* called from CPU hotplug notifier, hotplug lock held */
struct rapl_package *rapl_add_package(int id, struct rapl_if_priv *priv, bool id_is_cpu)
struct rapl_package *rapl_add_package_cpuslocked(int id, struct rapl_if_priv *priv, bool id_is_cpu)
{
struct rapl_package *rp;
int ret;
@@ -1598,6 +1621,13 @@ struct rapl_package *rapl_add_package(int id, struct rapl_if_priv *priv, bool id
kfree(rp);
return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(rapl_add_package_cpuslocked);
struct rapl_package *rapl_add_package(int id, struct rapl_if_priv *priv, bool id_is_cpu)
{
guard(cpus_read_lock)();
return rapl_add_package_cpuslocked(id, priv, id_is_cpu);
}
EXPORT_SYMBOL_GPL(rapl_add_package);
static void power_limit_state_save(void)

View File

@@ -73,9 +73,9 @@ static int rapl_cpu_online(unsigned int cpu)
{
struct rapl_package *rp;
rp = rapl_find_package_domain(cpu, rapl_msr_priv, true);
rp = rapl_find_package_domain_cpuslocked(cpu, rapl_msr_priv, true);
if (!rp) {
rp = rapl_add_package(cpu, rapl_msr_priv, true);
rp = rapl_add_package_cpuslocked(cpu, rapl_msr_priv, true);
if (IS_ERR(rp))
return PTR_ERR(rp);
}
@@ -88,14 +88,14 @@ static int rapl_cpu_down_prep(unsigned int cpu)
struct rapl_package *rp;
int lead_cpu;
rp = rapl_find_package_domain(cpu, rapl_msr_priv, true);
rp = rapl_find_package_domain_cpuslocked(cpu, rapl_msr_priv, true);
if (!rp)
return 0;
cpumask_clear_cpu(cpu, &rp->cpumask);
lead_cpu = cpumask_first(&rp->cpumask);
if (lead_cpu >= nr_cpu_ids)
rapl_remove_package(rp);
rapl_remove_package_cpuslocked(rp);
else if (rp->lead_cpu == cpu)
rp->lead_cpu = lead_cpu;
return 0;

View File

@@ -40,6 +40,7 @@ enum tpmi_rapl_register {
TPMI_RAPL_REG_ENERGY_STATUS,
TPMI_RAPL_REG_PERF_STATUS,
TPMI_RAPL_REG_POWER_INFO,
TPMI_RAPL_REG_DOMAIN_INFO,
TPMI_RAPL_REG_INTERRUPT,
TPMI_RAPL_REG_MAX = 15,
};
@@ -130,6 +131,12 @@ static void trp_release(struct tpmi_rapl_package *trp)
mutex_unlock(&tpmi_rapl_lock);
}
/*
* Bit 0 of TPMI_RAPL_REG_DOMAIN_INFO indicates if the current package is a domain
* root or not. Only domain root packages can enumerate System (Psys) Domain.
*/
#define TPMI_RAPL_DOMAIN_ROOT BIT(0)
static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset)
{
u8 tpmi_domain_version;
@@ -139,6 +146,7 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset)
enum rapl_domain_reg_id reg_id;
int tpmi_domain_size, tpmi_domain_flags;
u64 tpmi_domain_header = readq(trp->base + offset);
u64 tpmi_domain_info;
/* Domain Parent bits are ignored for now */
tpmi_domain_version = tpmi_domain_header & 0xff;
@@ -169,6 +177,13 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset)
domain_type = RAPL_DOMAIN_PACKAGE;
break;
case TPMI_RAPL_DOMAIN_SYSTEM:
if (!(tpmi_domain_flags & BIT(TPMI_RAPL_REG_DOMAIN_INFO))) {
pr_warn(FW_BUG "System domain must support Domain Info register\n");
return -ENODEV;
}
tpmi_domain_info = readq(trp->base + offset + TPMI_RAPL_REG_DOMAIN_INFO);
if (!(tpmi_domain_info & TPMI_RAPL_DOMAIN_ROOT))
return 0;
domain_type = RAPL_DOMAIN_PLATFORM;
break;
case TPMI_RAPL_DOMAIN_MEMORY:

View File

@@ -27,9 +27,9 @@ static int rapl_mmio_cpu_online(unsigned int cpu)
if (topology_physical_package_id(cpu))
return 0;
rp = rapl_find_package_domain(cpu, &rapl_mmio_priv, true);
rp = rapl_find_package_domain_cpuslocked(cpu, &rapl_mmio_priv, true);
if (!rp) {
rp = rapl_add_package(cpu, &rapl_mmio_priv, true);
rp = rapl_add_package_cpuslocked(cpu, &rapl_mmio_priv, true);
if (IS_ERR(rp))
return PTR_ERR(rp);
}
@@ -42,14 +42,14 @@ static int rapl_mmio_cpu_down_prep(unsigned int cpu)
struct rapl_package *rp;
int lead_cpu;
rp = rapl_find_package_domain(cpu, &rapl_mmio_priv, true);
rp = rapl_find_package_domain_cpuslocked(cpu, &rapl_mmio_priv, true);
if (!rp)
return 0;
cpumask_clear_cpu(cpu, &rp->cpumask);
lead_cpu = cpumask_first(&rp->cpumask);
if (lead_cpu >= nr_cpu_ids)
rapl_remove_package(rp);
rapl_remove_package_cpuslocked(rp);
else if (rp->lead_cpu == cpu)
rp->lead_cpu = lead_cpu;
return 0;

View File

@@ -178,6 +178,12 @@ struct rapl_package {
struct rapl_if_priv *priv;
};
struct rapl_package *rapl_find_package_domain_cpuslocked(int id, struct rapl_if_priv *priv,
bool id_is_cpu);
struct rapl_package *rapl_add_package_cpuslocked(int id, struct rapl_if_priv *priv,
bool id_is_cpu);
void rapl_remove_package_cpuslocked(struct rapl_package *rp);
struct rapl_package *rapl_find_package_domain(int id, struct rapl_if_priv *priv, bool id_is_cpu);
struct rapl_package *rapl_add_package(int id, struct rapl_if_priv *priv, bool id_is_cpu);
void rapl_remove_package(struct rapl_package *rp);

View File

@@ -32,7 +32,7 @@ Gets the currently used cpufreq policy.
\fB\-g\fR \fB\-\-governors\fR
Determines available cpufreq governors.
.TP
\fB\-a\fR \fB\-\-related\-cpus\fR
\fB\-r\fR \fB\-\-related\-cpus\fR
Determines which CPUs run at the same hardware frequency.
.TP
\fB\-a\fR \fB\-\-affected\-cpus\fR

View File

@@ -1241,6 +1241,7 @@ unsigned int get_pkg_num(int cpu)
retval = fscanf(fp, "%d\n", &pkg);
if (retval != 1)
errx(1, "%s: failed to parse", pathname);
fclose(fp);
return pkg;
}