Skip to content

Commit cf3c8f8

Browse files
committed
Merge tag 'pm-5.6-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more power manadement updates from Rafael Wysocki: "Prevent cpufreq from creating excessively large stack frames and fix the handling of devices deleted during system-wide resume in the PM core (Rafael Wysocki), revert a problematic commit affecting the cpupower utility and correct its man page (Thomas Renninger, Brahadambal Srinivasan), and improve the intel_pstate_tracer utility (Doug Smythies)" * tag 'pm-5.6-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: tools/power/x86/intel_pstate_tracer: change several graphs to autoscale y-axis tools/power/x86/intel_pstate_tracer: changes for python 3 compatibility Correction to manpage of cpupower cpufreq: Avoid creating excessively large stack frames PM: core: Fix handling of devices deleted during system-wide resume cpupower: Revert library ABI changes from commit ae29170
2 parents a62aa6f + 82b2c6f commit cf3c8f8

File tree

17 files changed

+264
-171
lines changed

17 files changed

+264
-171
lines changed

drivers/base/power/main.c

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,38 @@ static void dpm_wait_for_suppliers(struct device *dev, bool async)
273273
device_links_read_unlock(idx);
274274
}
275275

276-
static void dpm_wait_for_superior(struct device *dev, bool async)
276+
static bool dpm_wait_for_superior(struct device *dev, bool async)
277277
{
278-
dpm_wait(dev->parent, async);
278+
struct device *parent;
279+
280+
/*
281+
* If the device is resumed asynchronously and the parent's callback
282+
* deletes both the device and the parent itself, the parent object may
283+
* be freed while this function is running, so avoid that by reference
284+
* counting the parent once more unless the device has been deleted
285+
* already (in which case return right away).
286+
*/
287+
mutex_lock(&dpm_list_mtx);
288+
289+
if (!device_pm_initialized(dev)) {
290+
mutex_unlock(&dpm_list_mtx);
291+
return false;
292+
}
293+
294+
parent = get_device(dev->parent);
295+
296+
mutex_unlock(&dpm_list_mtx);
297+
298+
dpm_wait(parent, async);
299+
put_device(parent);
300+
279301
dpm_wait_for_suppliers(dev, async);
302+
303+
/*
304+
* If the parent's callback has deleted the device, attempting to resume
305+
* it would be invalid, so avoid doing that then.
306+
*/
307+
return device_pm_initialized(dev);
280308
}
281309

