cpufreq/ondemand: fix race while offlining CPU
authorJan Beulich <jbeulich@suse.com>
Fri, 9 Mar 2018 16:30:49 +0000 (17:30 +0100)
committerJan Beulich <jbeulich@suse.com>
Fri, 9 Mar 2018 16:30:49 +0000 (17:30 +0100)
commit185413355fe331cbc926d48568838227234c9a20
treeff8ae9d04dd4601ba25b24b36bcb6e4523e29616
parentb78a43d60af39a8a3d59ddc2e33d5aa290f5a7f9
cpufreq/ondemand: fix race while offlining CPU

Offlining a CPU involves stopping the cpufreq governor. The on-demand
governor will kill the timer before letting generic code proceed, but
since that generally isn't happening on the subject CPU,
cpufreq_dbs_timer_resume() may run in parallel. If that managed to
invoke the timer handler, that handler needs to run to completion before
dbs_timer_exit() may safely exit.

Make the "stoppable" field a tristate, changing it from +1 to -1 around
the timer function invocation, and make dbs_timer_exit() wait for it to
become non-negative (still writing zero if it's +1).

Also adjust coding style in cpufreq_dbs_timer_resume().

Reported-by: Martin Cerveny <martin@c-home.cz>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Martin Cerveny <martin@c-home.cz>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
xen/drivers/cpufreq/cpufreq_ondemand.c
xen/include/acpi/cpufreq/cpufreq.h