aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2009-09-01 04:34:33 -0400
committerIngo Molnar <mingo@elte.hu>2009-09-04 04:09:53 -0400
commitb5d978e0c7e79a7ff842e895c85a86b38c71f1cd (patch)
tree83502797f31953c66a76ab9cd43d6df999084210
parentf93e65c186ab3c05ce2068733ca10e34fd00125e (diff)
sched: Add SD_PREFER_SIBLING
Do the placement thing using SD flags. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Tested-by: Andreas Herrmann <andreas.herrmann3@amd.com> Acked-by: Andreas Herrmann <andreas.herrmann3@amd.com> Acked-by: Gautham R Shenoy <ego@in.ibm.com> Cc: Balbir Singh <balbir@in.ibm.com> LKML-Reference: <20090901083825.897028974@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--include/linux/sched.h29
-rw-r--r--kernel/sched.c14
2 files changed, 28 insertions, 15 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 9c96ef2f7e68..651dded25720 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -798,18 +798,19 @@ enum cpu_idle_type {
798#define SCHED_LOAD_SCALE_FUZZ SCHED_LOAD_SCALE 798#define SCHED_LOAD_SCALE_FUZZ SCHED_LOAD_SCALE
799 799
800#ifdef CONFIG_SMP 800#ifdef CONFIG_SMP
801#define SD_LOAD_BALANCE 1 /* Do load balancing on this domain. */ 801#define SD_LOAD_BALANCE 0x0001 /* Do load balancing on this domain. */
802#define SD_BALANCE_NEWIDLE 2 /* Balance when about to become idle */ 802#define SD_BALANCE_NEWIDLE 0x0002 /* Balance when about to become idle */
803#define SD_BALANCE_EXEC 4 /* Balance on exec */ 803#define SD_BALANCE_EXEC 0x0004 /* Balance on exec */
804#define SD_BALANCE_FORK 8 /* Balance on fork, clone */ 804#define SD_BALANCE_FORK 0x0008 /* Balance on fork, clone */
805#define SD_WAKE_IDLE 16 /* Wake to idle CPU on task wakeup */ 805#define SD_WAKE_IDLE 0x0010 /* Wake to idle CPU on task wakeup */
806#define SD_WAKE_AFFINE 32 /* Wake task to waking CPU */ 806#define SD_WAKE_AFFINE 0x0020 /* Wake task to waking CPU */
807#define SD_WAKE_BALANCE 64 /* Perform balancing at task wakeup */ 807#define SD_WAKE_BALANCE 0x0040 /* Perform balancing at task wakeup */
808#define SD_SHARE_CPUPOWER 128 /* Domain members share cpu power */ 808#define SD_SHARE_CPUPOWER 0x0080 /* Domain members share cpu power */
809#define SD_POWERSAVINGS_BALANCE 256 /* Balance for power savings */ 809#define SD_POWERSAVINGS_BALANCE 0x0100 /* Balance for power savings */
810#define SD_SHARE_PKG_RESOURCES 512 /* Domain members share cpu pkg resources */ 810#define SD_SHARE_PKG_RESOURCES 0x0200 /* Domain members share cpu pkg resources */
811#define SD_SERIALIZE 1024 /* Only a single load balancing instance */ 811#define SD_SERIALIZE 0x0400 /* Only a single load balancing instance */
812#define SD_WAKE_IDLE_FAR 2048 /* Gain latency sacrificing cache hit */ 812#define SD_WAKE_IDLE_FAR 0x0800 /* Gain latency sacrificing cache hit */
813#define SD_PREFER_SIBLING 0x1000 /* Prefer to place tasks in a sibling domain */
813 814
814enum powersavings_balance_level { 815enum powersavings_balance_level {
815 POWERSAVINGS_BALANCE_NONE = 0, /* No power saving load balance */ 816 POWERSAVINGS_BALANCE_NONE = 0, /* No power saving load balance */
@@ -829,7 +830,7 @@ static inline int sd_balance_for_mc_power(void)
829 if (sched_smt_power_savings) 830 if (sched_smt_power_savings)
830 return SD_POWERSAVINGS_BALANCE; 831 return SD_POWERSAVINGS_BALANCE;
831 832
832 return 0; 833 return SD_PREFER_SIBLING;
833} 834}
834 835
835static inline int sd_balance_for_package_power(void) 836static inline int sd_balance_for_package_power(void)
@@ -837,7 +838,7 @@ static inline int sd_balance_for_package_power(void)
837 if (sched_mc_power_savings | sched_smt_power_savings) 838 if (sched_mc_power_savings | sched_smt_power_savings)
838 return SD_POWERSAVINGS_BALANCE; 839 return SD_POWERSAVINGS_BALANCE;
839 840
840 return 0; 841 return SD_PREFER_SIBLING;
841} 842}
842 843
843/* 844/*
diff --git a/kernel/sched.c b/kernel/sched.c
index 584a122b553c..9d64cec9ae1d 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -3811,9 +3811,13 @@ static inline void update_sd_lb_stats(struct sched_domain *sd, int this_cpu,
3811 const struct cpumask *cpus, int *balance, 3811 const struct cpumask *cpus, int *balance,
3812 struct sd_lb_stats *sds) 3812 struct sd_lb_stats *sds)
3813{ 3813{
3814 struct sched_domain *child = sd->child;
3814 struct sched_group *group = sd->groups; 3815 struct sched_group *group = sd->groups;
3815 struct sg_lb_stats sgs; 3816 struct sg_lb_stats sgs;
3816 int load_idx; 3817 int load_idx, prefer_sibling = 0;
3818
3819 if (child && child->flags & SD_PREFER_SIBLING)
3820 prefer_sibling = 1;
3817 3821
3818 init_sd_power_savings_stats(sd, sds, idle); 3822 init_sd_power_savings_stats(sd, sds, idle);
3819 load_idx = get_sd_load_idx(sd, idle); 3823 load_idx = get_sd_load_idx(sd, idle);
@@ -3833,6 +3837,14 @@ static inline void update_sd_lb_stats(struct sched_domain *sd, int this_cpu,
3833 sds->total_load += sgs.group_load; 3837 sds->total_load += sgs.group_load;
3834 sds->total_pwr += group->__cpu_power; 3838 sds->total_pwr += group->__cpu_power;
3835 3839
3840 /*
3841 * In case the child domain prefers tasks go to siblings
3842 * first, lower the group capacity to one so that we'll try
3843 * and move all the excess tasks away.
3844 */
3845 if (prefer_sibling)
3846 sgs.group_capacity = 1;
3847
3836 if (local_group) { 3848 if (local_group) {
3837 sds->this_load = sgs.avg_load; 3849 sds->this_load = sgs.avg_load;
3838 sds->this = group; 3850 sds->this = group;