• Venkatesh Pallipadi's avatar
    [CPUFREQ] Fix ondemand vs suspend deadlock · 4ec223d0
    Venkatesh Pallipadi authored
    Rootcaused the bug to a deadlock in cpufreq and ondemand. Due to non-existent
    ordering between cpu_hotplug lock and dbs_mutex. Basically a race condition
    between cpu_down() and do_dbs_timer().
    
    cpu_down() flow:
    * cpu_down() call for CPU 1
    * Takes hot plug lock
    * Calls pre down notifier
    *     cpufreq notifier handler calls cpufreq_driver_target() which takes
          cpu_hotplug lock again. OK as cpu_hotplug lock is recursive in same
          process context
    * CPU 1 goes down
    * Calls post down notifier
    *     cpufreq notifier handler calls ondemand event stop which takes dbs_mutex
    
    So, cpu_hotplug lock is taken before dbs_mutex in this flow.
    
    do_dbs_timer is triggerred by a periodic timer event.
    It first takes dbs_mutex and then takes cpu_hotplug lock in
    cpufreq_driver_target().
    Note the reverse order here compared to above. So, if this timer event happens
    at right moment during cpu_down, system will deadlok.
    
    Attached patch fixes the issue for both ondemand and conservative.
    Signed-off-by: default avatarVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>
    Signed-off-by: default avatarDave Jones <davej@redhat.com>
    4ec223d0
cpufreq_conservative.c 15.2 KB