• V
    [CPUFREQ] Eliminate cpufreq_userspace scaling_setspeed deadlock · 9e76988e
    Venki Pallipadi 提交于
    Eliminate cpufreq_userspace scaling_setspeed deadlock.
    
    Luming Yu recently uncovered yet another cpufreq related deadlock.
    One thread that continuously switches the governors and the other thread that
    repeatedly cats the contents of cpufreq directory causes both these threads to
    go into a deadlock.
    
    Detailed examination of the deadlock showed the exact flow before the deadlock
    as:
    
    Thread 1			Thread 2
    ________			________
    				cats files under /sys/devices/.../cpufreq/
    Set governor to userspace
      Adds a new sysfs entry for
      scaling_setspeed
    				cats files under /sys/devices/.../cpufreq/
    
    Set governor to performance
      Holds cpufreq_rw_sem in write
      mode
      Sends a STOP notify to
      userspace governor
    				cat /sys/devices/.../cpufreq/scaling_setspeed
    				  Gets a handle on the above sysfs entry with
    				  sysfs_get_active
    				  Blocks while trying to get cpufreq_rw_sem
    				  in read mode
      Remove a sysfs entry for
      scaling_setspeed
        Blocks on sysfs_deactivate
        while waiting for earlier
        get_active (on other thread)
        to drain
    
    At this point both threads go into deadlock and any other thread that tries to
    do anything with sysfs cpufreq will also block.
    
    There seems to be no easy way to avoid this deadlock as long as
    cpufreq_userspace adds/removes the sysfs entry under same kobject as cpufreq.
    Below patch moves scaling_setspeed to cpufreq.c, keeping it always and calling
    back the governor on read/write. This is the cleanest fix I could think of,
    even though adding two callbacks in governor structure just for this seems
    unnecessary.
    
    Note that the change makes scaling_setspeed under /sys/.../cpufreq permanent
    and returns <unsupported> when governor is not userspace.
    Signed-off-by: NVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>
    Signed-off-by: NDave Jones <davej@redhat.com>
    9e76988e
cpufreq.c 47.6 KB