Commit c907ab55 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

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()
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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);
+33 −3
Original line number Diff line number Diff line
@@ -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)
+4 −4
Original line number Diff line number Diff line
@@ -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;
+15 −0
Original line number Diff line number Diff line
@@ -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:
Loading