• Vikram Mulukutla's avatar
    cpufreq: schedutil: Fix sugov_start() versus sugov_update_shared() race · ab2f7cf1
    Vikram Mulukutla authored
    With a shared policy in place, when one of the CPUs in the policy is
    hotplugged out and then brought back online, sugov_stop() and
    sugov_start() are called in order.
    
    sugov_stop() removes utilization hooks for each CPU in the policy and
    does nothing else in the for_each_cpu() loop. sugov_start() on the
    other hand iterates through the CPUs in the policy and re-initializes
    the per-cpu structure _and_ adds the utilization hook.  This implies
    that the scheduler is allowed to invoke a CPU's utilization update
    hook when the rest of the per-cpu structures have yet to be
    re-inited.
    
    Apart from some strange values in tracepoints this doesn't cause a
    problem, but if we do end up accessing a pointer from the per-cpu
    sugov_cpu structure somewhere in the sugov_update_shared() path,
    we will likely see crashes since the memset for another CPU in the
    policy is free to race with sugov_update_shared from the CPU that is
    ready to go.  So let's fix this now to first init all per-cpu
    structures, and then add the per-cpu utilization update hooks all at
    once.
    Signed-off-by: default avatarVikram Mulukutla <markivx@codeaurora.org>
    Acked-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    ab2f7cf1
cpufreq_schedutil.c 17.2 KB