• Viresh Kumar's avatar
    cpufreq: move policy kobj to policy->cpu at resume · 92c14bd9
    Viresh Kumar authored
    This is only relevant to implementations with multiple clusters, where clusters
    have separate clock lines but all CPUs within a cluster share it.
    
    Consider a dual cluster platform with 2 cores per cluster. During suspend we
    start hot unplugging CPUs in order 1 to 3. When CPU2 is removed, policy->kobj
    would be moved to CPU3 and when CPU3 goes down we wouldn't free policy or its
    kobj as we want to retain permissions/values/etc.
    
    Now on resume, we will get CPU2 before CPU3 and will call __cpufreq_add_dev().
    We will recover the old policy and update policy->cpu from 3 to 2 from
    update_policy_cpu().
    
    But the kobj is still tied to CPU3 and isn't moved to CPU2. We wouldn't create a
    link for CPU2, but would try that for CPU3 while bringing it online. Which will
    report errors as CPU3 already has kobj assigned to it.
    
    This bug got introduced with commit 42f921a6, which overlooked this scenario.
    
    To fix this, lets move kobj to the new policy->cpu while bringing first CPU of a
    cluster back. Also do a WARN_ON() if kobject_move failed, as we would reach here
    only for the first CPU of a non-boot cluster. And we can't recover from this
    situation, if kobject_move() fails.
    
    Fixes: 42f921a6 (cpufreq: remove sysfs files for CPUs which failed to come back after resume)
    Cc:  3.13+ <stable@vger.kernel.org> # 3.13+
    Reported-and-tested-by: default avatarBu Yitian <ybu@qti.qualcomm.com>
    Reported-by: default avatarSaravana Kannan <skannan@codeaurora.org>
    Reviewed-by: default avatarSrivatsa S. Bhat <srivatsa@mit.edu>
    Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    92c14bd9
cpufreq.c 64.5 KB