diff options
| author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2008-02-25 11:34:02 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-03-04 11:54:06 -0500 |
| commit | 62fb185130e4d420f71a30ff59d8b16b74ef5d2b (patch) | |
| tree | 474c0824a5bf90950b0a430a11a52b358c9e1f31 /kernel | |
| parent | 976dde010e513a9c7c3117a32b7b015f84b37430 (diff) | |
sched: revert load_balance_monitor() changes
The following commits cause a number of regressions:
commit 58e2d4ca581167c2a079f4ee02be2f0bc52e8729
Author: Srivatsa Vaddagiri <vatsa@linux.vnet.ibm.com>
Date: Fri Jan 25 21:08:00 2008 +0100
sched: group scheduling, change how cpu load is calculated
commit 6b2d7700266b9402e12824e11e0099ae6a4a6a79
Author: Srivatsa Vaddagiri <vatsa@linux.vnet.ibm.com>
Date: Fri Jan 25 21:08:00 2008 +0100
sched: group scheduler, fix fairness of cpu bandwidth allocation for task groups
Namely:
- very frequent wakeups on SMP, reported by PowerTop users.
- cacheline trashing on (large) SMP
- some latencies larger than 500ms
While there is a mergeable patch to fix the latter, the former issues
are not fixable in a manner suitable for .25 (we're at -rc3 now).
Hence we revert them and try again in v2.6.26.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
CC: Srivatsa Vaddagiri <vatsa@linux.vnet.ibm.com>
Tested-by: Alexey Zaytsev <alexey.zaytsev@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sched.c | 283 | ||||
| -rw-r--r-- | kernel/sched_fair.c | 115 | ||||
| -rw-r--r-- | kernel/sched_rt.c | 4 | ||||
| -rw-r--r-- | kernel/sysctl.c | 18 |
4 files changed, 70 insertions, 350 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index f06950c8a6ce..dcd553cc4ee8 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -174,41 +174,6 @@ struct task_group { | |||
| 174 | struct sched_entity **se; | 174 | struct sched_entity **se; |
| 175 | /* runqueue "owned" by this group on each cpu */ | 175 | /* runqueue "owned" by this group on each cpu */ |
| 176 | struct cfs_rq **cfs_rq; | 176 | struct cfs_rq **cfs_rq; |
| 177 | |||
| 178 | /* | ||
| 179 | * shares assigned to a task group governs how much of cpu bandwidth | ||
| 180 | * is allocated to the group. The more shares a group has, the more is | ||
| 181 | * the cpu bandwidth allocated to it. | ||
| 182 | * | ||
| 183 | * For ex, lets say that there are three task groups, A, B and C which | ||
| 184 | * have been assigned shares 1000, 2000 and 3000 respectively. Then, | ||
| 185 | * cpu bandwidth allocated by the scheduler to task groups A, B and C | ||
| 186 | * should be: | ||
| 187 | * | ||
| 188 | * Bw(A) = 1000/(1000+2000+3000) * 100 = 16.66% | ||
| 189 | * Bw(B) = 2000/(1000+2000+3000) * 100 = 33.33% | ||
| 190 | * Bw(C) = 3000/(1000+2000+3000) * 100 = 50% | ||
| 191 | * | ||
| 192 | * The weight assigned to a task group's schedulable entities on every | ||
| 193 | * cpu (task_group.se[a_cpu]->load.weight) is derived from the task | ||
| 194 | * group's shares. For ex: lets say that task group A has been | ||
| 195 | * assigned shares of 1000 and there are two CPUs in a system. Then, | ||
| 196 | * | ||
| 197 | * tg_A->se[0]->load.weight = tg_A->se[1]->load.weight = 1000; | ||
| 198 | * | ||
| 199 | * Note: It's not necessary that each of a task's group schedulable | ||
| 200 | * entity have the same weight on all CPUs. If the group | ||
| 201 | * has 2 of its tasks on CPU0 and 1 task on CPU1, then a | ||
| 202 | * better distribution of weight could be: | ||
| 203 | * | ||
| 204 | * tg_A->se[0]->load.weight = 2/3 * 2000 = 1333 | ||
| 205 | * tg_A->se[1]->load.weight = 1/2 * 2000 = 667 | ||
| 206 | * | ||
| 207 | * rebalance_shares() is responsible for distributing the shares of a | ||
| 208 | * task groups like this among the group's schedulable entities across | ||
| 209 | * cpus. | ||
| 210 | * | ||
| 211 | */ | ||
| 212 | unsigned long shares; | 177 | unsigned long shares; |
| 213 | #endif | 178 | #endif |
| 214 | 179 | ||
| @@ -250,22 +215,12 @@ static DEFINE_SPINLOCK(task_group_lock); | |||
| 250 | static DEFINE_MUTEX(doms_cur_mutex); | 215 | static DEFINE_MUTEX(doms_cur_mutex); |
| 251 | 216 | ||
| 252 | #ifdef CONFIG_FAIR_GROUP_SCHED | 217 | #ifdef CONFIG_FAIR_GROUP_SCHED |
| 253 | #ifdef CONFIG_SMP | ||
| 254 | /* kernel thread that runs rebalance_shares() periodically */ | ||
| 255 | static struct task_struct *lb_monitor_task; | ||
| 256 | static int load_balance_monitor(void *unused); | ||
| 257 | #endif | ||
| 258 | |||
| 259 | static void set_se_shares(struct sched_entity *se, unsigned long shares); | ||
| 260 | |||
| 261 | #ifdef CONFIG_USER_SCHED | 218 | #ifdef CONFIG_USER_SCHED |
| 262 | # define INIT_TASK_GROUP_LOAD (2*NICE_0_LOAD) | 219 | # define INIT_TASK_GROUP_LOAD (2*NICE_0_LOAD) |
| 263 | #else | 220 | #else |
| 264 | # define INIT_TASK_GROUP_LOAD NICE_0_LOAD | 221 | # define INIT_TASK_GROUP_LOAD NICE_0_LOAD |
| 265 | #endif | 222 | #endif |
| 266 | 223 | ||
| 267 | #define MIN_GROUP_SHARES 2 | ||
| 268 | |||
| 269 | static int init_task_group_load = INIT_TASK_GROUP_LOAD; | 224 | static int init_task_group_load = INIT_TASK_GROUP_LOAD; |
| 270 | #endif | 225 | #endif |
| 271 | 226 | ||
| @@ -1245,16 +1200,6 @@ static void cpuacct_charge(struct task_struct *tsk, u64 cputime); | |||
| 1245 | static inline void cpuacct_charge(struct task_struct *tsk, u64 cputime) {} | 1200 | static inline void cpuacct_charge(struct task_struct *tsk, u64 cputime) {} |
| 1246 | #endif | 1201 | #endif |
| 1247 | 1202 | ||
| 1248 | static inline void inc_cpu_load(struct rq *rq, unsigned long load) | ||
| 1249 | { | ||
| 1250 | update_load_add(&rq->load, load); | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | static inline void dec_cpu_load(struct rq *rq, unsigned long load) | ||
| 1254 | { | ||
| 1255 | update_load_sub(&rq->load, load); | ||
| 1256 | } | ||
| 1257 | |||
| 1258 | #ifdef CONFIG_SMP | 1203 | #ifdef CONFIG_SMP |
| 1259 | static unsigned long source_load(int cpu, int type); | 1204 | static unsigned long source_load(int cpu, int type); |
| 1260 | static unsigned long target_load(int cpu, int type); | 1205 | static unsigned long target_load(int cpu, int type); |
| @@ -1272,14 +1217,26 @@ static int task_hot(struct task_struct *p, u64 now, struct sched_domain *sd); | |||
| 1272 | 1217 | ||
| 1273 | #define sched_class_highest (&rt_sched_class) | 1218 | #define sched_class_highest (&rt_sched_class) |
| 1274 | 1219 | ||
| 1275 | static void inc_nr_running(struct rq *rq) | 1220 | static inline void inc_load(struct rq *rq, const struct task_struct *p) |
| 1221 | { | ||
| 1222 | update_load_add(&rq->load, p->se.load.weight); | ||
| 1223 | } | ||
| 1224 | |||
| 1225 | static inline void dec_load(struct rq *rq, const struct task_struct *p) | ||
| 1226 | { | ||
| 1227 | update_load_sub(&rq->load, p->se.load.weight); | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | static void inc_nr_running(struct task_struct *p, struct rq *rq) | ||
| 1276 | { | 1231 | { |
| 1277 | rq->nr_running++; | 1232 | rq->nr_running++; |
| 1233 | inc_load(rq, p); | ||
| 1278 | } | 1234 | } |
| 1279 | 1235 | ||
| 1280 | static void dec_nr_running(struct rq *rq) | 1236 | static void dec_nr_running(struct task_struct *p, struct rq *rq) |
| 1281 | { | 1237 | { |
| 1282 | rq->nr_running--; | 1238 | rq->nr_running--; |
| 1239 | dec_load(rq, p); | ||
| 1283 | } | 1240 | } |
| 1284 | 1241 | ||
| 1285 | static void set_load_weight(struct task_struct *p) | 1242 | static void set_load_weight(struct task_struct *p) |
| @@ -1371,7 +1328,7 @@ static void activate_task(struct rq *rq, struct task_struct *p, int wakeup) | |||
| 1371 | rq->nr_uninterruptible--; | 1328 | rq->nr_uninterruptible--; |
| 1372 | 1329 | ||
| 1373 | enqueue_task(rq, p, wakeup); | 1330 | enqueue_task(rq, p, wakeup); |
| 1374 | inc_nr_running(rq); | 1331 | inc_nr_running(p, rq); |
| 1375 | } | 1332 | } |
| 1376 | 1333 | ||
| 1377 | /* | 1334 | /* |
| @@ -1383,7 +1340,7 @@ static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep) | |||
| 1383 | rq->nr_uninterruptible++; | 1340 | rq->nr_uninterruptible++; |
| 1384 | 1341 | ||
| 1385 | dequeue_task(rq, p, sleep); | 1342 | dequeue_task(rq, p, sleep); |
| 1386 | dec_nr_running(rq); | 1343 | dec_nr_running(p, rq); |
| 1387 | } | 1344 | } |
| 1388 | 1345 | ||
| 1389 | /** | 1346 | /** |
| @@ -2023,7 +1980,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) | |||
| 2023 | * management (if any): | 1980 | * management (if any): |
| 2024 | */ | 1981 | */ |
| 2025 | p->sched_class->task_new(rq, p); | 1982 | p->sched_class->task_new(rq, p); |
| 2026 | inc_nr_running(rq); | 1983 | inc_nr_running(p, rq); |
| 2027 | } | 1984 | } |
| 2028 | check_preempt_curr(rq, p); | 1985 | check_preempt_curr(rq, p); |
| 2029 | #ifdef CONFIG_SMP | 1986 | #ifdef CONFIG_SMP |
| @@ -4362,8 +4319,10 @@ void set_user_nice(struct task_struct *p, long nice) | |||
| 4362 | goto out_unlock; | 4319 | goto out_unlock; |
| 4363 | } | 4320 | } |
| 4364 | on_rq = p->se.on_rq; | 4321 | on_rq = p->se.on_rq; |
| 4365 | if (on_rq) | 4322 | if (on_rq) { |
| 4366 | dequeue_task(rq, p, 0); | 4323 | dequeue_task(rq, p, 0); |
| 4324 | dec_load(rq, p); | ||
| 4325 | } | ||
| 4367 | 4326 | ||
| 4368 | p->static_prio = NICE_TO_PRIO(nice); | 4327 | p->static_prio = NICE_TO_PRIO(nice); |
| 4369 | set_load_weight(p); | 4328 | set_load_weight(p); |
| @@ -4373,6 +4332,7 @@ void set_user_nice(struct task_struct *p, long nice) | |||
| 4373 | 4332 | ||
| 4374 | if (on_rq) { | 4333 | if (on_rq) { |
| 4375 | enqueue_task(rq, p, 0); | 4334 | enqueue_task(rq, p, 0); |
| 4335 | inc_load(rq, p); | ||
| 4376 | /* | 4336 | /* |
| 4377 | * If the task increased its priority or is running and | 4337 | * If the task increased its priority or is running and |
| 4378 | * lowered its priority, then reschedule its CPU: | 4338 | * lowered its priority, then reschedule its CPU: |
| @@ -7087,21 +7047,6 @@ void __init sched_init_smp(void) | |||
| 7087 | if (set_cpus_allowed(current, non_isolated_cpus) < 0) | 7047 | if (set_cpus_allowed(current, non_isolated_cpus) < 0) |
| 7088 | BUG(); | 7048 | BUG(); |
| 7089 | sched_init_granularity(); | 7049 | sched_init_granularity(); |
| 7090 | |||
| 7091 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
| 7092 | if (nr_cpu_ids == 1) | ||
| 7093 | return; | ||
| 7094 | |||
| 7095 | lb_monitor_task = kthread_create(load_balance_monitor, NULL, | ||
