aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2008-06-27 07:41:35 -0400
committerIngo Molnar <mingo@elte.hu>2008-06-27 08:31:45 -0400
commit2398f2c6d34b43025f274fc42eaca34d23ec2320 (patch)
tree0ff3e9edf12c6b4485e4fa94f47a79b44d75376a
parentcd80917e4ff465ea77106f8e4fb631eedc4cf426 (diff)
sched: update shares on wakeup
We found that the affine wakeup code needs rather accurate load figures to be effective. The trouble is that updating the load figures is fairly expensive with group scheduling. Therefore ratelimit the updating. Signed-off-by: Peter Zijlstra <peterz@infradead.org> Cc: Srivatsa Vaddagiri <vatsa@linux.vnet.ibm.com> Cc: Mike Galbraith <efault@gmx.de> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--include/linux/sched.h3
-rw-r--r--kernel/sched.c30
-rw-r--r--kernel/sched_features.h3
-rw-r--r--kernel/sysctl.c8
4 files changed, 42 insertions, 2 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index eaf821072dbd..835b6c6fcc56 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -783,6 +783,8 @@ struct sched_domain {
783 unsigned int balance_interval; /* initialise to 1. units in ms. */ 783 unsigned int balance_interval; /* initialise to 1. units in ms. */
784 unsigned int nr_balance_failed; /* initialise to 0 */ 784 unsigned int nr_balance_failed; /* initialise to 0 */
785 785
786 u64 last_update;
787
786#ifdef CONFIG_SCHEDSTATS 788#ifdef CONFIG_SCHEDSTATS
787 /* load_balance() stats */ 789 /* load_balance() stats */
788 unsigned int lb_count[CPU_MAX_IDLE_TYPES]; 790 unsigned int lb_count[CPU_MAX_IDLE_TYPES];
@@ -1605,6 +1607,7 @@ extern unsigned int sysctl_sched_child_runs_first;
1605extern unsigned int sysctl_sched_features; 1607extern unsigned int sysctl_sched_features;
1606extern unsigned int sysctl_sched_migration_cost; 1608extern unsigned int sysctl_sched_migration_cost;
1607extern unsigned int sysctl_sched_nr_migrate; 1609extern unsigned int sysctl_sched_nr_migrate;
1610extern unsigned int sysctl_sched_shares_ratelimit;
1608 1611
1609int sched_nr_latency_handler(struct ctl_table *table, int write, 1612int sched_nr_latency_handler(struct ctl_table *table, int write,
1610 struct file *file, void __user *buffer, size_t *length, 1613 struct file *file, void __user *buffer, size_t *length,
diff --git a/kernel/sched.c b/kernel/sched.c
index 1cff969f6646..62db0891025a 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -778,6 +778,12 @@ late_initcall(sched_init_debug);
778const_debug unsigned int sysctl_sched_nr_migrate = 32; 778const_debug unsigned int sysctl_sched_nr_migrate = 32;
779 779
780/* 780/*
781 * ratelimit for updating the group shares.
782 * default: 0.5ms
783 */
784const_debug unsigned int sysctl_sched_shares_ratelimit = 500000;
785
786/*
781 * period over which we measure -rt task cpu usage in us. 787 * period over which we measure -rt task cpu usage in us.
782 * default: 1s 788 * default: 1s
783 */ 789 */
@@ -1590,7 +1596,13 @@ tg_nop(struct task_group *tg, int cpu, struct sched_domain *sd)
1590 1596
1591static void update_shares(struct sched_domain *sd) 1597static void update_shares(struct sched_domain *sd)
1592{ 1598{
1593 walk_tg_tree(tg_nop, tg_shares_up, 0, sd); 1599 u64 now = cpu_clock(raw_smp_processor_id());
1600 s64 elapsed = now - sd->last_update;
1601
1602 if (elapsed >= (s64)(u64)sysctl_sched_shares_ratelimit) {
1603 sd->last_update = now;
1604 walk_tg_tree(tg_nop, tg_shares_up, 0, sd);
1605 }
1594} 1606}
1595 1607
1596static void update_shares_locked(struct rq *rq, struct sched_domain *sd) 1608static void update_shares_locked(struct rq *rq, struct sched_domain *sd)
@@ -2199,6 +2211,22 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
2199 if (!sched_feat(SYNC_WAKEUPS)) 2211 if (!sched_feat(SYNC_WAKEUPS))
2200 sync = 0; 2212 sync = 0;
2201 2213
2214#ifdef CONFIG_SMP
2215 if (sched_feat(LB_WAKEUP_UPDATE)) {
2216 struct sched_domain *sd;
2217
2218 this_cpu = raw_smp_processor_id();
2219 cpu = task_cpu(p);
2220
2221 for_each_domain(this_cpu, sd) {
2222 if (cpu_isset(cpu, sd->span)) {
2223 update_shares(sd);
2224 break;
2225 }
2226 }
2227 }
2228#endif
2229
2202 smp_wmb(); 2230 smp_wmb();
2203 rq = task_rq_lock(p, &flags); 2231 rq = task_rq_lock(p, &flags);
2204 old_state = p->state; 2232 old_state = p->state;
diff --git a/kernel/sched_features.h b/kernel/sched_features.h
index d56e3053e746..7d616d2a2a3f 100644
--- a/kernel/sched_features.h
+++ b/kernel/sched_features.h
@@ -8,4 +8,5 @@ SCHED_FEAT(SYNC_WAKEUPS, 1)
8SCHED_FEAT(HRTICK, 1) 8SCHED_FEAT(HRTICK, 1)
9SCHED_FEAT(DOUBLE_TICK, 0) 9SCHED_FEAT(DOUBLE_TICK, 0)
10SCHED_FEAT(ASYM_GRAN, 1) 10SCHED_FEAT(ASYM_GRAN, 1)
11SCHED_FEAT(LB_BIAS, 0) \ No newline at end of file 11SCHED_FEAT(LB_BIAS, 0)
12SCHED_FEAT(LB_WAKEUP_UPDATE, 1)
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 29116652dca8..fe8cdc80ff02 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -266,6 +266,14 @@ static struct ctl_table kern_table[] = {
266 }, 266 },
267 { 267 {
268 .ctl_name = CTL_UNNUMBERED, 268 .ctl_name = CTL_UNNUMBERED,
269 .procname = "sched_shares_ratelimit",
270 .data = &sysctl_sched_shares_ratelimit,
271 .maxlen = sizeof(unsigned int),
272 .mode = 0644,
273 .proc_handler = &proc_dointvec,
274 },
275 {
276 .ctl_name = CTL_UNNUMBERED,
269 .procname = "sched_child_runs_first", 277 .procname = "sched_child_runs_first",
270 .data = &sysctl_sched_child_runs_first, 278 .data = &sysctl_sched_child_runs_first,
271 .maxlen = sizeof(unsigned int), 279 .maxlen = sizeof(unsigned int),