cpu/hotplug: Ensure that sched domains are rebuilt before hotplug

When cpusets are enabled, the rebuilding of the scheduling domains
is deferred to a workqueue context. Make sure that the work is
completed before proceeding to the next hotplug. Otherwise scheduler
observes an inconsistent view of online and offline CPUs in the
root domain. If the online CPUs are still stuck in the offline i.e
default domain, those CPUs would not be visible when scheduling
happens on from other CPUs in the root domain. This results in
packing tasks more on certain CPUs while leaving the other CPUs
idle. Also RT_RUNTIME_SHARE feature i.e borrowing RT runtime from
the other CPUs would not work correctly. Because the CPUs in the
root domain can't borrow the runtime from the online CPUs but stuck
in the offline/default domain.

Change-Id: I93c51d2abc8a9c099b62f1d2cbb9095d3a788bda
Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
[satyap@codeaurora.org: fix trivial merge conflict]
Signed-off-by: Satya Durga Srinivasu Prabhala <satyap@codeaurora.org>
This commit is contained in:
Pavankumar Kondeti 2018-12-12 10:50:30 +05:30 committed by Satya Durga Srinivasu Prabhala
parent 92f2e8151d
commit 281266a343

View file

@ -31,6 +31,7 @@
#include <linux/slab.h>
#include <linux/percpu-rwsem.h>
#include <uapi/linux/sched/types.h>
#include <linux/cpuset.h>
#include <trace/events/power.h>
#define CREATE_TRACE_POINTS
@ -1014,6 +1015,18 @@ static int do_cpu_down(unsigned int cpu, enum cpuhp_state target)
{
int err;
/*
* When cpusets are enabled, the rebuilding of the scheduling
* domains is deferred to a workqueue context. Make sure
* that the work is completed before proceeding to the next
* hotplug. Otherwise scheduler observes an inconsistent
* view of online and offline CPUs in the root domain. If
* the online CPUs are still stuck in the offline (default)
* domain, those CPUs would not be visible when scheduling
* happens on from other CPUs in the root domain.
*/
cpuset_wait_for_hotplug();
cpu_maps_update_begin();
err = cpu_down_maps_locked(cpu, target);
cpu_maps_update_done();
@ -1177,6 +1190,8 @@ static int do_cpu_up(unsigned int cpu, enum cpuhp_state target)
return -EINVAL;
}
cpuset_wait_for_hotplug();
switch_err = switch_to_rt_policy();
if (switch_err < 0)
return switch_err;