• Rafael J. Wysocki's avatar
    cpufreq: Avoid cpufreq_suspend() deadlock on system shutdown · 65650b35
    Rafael J. Wysocki authored
    It is incorrect to set the cpufreq syscore shutdown callback pointer
    to cpufreq_suspend(), because that function cannot be run in the
    syscore stage of system shutdown for two reasons: (a) it may attempt
    to carry out actions depending on devices that have already been shut
    down at that point and (b) the RCU synchronization carried out by it
    may not be able to make progress then.
    
    The latter issue has been present since commit 45975c7d ("rcu:
    Define RCU-sched API in terms of RCU for Tree RCU PREEMPT builds"),
    but the former one has been there since commit 90de2a4a ("cpufreq:
    suspend cpufreq governors on shutdown") regardless.
    
    Fix that by dropping cpufreq_syscore_ops altogether and making
    device_shutdown() call cpufreq_suspend() directly before shutting
    down devices, which is along the lines of what system-wide power
    management does.
    
    Fixes: 45975c7d ("rcu: Define RCU-sched API in terms of RCU for Tree RCU PREEMPT builds")
    Fixes: 90de2a4a ("cpufreq: suspend cpufreq governors on shutdown")
    Reported-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
    Tested-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    Acked-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
    Cc: 4.0+ <stable@vger.kernel.org> # 4.0+
    65650b35
cpufreq.c 71 KB