mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-10 04:29:11 -04:00
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:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user