• Rafael J. Wysocki's avatar
    cpufreq: governor: Use lockless timer function · 2dd3e724
    Rafael J. Wysocki authored
    It is possible to get rid of the timer_lock spinlock used by the
    governor timer function for synchronization, but a couple of races
    need to be avoided.
    
    The first race is between multiple dbs_timer_handler() instances
    that may be running in parallel with each other on different
    CPUs.  Namely, one of them has to queue up the work item, but it
    cannot be queued up more than once.  To achieve that,
    atomic_inc_return() can be used on the skip_work field of
    struct cpu_common_dbs_info.
    
    The second race is between an already running dbs_timer_handler()
    and gov_cancel_work().  In that case the dbs_timer_handler() might
    not notice the skip_work incrementation in gov_cancel_work() and
    it might queue up its work item after gov_cancel_work() had
    returned (and that work item would corrupt skip_work going
    forward).  To prevent that from happening, gov_cancel_work()
    can be made wait for the timer function to complete (on all CPUs)
    right after skip_work has been incremented.
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    Acked-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
    2dd3e724
cpufreq_governor.c 15.9 KB