Skip to content

Commit eb23a11

Browse files
committed
Merge tag 'pm-6.19-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management fixes from Rafael Wysocki: "These fix three issues in the power capping code including one recent regression and a runtime PM framework regression introduced during the 6.17 development cycle: - Fix CPU hotplug locking deadlock reported by lockdep after a recent update of the Intel RAPL power capping driver (Srinivas Pandruvada) - Fix sscanf() error return value handling in the power capping core and a race condition in register_control_type() (Sumeet Pawnikar) - Fix a concurrent bit field update issue in the runtime PM core code by only updating the bit field in question when runtime PM is disabled (Rafael Wysocki)" * tag 'pm-6.19-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: powercap: intel_rapl: Fix possible recursive lock warning PM: runtime: Do not clear needs_force_resume with enabled runtime PM powercap: fix sscanf() error return value handling powercap: fix race condition in register_control_type()
2 parents 14e0e8d + 277141a commit eb23a11

5 files changed

Lines changed: 50 additions & 26 deletions

File tree

drivers/base/power/runtime.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1868,16 +1868,18 @@ void pm_runtime_init(struct device *dev)
18681868
*/
18691869
void pm_runtime_reinit(struct device *dev)
18701870
{
1871-
if (!pm_runtime_enabled(dev)) {
1872-
if (dev->power.runtime_status == RPM_ACTIVE)
1873-
pm_runtime_set_suspended(dev);
1874-
if (dev->power.irq_safe) {
1875-
spin_lock_irq(&dev->power.lock);
1876-
dev->power.irq_safe = 0;
1877-
spin_unlock_irq(&dev->power.lock);
1878-
if (dev->parent)
1879-
pm_runtime_put(dev->parent);
1880-
}
1871+
if (pm_runtime_enabled(dev))
1872+
return;
1873+
1874+
if (dev->power.runtime_status == RPM_ACTIVE)
1875+
pm_runtime_set_suspended(dev);
1876+
1877+
if (dev->power.irq_safe) {
1878+
spin_lock_irq(&dev->power.lock);
1879+
dev->power.irq_safe = 0;
1880+
spin_unlock_irq(&dev->power.lock);
1881+
if (dev->parent)
1882+
pm_runtime_put(dev->parent);
18811883
}
18821884
/*
18831885
* Clear power.needs_force_resume in case it has been set by

drivers/powercap/intel_rapl_common.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,16 +2032,14 @@ static int rapl_pmu_update(struct rapl_package *rp)
20322032
return ret;
20332033
}
20342034

2035-
int rapl_package_add_pmu(struct rapl_package *rp)
2035+
int rapl_package_add_pmu_locked(struct rapl_package *rp)
20362036
{
20372037
struct rapl_package_pmu_data *data = &rp->pmu_data;
20382038
int idx;
20392039

20402040
if (rp->has_pmu)
20412041
return -EEXIST;
20422042

2043-
guard(cpus_read_lock)();
2044-
20452043
for (idx = 0; idx < rp->nr_domains; idx++) {
20462044
struct rapl_domain *rd = &rp->domains[idx];
20472045
int domain = rd->id;
@@ -2091,17 +2089,23 @@ int rapl_package_add_pmu(struct rapl_package *rp)
20912089

20922090
return rapl_pmu_update(rp);
20932091
}
2092+
EXPORT_SYMBOL_GPL(rapl_package_add_pmu_locked);
2093+
2094+
int rapl_package_add_pmu(struct rapl_package *rp)
2095+
{
2096+
guard(cpus_read_lock)();
2097+
2098+
return rapl_package_add_pmu_locked(rp);
2099+
}
20942100
EXPORT_SYMBOL_GPL(rapl_package_add_pmu);
20952101

2096-
void rapl_package_remove_pmu(struct rapl_package *rp)
2102+
void rapl_package_remove_pmu_locked(struct rapl_package *rp)
20972103
{
20982104
struct rapl_package *pos;
20992105

21002106
if (!rp->has_pmu)
21012107
return;
21022108

2103-
guard(cpus_read_lock)();
2104-
21052109
list_for_each_entry(pos, &rapl_packages, plist) {
21062110
/* PMU is still needed */
21072111
if (pos->has_pmu && pos != rp)
@@ -2111,6 +2115,14 @@ void rapl_package_remove_pmu(struct rapl_package *rp)
21112115
perf_pmu_unregister(&rapl_pmu.pmu);
21122116
memset(&rapl_pmu, 0, sizeof(struct rapl_pmu));
21132117
}
2118+
EXPORT_SYMBOL_GPL(rapl_package_remove_pmu_locked);
2119+
2120+
void rapl_package_remove_pmu(struct rapl_package *rp)
2121+
{
2122+
guard(cpus_read_lock)();
2123+
2124+
rapl_package_remove_pmu_locked(rp);
2125+
}
21142126
EXPORT_SYMBOL_GPL(rapl_package_remove_pmu);
21152127
#endif
21162128

drivers/powercap/intel_rapl_msr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ static int rapl_cpu_online(unsigned int cpu)
8282
if (IS_ERR(rp))
8383
return PTR_ERR(rp);
8484
if (rapl_msr_pmu)
85-
rapl_package_add_pmu(rp);
85+
rapl_package_add_pmu_locked(rp);
8686
}
8787
cpumask_set_cpu(cpu, &rp->cpumask);
8888
return 0;
@@ -101,7 +101,7 @@ static int rapl_cpu_down_prep(unsigned int cpu)
101101
lead_cpu = cpumask_first(&rp->cpumask);
102102
if (lead_cpu >= nr_cpu_ids) {
103103
if (rapl_msr_pmu)
104-
rapl_package_remove_pmu(rp);
104+
rapl_package_remove_pmu_locked(rp);
105105
rapl_remove_package_cpuslocked(rp);
106106
} else if (rp->lead_cpu == cpu) {
107107
rp->lead_cpu = lead_cpu;

drivers/powercap/powercap_sys.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static ssize_t show_constraint_##_attr(struct device *dev, \
6868
int id; \
6969
struct powercap_zone_constraint *pconst;\
7070
\
71-
if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \
71+
if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \
7272
return -EINVAL; \
7373
if (id >= power_zone->const_id_cnt) \
7474
return -EINVAL; \
@@ -93,7 +93,7 @@ static ssize_t store_constraint_##_attr(struct device *dev,\
9393
int id; \
9494
struct powercap_zone_constraint *pconst;\
9595
\
96-
if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \
96+
if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \
9797
return -EINVAL; \
9898
if (id >= power_zone->const_id_cnt) \
9999
return -EINVAL; \
@@ -162,7 +162,7 @@ static ssize_t show_constraint_name(struct device *dev,
162162
ssize_t len = -ENODATA;
163163
struct powercap_zone_constraint *pconst;
164164

165-
if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id))
165+
if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1)
166166
return -EINVAL;
167167
if (id >= power_zone->const_id_cnt)
168168
return -EINVAL;
@@ -625,17 +625,23 @@ struct powercap_control_type *powercap_register_control_type(
625625
INIT_LIST_HEAD(&control_type->node);
626626
control_type->dev.class = &powercap_class;
627627
dev_set_name(&control_type->dev, "%s", name);
628-
result = device_register(&control_type->dev);
629-
if (result) {
630-
put_device(&control_type->dev);
631-
return ERR_PTR(result);
632-
}
633628
idr_init(&control_type->idr);
634629

635630
mutex_lock(&powercap_cntrl_list_lock);
636631
list_add_tail(&control_type->node, &powercap_cntrl_list);
637632
mutex_unlock(&powercap_cntrl_list_lock);
638633

634+
result = device_register(&control_type->dev);
635+
if (result) {
636+
mutex_lock(&powercap_cntrl_list_lock);
637+
list_del(&control_type->node);
638+
mutex_unlock(&powercap_cntrl_list_lock);
639+
640+
idr_destroy(&control_type->idr);
641+
put_device(&control_type->dev);
642+
return ERR_PTR(result);
643+
}
644+
639645
return control_type;
640646
}
641647
EXPORT_SYMBOL_GPL(powercap_register_control_type);

include/linux/intel_rapl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,14 @@ void rapl_remove_package(struct rapl_package *rp);
214214

215215
#ifdef CONFIG_PERF_EVENTS
216216
int rapl_package_add_pmu(struct rapl_package *rp);
217+
int rapl_package_add_pmu_locked(struct rapl_package *rp);
217218
void rapl_package_remove_pmu(struct rapl_package *rp);
219+
void rapl_package_remove_pmu_locked(struct rapl_package *rp);
218220
#else
219221
static inline int rapl_package_add_pmu(struct rapl_package *rp) { return 0; }
222+
static inline int rapl_package_add_pmu_locked(struct rapl_package *rp) { return 0; }
220223
static inline void rapl_package_remove_pmu(struct rapl_package *rp) { }
224+
static inline void rapl_package_remove_pmu_locked(struct rapl_package *rp) { }
221225
#endif
222226

223227
#endif /* __INTEL_RAPL_H__ */

0 commit comments

Comments
 (0)