]> git.baikalelectronics.ru Git - kernel.git/commit
cpufreq: governor: Use lockless timer function
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 8 Dec 2015 20:44:05 +0000 (21:44 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 9 Dec 2015 21:26:13 +0000 (22:26 +0100)
commitb2c9ed750ad39a93bdac7a4d9af6a2ce9105eaad
tree5c66a069efca038756228ee65e71e0dd7e4807a1
parent5fa507d0b4e46946d46352167d95b50a90c05921
cpufreq: governor: Use lockless timer function

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: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
drivers/cpufreq/cpufreq_governor.c
drivers/cpufreq/cpufreq_governor.h