diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched.c | 30 | ||||
-rw-r--r-- | kernel/sched_features.h | 3 | ||||
-rw-r--r-- | kernel/sysctl.c | 8 |
3 files changed, 39 insertions, 2 deletions
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); | |||
778 | const_debug unsigned int sysctl_sched_nr_migrate = 32; | 778 | const_debug unsigned int sysctl_sched_nr_migrate = 32; |
779 | 779 | ||
780 | /* | 780 | /* |
781 | * ratelimit for updating the group shares. | ||
782 | * default: 0.5ms | ||
783 | */ | ||
784 | const_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 | ||
1591 | static void update_shares(struct sched_domain *sd) | 1597 | static 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 | ||
1596 | static void update_shares_locked(struct rq *rq, struct sched_domain *sd) | 1608 | static 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) | |||
8 | SCHED_FEAT(HRTICK, 1) | 8 | SCHED_FEAT(HRTICK, 1) |
9 | SCHED_FEAT(DOUBLE_TICK, 0) | 9 | SCHED_FEAT(DOUBLE_TICK, 0) |
10 | SCHED_FEAT(ASYM_GRAN, 1) | 10 | SCHED_FEAT(ASYM_GRAN, 1) |
11 | SCHED_FEAT(LB_BIAS, 0) \ No newline at end of file | 11 | SCHED_FEAT(LB_BIAS, 0) |
12 | SCHED_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), |