cpufreq: Skip cpufreq resume if it's not suspended

"Linux Kernel Mailing List" <[email protected]>
Newsgroups gmane.linux.kernel.commits.head
Message-ID <[email protected]>
Web:        https://git.kernel.org/torvalds/c/703cbaa601ff3fb554d1246c336ba727cc083ea0
Commit:     703cbaa601ff3fb554d1246c336ba727cc083ea0
Parent:     7f3fdd40a7dfaa7405185250974b0fabd08c1f8b
Refname:    refs/heads/master
Author:     Bo Yan <[email protected]>
AuthorDate: Tue Jan 23 13:57:55 2018 -0800
Committer:  Rafael J. Wysocki <[email protected]>
CommitDate: Mon Feb 5 11:03:33 2018 +0100

    cpufreq: Skip cpufreq resume if it's not suspended
    
    cpufreq_resume can be called even without preceding cpufreq_suspend.
    This can happen in following scenario:
    
        suspend_devices_and_enter
           --> dpm_suspend_start
              --> dpm_prepare
                  --> device_prepare : this function errors out
              --> dpm_suspend: this is skipped due to dpm_prepare failure
                               this means cpufreq_suspend is skipped over
           --> goto Recover_platform, due to previous error
           --> goto Resume_devices
           --> dpm_resume_end
               --> dpm_resume
                   --> cpufreq_resume
    
    In case schedutil is used as frequency governor, cpufreq_resume will
    eventually call sugov_start, which does following:
    
        memset(sg_cpu, 0, sizeof(*sg_cpu));
        ....
    
    This effectively erases function pointer for frequency update, causing
    crash later on. The function pointer would have been set correctly if
    subsequent cpufreq_add_update_util_hook runs successfully, but that
    function returns earlier because cpufreq_suspend was not called:
    
        if (WARN_ON(per_cpu(cpufreq_update_util_data, cpu)))
                    return;
    
    The fix is to check cpufreq_suspended first, if it's false, that means
    cpufreq_suspend was not called in the first place, so do not resume
    cpufreq.
    
    Signed-off-by: Bo Yan <[email protected]>
    Acked-by: Viresh Kumar <[email protected]>
    [ rjw: Dropped printing a message ]
    Signed-off-by: Rafael J. Wysocki <[email protected]>
---
 drivers/cpufreq/cpufreq.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 421f318c0e66..de33ebf008ad 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1686,6 +1686,9 @@ void cpufreq_resume(void)
 	if (!cpufreq_driver)
 		return;
 
+	if (unlikely(!cpufreq_suspended))
+		return;
+
 	cpufreq_suspended = false;
 
 	if (!has_target() && !cpufreq_driver->resume)
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.