282310
static void dpm_wait_for_consumers(struct device *dev, bool async)
@@ -621,7 +649,8 @@ static int device_resume_noirq(struct device *dev, pm_message_t state, bool asyn
621649
if (!dev->power.is_noirq_suspended)
622650
goto Out;
623651

624-
dpm_wait_for_superior(dev, async);
652+
if (!dpm_wait_for_superior(dev, async))
653+
goto Out;
625654

626655
skip_resume = dev_pm_may_skip_resume(dev);
627656

@@ -829,7 +858,8 @@ static int device_resume_early(struct device *dev, pm_message_t state, bool asyn
829858
if (!dev->power.is_late_suspended)
830859
goto Out;
831860

832-
dpm_wait_for_superior(dev, async);
861+
if (!dpm_wait_for_superior(dev, async))
862+
goto Out;
833863

834864
callback = dpm_subsys_resume_early_cb(dev, state, &info);
835865

@@ -944,7 +974,9 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
944974
goto Complete;
945975
}
946976

947-
dpm_wait_for_superior(dev, async);
977+
if (!dpm_wait_for_superior(dev, async))
978+
goto Complete;
979+
948980
dpm_watchdog_set(&wd, dev);
949981
device_lock(dev);
950982

drivers/cpufreq/cppc_cpufreq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ static int cppc_cpufreq_set_target(struct cpufreq_policy *policy,
221221
return ret;
222222
}
223223

224-
static int cppc_verify_policy(struct cpufreq_policy *policy)
224+
static int cppc_verify_policy(struct cpufreq_policy_data *policy)
225225
{
226226
cpufreq_verify_within_cpu_limits(policy);
227227
return 0;

drivers/cpufreq/cpufreq-nforce2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ static int nforce2_target(struct cpufreq_policy *policy,
291291
* nforce2_verify - verifies a new CPUFreq policy
292292
* @policy: new policy
293293
*/
294-
static int nforce2_verify(struct cpufreq_policy *policy)
294+
static int nforce2_verify(struct cpufreq_policy_data *policy)
295295
{
296296
unsigned int fsb_pol_max;
297297

drivers/cpufreq/cpufreq.c

Lines changed: 70 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ static void cpufreq_exit_governor(struct cpufreq_policy *policy);
7474
static int cpufreq_start_governor(struct cpufreq_policy *policy);
7575
static void cpufreq_stop_governor(struct cpufreq_policy *policy);
7676
static void cpufreq_governor_limits(struct cpufreq_policy *policy);
77+
static int cpufreq_set_policy(struct cpufreq_policy *policy,
78+
struct cpufreq_governor *new_gov,
79+
unsigned int new_pol);
7780

7881
/**
7982
* Two notifier lists: the "policy" list is involved in the
@@ -616,25 +619,22 @@ static struct cpufreq_governor *find_governor(const char *str_governor)
616619
return NULL;
617620
}
618621

619-
static int cpufreq_parse_policy(char *str_governor,
620-
struct cpufreq_policy *policy)
622+
static unsigned int cpufreq_parse_policy(char *str_governor)
621623
{
622-
if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
623-
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
624-
return 0;
625-
}
626-
if (!strncasecmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) {
627-
policy->policy = CPUFREQ_POLICY_POWERSAVE;
628-
return 0;
629-
}
630-
return -EINVAL;
624+
if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN))
625+
return CPUFREQ_POLICY_PERFORMANCE;
626+
627+
if (!strncasecmp(str_governor, "powersave", CPUFREQ_NAME_LEN))
628+
return CPUFREQ_POLICY_POWERSAVE;
629+
630+
return CPUFREQ_POLICY_UNKNOWN;
631631
}
632632

633633
/**
634634
* cpufreq_parse_governor - parse a governor string only for has_target()
635+
* @str_governor: Governor name.
635636
*/
636-
static int cpufreq_parse_governor(char *str_governor,
637-
struct cpufreq_policy *policy)
637+
static struct cpufreq_governor *cpufreq_parse_governor(char *str_governor)
638638
{
639639
struct cpufreq_governor *t;
640640

@@ -648,7 +648,7 @@ static int cpufreq_parse_governor(char *str_governor,
648648

649649
ret = request_module("cpufreq_%s", str_governor);
650650
if (ret)
651-
return -EINVAL;
651+
return NULL;
652652

653653
mutex_lock(&cpufreq_governor_mutex);
654654

@@ -659,12 +659,7 @@ static int cpufreq_parse_governor(char *str_governor,
659659

660660
mutex_unlock(&cpufreq_governor_mutex);
661661

662-
if (t) {
663-
policy->governor = t;
664-
return 0;
665-
}
666-
667-
return -EINVAL;
662+
return t;
668663
}
669664

670665
/**
@@ -765,28 +760,33 @@ static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
765760
static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
766761
const char *buf, size_t count)
767762
{
763+
char str_governor[16];
768764
int ret;
769-
char str_governor[16];
770-
struct cpufreq_policy new_policy;
771-
772-
memcpy(&new_policy, policy, sizeof(*policy));
773765

774766
ret = sscanf(buf, "%15s", str_governor);
775767
if (ret != 1)
776768
return -EINVAL;
777769

778770
if (cpufreq_driver->setpolicy) {
779-
if (cpufreq_parse_policy(str_governor, &new_policy))
771+
unsigned int new_pol;
772+
773+
new_pol = cpufreq_parse_policy(str_governor);
774+
if (!new_pol)
780775
return -EINVAL;
776+
777+
ret = cpufreq_set_policy(policy, NULL, new_pol);
781778
} else {
782-
if (cpufreq_parse_governor(str_governor, &new_policy))
779+
struct cpufreq_governor *new_gov;
780+
781+
new_gov = cpufreq_parse_governor(str_governor);
782+
if (!new_gov)
783783
return -EINVAL;
784-
}
785784

786-
ret = cpufreq_set_policy(policy, &new_policy);
785+
ret = cpufreq_set_policy(policy, new_gov,
786+
CPUFREQ_POLICY_UNKNOWN);
787787

788-
if (new_policy.governor)
789-
module_put(new_policy.governor->owner);
788+
module_put(new_gov->owner);
789+
}
790790

791791
return ret ? ret : count;
792792
}
@@ -1053,40 +1053,33 @@ __weak struct cpufreq_governor *cpufreq_default_governor(void)
10531053

10541054
static int cpufreq_init_policy(struct cpufreq_policy *policy)
10551055
{
1056-
struct cpufreq_governor *gov = NULL, *def_gov = NULL;
1057-
struct cpufreq_policy new_policy;
1058-
1059-
memcpy(&new_policy, policy, sizeof(*policy));
1060-
1061-
def_gov = cpufreq_default_governor();
1056+
struct cpufreq_governor *def_gov = cpufreq_default_governor();
1057+
struct cpufreq_governor *gov = NULL;
1058+
unsigned int pol = CPUFREQ_POLICY_UNKNOWN;
10621059

10631060
if (has_target()) {
1064-
/*
1065-
* Update governor of new_policy to the governor used before
1066-
* hotplug
1067-
*/
1061+
/* Update policy governor to the one used before hotplug. */
10681062
gov = find_governor(policy->last_governor);
10691063
if (gov) {
10701064
pr_debug("Restoring governor %s for cpu %d\n",
1071-
policy->governor->name, policy->cpu);
1072-
} else {
1073-
if (!def_gov)
1074-
return -ENODATA;
1065+
policy->governor->name, policy->cpu);
1066+
} else if (def_gov) {
10751067
gov = def_gov;
1068+
} else {
1069+
return -ENODATA;
10761070
}
1077-
new_policy.governor = gov;
10781071
} else {
10791072
/* Use the default policy if there is no last_policy. */
10801073
if (policy->last_policy) {
1081-
new_policy.policy = policy->last_policy;
1074+
pol = policy->last_policy;
1075+
} else if (def_gov) {
1076+
pol = cpufreq_parse_policy(def_gov->name);
10821077
} else {
1083-
if (!def_gov)
1084-
return -ENODATA;
1085-
cpufreq_parse_policy(def_gov->name, &new_policy);
1078+
return -ENODATA;
10861079
}
10871080
}
10881081

1089-
return cpufreq_set_policy(policy, &new_policy);
1082+
return cpufreq_set_policy(policy, gov, pol);
10901083
}
10911084

10921085
static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
@@ -1114,13 +1107,10 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cp
11141107

11151108
void refresh_frequency_limits(struct cpufreq_policy *policy)
11161109
{
1117-
struct cpufreq_policy new_policy;
1118-
11191110
if (!policy_is_inactive(policy)) {
1120-
new_policy = *policy;
11211111
pr_debug("updating policy for CPU %u\n", policy->cpu);
11221112

1123-
cpufreq_set_policy(policy, &new_policy);
1113+
cpufreq_set_policy(policy, policy->governor, policy->policy);
11241114
}
11251115
}
11261116
EXPORT_SYMBOL(refresh_frequency_limits);
@@ -2364,46 +2354,49 @@ EXPORT_SYMBOL(cpufreq_get_policy);
23642354
/**
23652355
* cpufreq_set_policy - Modify cpufreq policy parameters.
23662356
* @policy: Policy object to modify.
2367-
* @new_policy: New policy data.
2357+
* @new_gov: Policy governor pointer.
2358+
* @new_pol: Policy value (for drivers with built-in governors).
23682359
*
2369-
* Pass @new_policy to the cpufreq driver's ->verify() callback. Next, copy the
2370-
* min and max parameters of @new_policy to @policy and either invoke the
2371-
* driver's ->setpolicy() callback (if present) or carry out a governor update
2372-
* for @policy. That is, run the current governor's ->limits() callback (if the
2373-
* governor field in @new_policy points to the same object as the one in
2374-
* @policy) or replace the governor for @policy with the new one stored in
2375-
* @new_policy.
2360+
* Invoke the cpufreq driver's ->verify() callback to sanity-check the frequency
2361+
* limits to be set for the policy, update @policy with the verified limits
2362+
* values and either invoke the driver's ->setpolicy() callback (if present) or
2363+
* carry out a governor update for @policy. That is, run the current governor's
2364+
* ->limits() callback (if @new_gov points to the same object as the one in
2365+
* @policy) or replace the governor for @policy with @new_gov.
23762366
*
23772367
* The cpuinfo part of @policy is not updated by this function.
23782368
*/
2379-
int cpufreq_set_policy(struct cpufreq_policy *policy,
2380-
struct cpufreq_policy *new_policy)
2369+
static int cpufreq_set_policy(struct cpufreq_policy *policy,
2370+
struct cpufreq_governor *new_gov,
2371+
unsigned int new_pol)
23812372
{
2373+
struct cpufreq_policy_data new_data;
23822374
struct cpufreq_governor *old_gov;
23832375
int ret;
23842376

2385-
pr_debug("setting new policy for CPU %u: %u - %u kHz\n",
2386-
new_policy->cpu, new_policy->min, new_policy->max);
2387-
2388-
memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo));
2389-
2377+
memcpy(&new_data.cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo));
2378+
new_data.freq_table = policy->freq_table;
2379+
new_data.cpu = policy->cpu;
23902380
/*
23912381
* PM QoS framework collects all the requests from users and provide us
23922382
* the final aggregated value here.
23932383
*/
2394-
new_policy->min = freq_qos_read_value(&policy->constraints, FREQ_QOS_MIN);
2395-
new_policy->max = freq_qos_read_value(&policy->constraints, FREQ_QOS_MAX);
2384+
new_data.min = freq_qos_read_value(&policy->constraints, FREQ_QOS_MIN);
2385+
new_data.max = freq_qos_read_value(&policy->constraints, FREQ_QOS_MAX);
2386+
2387+
pr_debug("setting new policy for CPU %u: %u - %u kHz\n",
2388+
new_data.cpu, new_data.min, new_data.max);
23962389

23972390
/*
23982391
* Verify that the CPU speed can be set within these limits and make sure
23992392
* that min <= max.
24002393
*/
2401-
ret = cpufreq_driver->verify(new_policy);
2394+
ret = cpufreq_driver->verify(&new_data);
24022395
if (ret)
24032396
return ret;
24042397

2405-
policy->min = new_policy->min;
2406-
policy->max = new_policy->max;
2398+
policy->min = new_data.min;
2399+
policy->max = new_data.max;
24072400
trace_cpu_frequency_limits(policy);
24082401

24092402
policy->cached_target_freq = UINT_MAX;
@@ -2412,12 +2405,12 @@ int cpufreq_set_policy(struct cpufreq_policy *policy,
24122405
policy->min, policy->max);
24132406

24142407
if (cpufreq_driver->setpolicy) {
2415-
policy->policy = new_policy->policy;
2408+
policy->policy = new_pol;
24162409
pr_debug("setting range\n");
24172410
return cpufreq_driver->setpolicy(policy);
24182411
}
24192412

2420-
if (new_policy->governor == policy->governor) {
2413+
if (new_gov == policy->governor) {
24212414
pr_debug("governor limits update\n");
24222415
cpufreq_governor_limits(policy);
24232416
return 0;
@@ -2434,7 +2427,7 @@ int cpufreq_set_policy(struct cpufreq_policy *policy,
24342427
}
24352428

24362429
/* start new governor */
2437-
policy->governor = new_policy->governor;
2430+
policy->governor = new_gov;
24382431
ret = cpufreq_init_governor(policy);
24392432
if (!ret) {
24402433
ret = cpufreq_start_governor(policy);

drivers/cpufreq/freq_table.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
6060
return 0;
6161
}
6262

63-
int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
63+
int cpufreq_frequency_table_verify(struct cpufreq_policy_data *policy,
6464
struct cpufreq_frequency_table *table)
6565
{
6666
struct cpufreq_frequency_table *pos;
@@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify);
100100
* Generic routine to verify policy & frequency table, requires driver to set
101101
* policy->freq_table prior to it.
102102
*/
103-
int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy)
103+
int cpufreq_generic_frequency_table_verify(struct cpufreq_policy_data *policy)
104104
{
105105
if (!policy->freq_table)
106106
return -ENODEV;

drivers/cpufreq/gx-suspmod.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ static void gx_set_cpuspeed(struct cpufreq_policy *policy, unsigned int khz)
328328
* for the hardware supported by the driver.
329329
*/
330330

331-
static int cpufreq_gx_verify(struct cpufreq_policy *policy)
331+
static int cpufreq_gx_verify(struct cpufreq_policy_data *policy)
332332
{
333333
unsigned int tmp_freq = 0;
334334
u8 tmp1, tmp2;

0 commit comments

Comments
 (0)