From c749c64f45fa07d20e11af2e3f3caa9d7650d341 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 12 May 2016 00:46:45 +0200 Subject: intel_pstate: Simplify conditional in intel_pstate_set_policy() One of the if () statements in intel_pstate_set_policy() causes another if () to be evaluated if the condition is true and it doesn't do anything else, so merge the two if () statements into one. No functional changes. Signed-off-by: Rafael J. Wysocki Acked-by: Srinivas Pandruvada --- drivers/cpufreq/intel_pstate.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index b76a98dd9988..3a9c4325d6e2 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -1461,12 +1461,11 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) intel_pstate_clear_update_util_hook(policy->cpu); cpu = all_cpu_data[0]; - if (cpu->pstate.max_pstate_physical > cpu->pstate.max_pstate) { - if (policy->max < policy->cpuinfo.max_freq && - policy->max > cpu->pstate.max_pstate * cpu->pstate.scaling) { - pr_debug("policy->max > max non turbo frequency\n"); - policy->max = policy->cpuinfo.max_freq; - } + if (cpu->pstate.max_pstate_physical > cpu->pstate.max_pstate && + policy->max < policy->cpuinfo.max_freq && + policy->max > cpu->pstate.max_pstate * cpu->pstate.scaling) { + pr_debug("policy->max > max non turbo frequency\n"); + policy->max = policy->cpuinfo.max_freq; } if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { -- cgit v1.2.3-58-ga151 From 36be3418eb769c66bc16eb1c9b402591cf1219b7 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 12 May 2016 15:13:35 +0200 Subject: cpufreq: governor: CPUFREQ_GOV_POLICY_EXIT never fails None of the cpufreq governors currently in the tree will ever fail an invocation of the ->governor() callback with the event argument equal to CPUFREQ_GOV_POLICY_EXIT (unless invoked with incorrect arguments which doesn't matter anyway) and it wouldn't really make sense to fail it, because the caller won't be able to handle that failure in a meaningful way. Accordingly, rearrange the code in the core to make it clear that this call never fails. Signed-off-by: Rafael J. Wysocki Acked-by: Viresh Kumar --- drivers/cpufreq/cpufreq.c | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 035513b012ee..74ab6f79145b 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -78,9 +78,9 @@ static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); static unsigned int __cpufreq_get(struct cpufreq_policy *policy); static int cpufreq_start_governor(struct cpufreq_policy *policy); -static inline int cpufreq_exit_governor(struct cpufreq_policy *policy) +static inline void cpufreq_exit_governor(struct cpufreq_policy *policy) { - return cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); + (void)cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); } /** @@ -1387,12 +1387,8 @@ static void cpufreq_offline(unsigned int cpu) if (cpufreq_driver->stop_cpu) cpufreq_driver->stop_cpu(policy); - /* If cpu is last user of policy, free policy */ - if (has_target()) { - ret = cpufreq_exit_governor(policy); - if (ret) - pr_err("%s: Failed to exit governor\n", __func__); - } + if (has_target()) + cpufreq_exit_governor(policy); /* * Perform the ->exit() even during light-weight tear-down, @@ -2049,16 +2045,15 @@ static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) ret = policy->governor->governor(policy, event); - if (!ret) { - if (event == CPUFREQ_GOV_POLICY_INIT) + if (event == CPUFREQ_GOV_POLICY_INIT) { + if (ret) + module_put(policy->governor->owner); + else policy->governor->initialized++; - else if (event == CPUFREQ_GOV_POLICY_EXIT) - policy->governor->initialized--; - } - - if (((event == CPUFREQ_GOV_POLICY_INIT) && ret) || - ((event == CPUFREQ_GOV_POLICY_EXIT) && !ret)) + } else if (event == CPUFREQ_GOV_POLICY_EXIT) { + policy->governor->initialized--; module_put(policy->governor->owner); + } return ret; } @@ -2228,13 +2223,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, __func__, old_gov->name, ret); return ret; } - - ret = cpufreq_exit_governor(policy); - if (ret) { - pr_err("%s: Failed to Exit Governor: %s (%d)\n", - __func__, old_gov->name, ret); - return ret; - } + cpufreq_exit_governor(policy); } /* start new governor */ -- cgit v1.2.3-58-ga151 From 45482c703b8c7e86e339e92f186cadd9a735fd0e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 12 May 2016 15:14:12 +0200 Subject: cpufreq: governor: CPUFREQ_GOV_STOP never fails None of the cpufreq governors currently in the tree will ever fail an invocation of the ->governor() callback with the event argument equal to CPUFREQ_GOV_STOP (unless invoked with incorrect arguments which doesn't matter anyway) and it is rather difficult to imagine a valid reason for such a failure. Accordingly, rearrange the code in the core to make it clear that this call never fails. Signed-off-by: Rafael J. Wysocki Acked-by: Viresh Kumar --- drivers/cpufreq/cpufreq.c | 40 +++++++++++----------------------------- 1 file changed, 11 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 74ab6f79145b..d199256d84c0 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -83,6 +83,11 @@ static inline void cpufreq_exit_governor(struct cpufreq_policy *policy) (void)cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); } +static inline void cpufreq_stop_governor(struct cpufreq_policy *policy) +{ + (void)cpufreq_governor(policy, CPUFREQ_GOV_STOP); +} + /** * Two notifier lists: the "policy" list is involved in the * validation process for a new CPU frequency policy; the @@ -1026,13 +1031,8 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cp return 0; down_write(&policy->rwsem); - if (has_target()) { - ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); - if (ret) { - pr_err("%s: Failed to stop governor\n", __func__); - goto unlock; - } - } + if (has_target()) + cpufreq_stop_governor(policy); cpumask_set_cpu(cpu, policy->cpus); @@ -1041,8 +1041,6 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cp if (ret) pr_err("%s: Failed to start governor\n", __func__); } - -unlock: up_write(&policy->rwsem); return ret; } @@ -1354,11 +1352,8 @@ static void cpufreq_offline(unsigned int cpu) } down_write(&policy->rwsem); - if (has_target()) { - ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); - if (ret) - pr_err("%s: Failed to stop governor\n", __func__); - } + if (has_target()) + cpufreq_stop_governor(policy); cpumask_clear_cpu(cpu, policy->cpus); @@ -1622,7 +1617,6 @@ EXPORT_SYMBOL(cpufreq_generic_suspend); void cpufreq_suspend(void) { struct cpufreq_policy *policy; - int ret; if (!cpufreq_driver) return; @@ -1635,14 +1629,8 @@ void cpufreq_suspend(void) for_each_active_policy(policy) { if (has_target()) { down_write(&policy->rwsem); - ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); + cpufreq_stop_governor(policy); up_write(&policy->rwsem); - - if (ret) { - pr_err("%s: Failed to stop governor for policy: %p\n", - __func__, policy); - continue; - } } if (cpufreq_driver->suspend && cpufreq_driver->suspend(policy)) @@ -2216,13 +2204,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, old_gov = policy->governor; /* end old governor */ if (old_gov) { - ret = cpufreq_governor(policy, CPUFREQ_GOV_STOP); - if (ret) { - /* This can happen due to race with other operations */ - pr_debug("%s: Failed to Stop Governor: %s (%d)\n", - __func__, old_gov->name, ret); - return ret; - } + cpufreq_stop_governor(policy); cpufreq_exit_governor(policy); } -- cgit v1.2.3-58-ga151 From 3834abb4e64483af7af7500e54c0a5f957a52b1b Mon Sep 17 00:00:00 2001 From: Pankaj Gupta Date: Mon, 16 May 2016 11:07:19 +0000 Subject: cpufreq: simplified goto out in cpufreq_register_driver() simplified goto out in cpufreq_register_driver for increasing code readability Signed-off-by: Pankaj Gupta Signed-off-by: Sanjeev Yadav Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index d199256d84c0..36bc11a106aa 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2466,10 +2466,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) register_hotcpu_notifier(&cpufreq_cpu_notifier); pr_debug("driver %s up and running\n", driver_data->name); - -out: - put_online_cpus(); - return ret; + goto out; err_if_unreg: subsys_interface_unregister(&cpufreq_interface); @@ -2479,7 +2476,9 @@ err_null_driver: write_lock_irqsave(&cpufreq_driver_lock, flags); cpufreq_driver = NULL; write_unlock_irqrestore(&cpufreq_driver_lock, flags); - goto out; +out: + put_online_cpus(); + return ret; } EXPORT_SYMBOL_GPL(cpufreq_register_driver); -- cgit v1.2.3-58-ga151 From e7387da52028b072489c45efeb7a916c0205ebd2 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Tue, 17 May 2016 16:54:00 +0200 Subject: cpuidle: Fix cpuidle_state_is_coupled() argument in cpuidle_enter() Commit 0b89e9aa2856 (cpuidle: delay enabling interrupts until all coupled CPUs leave idle) rightfully fixed a regression by letting the coupled idle state framework to handle local interrupt enabling when the CPU is exiting an idle state. The current code checks if the idle state is coupled and, if so, it will let the coupled code to enable interrupts. This way, it can decrement the ready-count before handling the interrupt. This mechanism prevents the other CPUs from waiting for a CPU which is handling interrupts. But the check is done against the state index returned by the back end driver's ->enter functions which could be different from the initial index passed as parameter to the cpuidle_enter_state() function. entered_state = target_state->enter(dev, drv, index); [ ... ] if (!cpuidle_state_is_coupled(drv, entered_state)) local_irq_enable(); [ ... ] If the 'index' is referring to a coupled idle state but the 'entered_state' is *not* coupled, then the interrupts are enabled again. All CPUs blocked on the sync barrier may busy loop longer if the CPU has interrupts to handle before decrementing the ready-count. That's consuming more energy than saving. Fixes: 0b89e9aa2856 (cpuidle: delay enabling interrupts until all coupled CPUs leave idle) Signed-off-by: Daniel Lezcano Cc: 3.15+ # 3.15+ [ rjw: Subject & changelog ] Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/cpuidle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 2b8e6ce62e81..a4d0059e232c 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -214,7 +214,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, tick_broadcast_exit(); } - if (!cpuidle_state_is_coupled(drv, entered_state)) + if (!cpuidle_state_is_coupled(drv, index)) local_irq_enable(); /* -- cgit v1.2.3-58-ga151 From 3a17fb329da68cb00558721aff876a80bba2fdb9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 20 May 2016 23:09:49 +0200 Subject: PM / sleep: Handle failures in device_suspend_late() consistently Grygorii Strashko reports: The PM runtime will be left disabled for the device if its .suspend_late() callback fails and async suspend is not allowed for this device. In this case device will not be added in dpm_late_early_list and dpm_resume_early() will ignore this device, as result PM runtime will be disabled for it forever (side effect: after 8 subsequent failures for the same device the PM runtime will be reenabled due to disable_depth overflow). To fix this problem, add devices to dpm_late_early_list regardless of whether or not device_suspend_late() returns errors for them. That will ensure failures in there to be handled consistently for all devices regardless of their async suspend/resume status. Reported-by: Grygorii Strashko Tested-by: Grygorii Strashko Signed-off-by: Rafael J. Wysocki Cc: All applicable --- drivers/base/power/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index c81667d4bb60..e44944f4be77 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1267,14 +1267,15 @@ int dpm_suspend_late(pm_message_t state) error = device_suspend_late(dev); mutex_lock(&dpm_list_mtx); + if (!list_empty(&dev->power.entry)) + list_move(&dev->power.entry, &dpm_late_early_list); + if (error) { pm_dev_err(dev, state, " late", error); dpm_save_failed_dev(dev_name(dev)); put_device(dev); break; } - if (!list_empty(&dev->power.entry)) - list_move(&dev->power.entry, &dpm_late_early_list); put_device(dev); if (async_error) -- cgit v1.2.3-58-ga151