powercap: intel_rapl: Fix locking in TPMI RAPL
ANBZ: #9468 commit1aa09b9379
upstream. The RAPL framework uses CPU hotplug locking to protect the rapl_packages list and rp->lead_cpu to guarantee that 1. the RAPL package device is not unprobed and freed 2. the cached rp->lead_cpu is always valid for operations like powercap sysfs accesses. Current RAPL APIs assume being called from CPU hotplug callbacks which hold the CPU hotplug lock, but TPMI RAPL driver invokes the APIs in the driver's .probe() function without acquiring the CPU hotplug lock. Fix the problem by providing both locked and lockless versions of RAPL APIs. Intel-SIG: commit1aa09b9379
powercap: intel_rapl: Fix locking in TPMI RAPL Backport Intel RAPL bugfixes up to upstream 6.9 to kernel 5.10. Use cpus_read_lock()/cpus_read_unlock() as the funciton lock instead of the guard macro of the cleanup framework which doesn't exist in kernel 5.10. Fixes:9eef7f9da9
("powercap: intel_rapl: Introduce RAPL TPMI interface driver") Signed-off-by: Zhang Rui <rui.zhang@intel.com> Cc: 6.5+ <stable@vger.kernel.org> # 6.5+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> [ Xiaolong Wang: amend commit log ] Signed-off-by: Xiaolong Wang <xiaolong.wang@intel.com> Reviewed-by: Artie Ding <artie.ding@linux.alibaba.com> Link: https://gitee.com/anolis/cloud-kernel/pulls/3470
This commit is contained in:
parent
02036037a8
commit
98f5223175
|
@ -1489,7 +1489,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;
|
||||
|
||||
|
@ -1518,10 +1518,19 @@ 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)
|
||||
{
|
||||
cpus_read_lock();
|
||||
rapl_remove_package_cpuslocked(rp);
|
||||
cpus_read_unlock();
|
||||
}
|
||||
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;
|
||||
|
@ -1539,10 +1548,20 @@ 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)
|
||||
{
|
||||
struct rapl_package *rp;
|
||||
cpus_read_lock();
|
||||
rp = rapl_find_package_domain_cpuslocked(id, priv, id_is_cpu);
|
||||
cpus_read_unlock();
|
||||
return rp;
|
||||
}
|
||||
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;
|
||||
|
@ -1588,6 +1607,16 @@ err_free_package:
|
|||
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)
|
||||
{
|
||||
struct rapl_package *rp;
|
||||
cpus_read_lock();
|
||||
rp = rapl_add_package_cpuslocked(id, priv, id_is_cpu);
|
||||
cpus_read_unlock();
|
||||
return rp;
|
||||
}
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue