Commit dfb512ec authored by Max Krasnyansky's avatar Max Krasnyansky Committed by Ingo Molnar

sched: arch_reinit_sched_domains() must destroy domains to force rebuild

What I realized recently is that calling rebuild_sched_domains() in
arch_reinit_sched_domains() by itself is not enough when cpusets are enabled.
partition_sched_domains() code is trying to avoid unnecessary domain rebuilds
and will not actually rebuild anything if new domain masks match the old ones.

What this means is that doing
     echo 1 > /sys/devices/system/cpu/sched_mc_power_savings
on a system with cpusets enabled will not take affect untill something changes
in the cpuset setup (ie new sets created or deleted).

This patch fixes restore correct behaviour where domains must be rebuilt in
order to enable MC powersaving flags.

Test on quad-core Core2 box with both CONFIG_CPUSETS and !CONFIG_CPUSETS.
Also tested on dual-core Core2 laptop. Lockdep is happy and things are working
as expected.
Signed-off-by: default avatarMax Krasnyansky <maxk@qualcomm.com>
Tested-by: default avatarVaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent cf417141
...@@ -160,7 +160,7 @@ static inline int current_cpuset_is_being_rebound(void) ...@@ -160,7 +160,7 @@ static inline int current_cpuset_is_being_rebound(void)
static inline void rebuild_sched_domains(void) static inline void rebuild_sched_domains(void)
{ {
partition_sched_domains(0, NULL, NULL); partition_sched_domains(1, NULL, NULL);
} }
#endif /* !CONFIG_CPUSETS */ #endif /* !CONFIG_CPUSETS */
......
...@@ -7589,24 +7589,27 @@ static int dattrs_equal(struct sched_domain_attr *cur, int idx_cur, ...@@ -7589,24 +7589,27 @@ static int dattrs_equal(struct sched_domain_attr *cur, int idx_cur,
* and partition_sched_domains() will fallback to the single partition * and partition_sched_domains() will fallback to the single partition
* 'fallback_doms', it also forces the domains to be rebuilt. * 'fallback_doms', it also forces the domains to be rebuilt.
* *
* If doms_new==NULL it will be replaced with cpu_online_map.
* ndoms_new==0 is a special case for destroying existing domains.
* It will not create the default domain.
*
* Call with hotplug lock held * Call with hotplug lock held
*/ */
void partition_sched_domains(int ndoms_new, cpumask_t *doms_new, void partition_sched_domains(int ndoms_new, cpumask_t *doms_new,
struct sched_domain_attr *dattr_new) struct sched_domain_attr *dattr_new)
{ {
int i, j; int i, j, n;
mutex_lock(&sched_domains_mutex); mutex_lock(&sched_domains_mutex);
/* always unregister in case we don't destroy any domains */ /* always unregister in case we don't destroy any domains */
unregister_sched_domain_sysctl(); unregister_sched_domain_sysctl();
if (doms_new == NULL) n = doms_new ? ndoms_new : 0;
ndoms_new = 0;
/* Destroy deleted domains */ /* Destroy deleted domains */
for (i = 0; i < ndoms_cur; i++) { for (i = 0; i < ndoms_cur; i++) {
for (j = 0; j < ndoms_new; j++) { for (j = 0; j < n; j++) {
if (cpus_equal(doms_cur[i], doms_new[j]) if (cpus_equal(doms_cur[i], doms_new[j])
&& dattrs_equal(dattr_cur, i, dattr_new, j)) && dattrs_equal(dattr_cur, i, dattr_new, j))
goto match1; goto match1;
...@@ -7619,7 +7622,6 @@ void partition_sched_domains(int ndoms_new, cpumask_t *doms_new, ...@@ -7619,7 +7622,6 @@ void partition_sched_domains(int ndoms_new, cpumask_t *doms_new,
if (doms_new == NULL) { if (doms_new == NULL) {
ndoms_cur = 0; ndoms_cur = 0;
ndoms_new = 1;
doms_new = &fallback_doms; doms_new = &fallback_doms;
cpus_andnot(doms_new[0], cpu_online_map, cpu_isolated_map); cpus_andnot(doms_new[0], cpu_online_map, cpu_isolated_map);
dattr_new = NULL; dattr_new = NULL;
...@@ -7656,8 +7658,13 @@ void partition_sched_domains(int ndoms_new, cpumask_t *doms_new, ...@@ -7656,8 +7658,13 @@ void partition_sched_domains(int ndoms_new, cpumask_t *doms_new,
int arch_reinit_sched_domains(void) int arch_reinit_sched_domains(void)
{ {
get_online_cpus(); get_online_cpus();
/* Destroy domains first to force the rebuild */
partition_sched_domains(0, NULL, NULL);
rebuild_sched_domains(); rebuild_sched_domains();
put_online_cpus(); put_online_cpus();
return 0; return 0;
} }
...@@ -7741,7 +7748,7 @@ static int update_sched_domains(struct notifier_block *nfb, ...@@ -7741,7 +7748,7 @@ static int update_sched_domains(struct notifier_block *nfb,
case CPU_ONLINE_FROZEN: case CPU_ONLINE_FROZEN:
case CPU_DEAD: case CPU_DEAD:
case CPU_DEAD_FROZEN: case CPU_DEAD_FROZEN:
partition_sched_domains(0, NULL, NULL); partition_sched_domains(1, NULL, NULL);
return NOTIFY_OK; return NOTIFY_OK;
default: default:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment