aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Krasnyansky <maxk@qualcomm.com>2008-08-29 16:11:41 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-06 13:22:15 -0400
commitdfb512ec4834116124da61d6c1ee10fd0aa32bd6 (patch)
treeea4f847f2a29face1b5774c6d44ec41bf92e302b
parentcf417141cbb3a4ceb5cca15b2c1f099bd0a6603c (diff)
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: Max Krasnyansky <maxk@qualcomm.com> Tested-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--include/linux/cpuset.h2
-rw-r--r--kernel/sched.c19
2 files changed, 14 insertions, 7 deletions
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index e8f450c499b0..2691926fb506 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -160,7 +160,7 @@ static inline int current_cpuset_is_being_rebound(void)
160 160
161static inline void rebuild_sched_domains(void) 161static inline void rebuild_sched_domains(void)
162{ 162{
163 partition_sched_domains(0, NULL, NULL); 163 partition_sched_domains(1, NULL, NULL);
164} 164}
165 165
166#endif /* !CONFIG_CPUSETS */ 166#endif /* !CONFIG_CPUSETS */
diff --git a/kernel/sched.c b/kernel/sched.c
index d601fb0406ca..d72ee9a0eacd 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -7589,24 +7589,27 @@ static int dattrs_equal(struct sched_domain_attr *cur, int idx_cur,
7589 * and partition_sched_domains() will fallback to the single partition 7589 * and partition_sched_domains() will fallback to the single partition
7590 * 'fallback_doms', it also forces the domains to be rebuilt. 7590 * 'fallback_doms', it also forces the domains to be rebuilt.
7591 * 7591 *
7592 * If doms_new==NULL it will be replaced with cpu_online_map.
7593 * ndoms_new==0 is a special case for destroying existing domains.
7594 * It will not create the default domain.
7595 *
7592 * Call with hotplug lock held 7596 * Call with hotplug lock held
7593 */ 7597 */
7594void partition_sched_domains(int ndoms_new, cpumask_t *doms_new, 7598void partition_sched_domains(int ndoms_new, cpumask_t *doms_new,
7595 struct sched_domain_attr *dattr_new) 7599 struct sched_domain_attr *dattr_new)
7596{ 7600{
7597 int i, j; 7601 int i, j, n;
7598 7602
7599 mutex_lock(&sched_domains_mutex); 7603 mutex_lock(&sched_domains_mutex);
7600 7604
7601 /* always unregister in case we don't destroy any domains */ 7605 /* always unregister in case we don't destroy any domains */
7602 unregister_sched_domain_sysctl(); 7606 unregister_sched_domain_sysctl();
7603 7607
7604 if (doms_new == NULL) 7608 n = doms_new ? ndoms_new : 0;
7605 ndoms_new = 0;
7606 7609
7607 /* Destroy deleted domains */ 7610 /* Destroy deleted domains */
7608 for (i = 0; i < ndoms_cur; i++) { 7611 for (i = 0; i < ndoms_cur; i++) {
7609 for (j = 0; j < ndoms_new; j++) { 7612 for (j = 0; j < n; j++) {
7610 if (cpus_equal(doms_cur[i], doms_new[j]) 7613 if (cpus_equal(doms_cur[i], doms_new[j])
7611 && dattrs_equal(dattr_cur, i, dattr_new, j)) 7614 && dattrs_equal(dattr_cur, i, dattr_new, j))
7612 goto match1; 7615 goto match1;
@@ -7619,7 +7622,6 @@ match1:
7619 7622
7620 if (doms_new == NULL) { 7623 if (doms_new == NULL) {
7621 ndoms_cur = 0; 7624 ndoms_cur = 0;
7622 ndoms_new = 1;
7623 doms_new = &fallback_doms; 7625 doms_new = &fallback_doms;
7624 cpus_andnot(doms_new[0], cpu_online_map, cpu_isolated_map); 7626 cpus_andnot(doms_new[0], cpu_online_map, cpu_isolated_map);
7625 dattr_new = NULL; 7627 dattr_new = NULL;
@@ -7656,8 +7658,13 @@ match2:
7656int arch_reinit_sched_domains(void) 7658int arch_reinit_sched_domains(void)
7657{ 7659{
7658 get_online_cpus(); 7660 get_online_cpus();
7661
7662 /* Destroy domains first to force the rebuild */
7663 partition_sched_domains(0, NULL, NULL);
7664
7659 rebuild_sched_domains(); 7665 rebuild_sched_domains();
7660 put_online_cpus(); 7666 put_online_cpus();
7667
7661 return 0; 7668 return 0;
7662} 7669}
7663 7670
@@ -7741,7 +7748,7 @@ static int update_sched_domains(struct notifier_block *nfb,
7741 case CPU_ONLINE_FROZEN: 7748 case CPU_ONLINE_FROZEN:
7742 case CPU_DEAD: 7749 case CPU_DEAD:
7743 case CPU_DEAD_FROZEN: 7750 case CPU_DEAD_FROZEN:
7744 partition_sched_domains(0, NULL, NULL); 7751 partition_sched_domains(1, NULL, NULL);
7745 return NOTIFY_OK; 7752 return NOTIFY_OK;
7746 7753
7747 default: 7754 default: