• Viresh Kumar's avatar
    cpufreq: Initialize the governor again while restoring policy · 35afd02e
    Viresh Kumar authored
    When all CPUs of a policy are hot-unplugged, we EXIT the governor but
    don't mark policy->governor as NULL. This was done in order to keep last
    used governor's information intact in sysfs, while the CPUs are offline.
    
    But we also need to clear policy->governor when restoring the policy.
    
    Because policy->governor still points to the last governor while policy
    is restored, following sequence of event happens:
     - cpufreq_init_policy() called while restoring policy
     - find_governor() matches last_governor string for present governors and
       returns last used governor's pointer, say ondemand. policy->governor
       already has the same address, unless the governor was removed in
       between.
     - cpufreq_set_policy() is called with both old/new policies governor set
       as ondemand.
     - Because governors matched, we skip governor initialization and return
       after calling __cpufreq_governor(CPUFREQ_GOV_LIMITS). Because the
       governor wasn't initialized for this policy, it returned -EBUSY.
     - cpufreq_init_policy() exits the policy on this error, but doesn't
       destroy it properly (should be fixed separately).
     - And so we enter a scenario where the policy isn't completely
       initialized but used.
    
    Fix this by setting policy->governor to NULL while restoring the policy.
    Reported-and-tested-by: default avatarPi-Cheng Chen <pi-cheng.chen@linaro.org>
    Reported-and-tested-by: default avatar"Jon Medhurst (Tixy)" <tixy@linaro.org>
    Reported-and-tested-by: default avatarSteven Rostedt <rostedt@goodmis.org>
    Fixes: 18bf3a12 (cpufreq: Mark policy->governor = NULL for inactive policies)
    Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    35afd02e
cpufreq.c 66.8 KB