diff options
| -rw-r--r-- | kernel/sched_fair.c | 133 |
1 files changed, 4 insertions, 129 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 3b89aa6594a9..c20899763457 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
| @@ -409,64 +409,6 @@ static u64 sched_vslice_add(struct cfs_rq *cfs_rq, struct sched_entity *se) | |||
| 409 | } | 409 | } |
| 410 | 410 | ||
| 411 | /* | 411 | /* |
| 412 | * The goal of calc_delta_asym() is to be asymmetrically around NICE_0_LOAD, in | ||
| 413 | * that it favours >=0 over <0. | ||
| 414 | * | ||
| 415 | * -20 | | ||
| 416 | * | | ||
| 417 | * 0 --------+------- | ||
| 418 | * .' | ||
| 419 | * 19 .' | ||
| 420 | * | ||
| 421 | */ | ||
| 422 | static unsigned long | ||
| 423 | calc_delta_asym(unsigned long delta, struct sched_entity *se) | ||
| 424 | { | ||
| 425 | struct load_weight lw = { | ||
| 426 | .weight = NICE_0_LOAD, | ||
| 427 | .inv_weight = 1UL << (WMULT_SHIFT-NICE_0_SHIFT) | ||
| 428 | }; | ||
| 429 | |||
| 430 | for_each_sched_entity(se) { | ||
| 431 | struct load_weight *se_lw = &se->load; | ||
| 432 | unsigned long rw = cfs_rq_of(se)->load.weight; | ||
| 433 | |||
| 434 | #ifdef CONFIG_FAIR_SCHED_GROUP | ||
| 435 | struct cfs_rq *cfs_rq = se->my_q; | ||
| 436 | struct task_group *tg = NULL | ||
| 437 | |||
| 438 | if (cfs_rq) | ||
| 439 | tg = cfs_rq->tg; | ||
| 440 | |||
| 441 | if (tg && tg->shares < NICE_0_LOAD) { | ||
| 442 | /* | ||
| 443 | * scale shares to what it would have been had | ||
| 444 | * tg->weight been NICE_0_LOAD: | ||
| 445 | * | ||
| 446 | * weight = 1024 * shares / tg->weight | ||
| 447 | */ | ||
| 448 | lw.weight *= se->load.weight; | ||
| 449 | lw.weight /= tg->shares; | ||
| 450 | |||
| 451 | lw.inv_weight = 0; | ||
| 452 | |||
| 453 | se_lw = &lw; | ||
| 454 | rw += lw.weight - se->load.weight; | ||
| 455 | } else | ||
| 456 | #endif | ||
| 457 | |||
| 458 | if (se->load.weight < NICE_0_LOAD) { | ||
| 459 | se_lw = &lw; | ||
| 460 | rw += NICE_0_LOAD - se->load.weight; | ||
| 461 | } | ||
| 462 | |||
| 463 | delta = calc_delta_mine(delta, rw, se_lw); | ||
| 464 | } | ||
| 465 | |||
| 466 | return delta; | ||
| 467 | } | ||
| 468 | |||
| 469 | /* | ||
| 470 | * Update the current task's runtime statistics. Skip current tasks that | 412 | * Update the current task's runtime statistics. Skip current tasks that |
| 471 | * are not in our scheduling class. | 413 | * are not in our scheduling class. |
| 472 | */ | 414 | */ |
| @@ -1281,54 +1223,12 @@ static unsigned long wakeup_gran(struct sched_entity *se) | |||
| 1281 | * + nice tasks. | 1223 | * + nice tasks. |
| 1282 | */ | 1224 | */ |
| 1283 | if (sched_feat(ASYM_GRAN)) | 1225 | if (sched_feat(ASYM_GRAN)) |
| 1284 | gran = calc_delta_asym(sysctl_sched_wakeup_granularity, se); | 1226 | gran = calc_delta_mine(gran, NICE_0_LOAD, &se->load); |
| 1285 | else | ||
| 1286 | gran = calc_delta_fair(sysctl_sched_wakeup_granularity, se); | ||
| 1287 | 1227 | ||
| 1288 | return gran; | 1228 | return gran; |
| 1289 | } | 1229 | } |
| 1290 | 1230 | ||
| 1291 | /* | 1231 | /* |
| 1292 | * Should 'se' preempt 'curr'. | ||
| 1293 | * | ||
| 1294 | * |s1 | ||
| 1295 | * |s2 | ||
| 1296 | * |s3 | ||
| 1297 | * g | ||
| 1298 | * |<--->|c | ||
| 1299 | * | ||
| 1300 | * w(c, s1) = -1 | ||
| 1301 | * w(c, s2) = 0 | ||
| 1302 | * w(c, s3) = 1 | ||
| 1303 | * | ||
| 1304 | */ | ||
| 1305 | static int | ||
| 1306 | wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se) | ||
| 1307 | { | ||
| 1308 | s64 gran, vdiff = curr->vruntime - se->vruntime; | ||
| 1309 | |||
| 1310 | if (vdiff < 0) | ||
| 1311 | return -1; | ||
| 1312 | |||
| 1313 | gran = wakeup_gran(curr); | ||
| 1314 | if (vdiff > gran) | ||
| 1315 | return 1; | ||
| 1316 | |||
| 1317 | return 0; | ||
| 1318 | } | ||
| 1319 | |||
| 1320 | /* return depth at which a sched entity is present in the hierarchy */ | ||
| 1321 | static inline int depth_se(struct sched_entity *se) | ||
| 1322 | { | ||
| 1323 | int depth = 0; | ||
| 1324 | |||
| 1325 | for_each_sched_entity(se) | ||
| 1326 | depth++; | ||
| 1327 | |||
| 1328 | return depth; | ||
| 1329 | } | ||
| 1330 | |||
| 1331 | /* | ||
| 1332 | * Preempt the current task with a newly woken task if needed: | 1232 | * Preempt the current task with a newly woken task if needed: |
| 1333 | */ | 1233 | */ |
| 1334 | static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync) | 1234 | static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync) |
| @@ -1336,7 +1236,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync) | |||
| 1336 | struct task_struct *curr = rq->curr; | 1236 | struct task_struct *curr = rq->curr; |
| 1337 | struct cfs_rq *cfs_rq = task_cfs_rq(curr); | 1237 | struct cfs_rq *cfs_rq = task_cfs_rq(curr); |
| 1338 | struct sched_entity *se = &curr->se, *pse = &p->se; | 1238 | struct sched_entity *se = &curr->se, *pse = &p->se; |
| 1339 | int se_depth, pse_depth; | 1239 | s64 delta_exec; |
| 1340 | 1240 | ||
| 1341 | if (unlikely(rt_prio(p->prio))) { | 1241 | if (unlikely(rt_prio(p->prio))) { |
| 1342 | update_rq_clock(rq); | 1242 | update_rq_clock(rq); |
| @@ -1374,33 +1274,8 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync) | |||
| 1374 | return; | 1274 | return; |
| 1375 | } | 1275 | } |
| 1376 | 1276 | ||
| 1377 | /* | 1277 | delta_exec = se->sum_exec_runtime - se->prev_sum_exec_runtime; |
| 1378 | * preemption test can be made between sibling entities who are in the | 1278 | if (delta_exec > wakeup_gran(pse)) |
| 1379 | * same cfs_rq i.e who have a common parent. Walk up the hierarchy of | ||
| 1380 | * both tasks until we find their ancestors who are siblings of common | ||
| 1381 | * parent. | ||
| 1382 | */ | ||
| 1383 | |||
| 1384 | /* First walk up until both entities are at same depth */ | ||
| 1385 | se_depth = depth_se(se); | ||
| 1386 | pse_depth = depth_se(pse); | ||
| 1387 | |||
| 1388 | while (se_depth > pse_depth) { | ||
| 1389 | se_depth--; | ||
| 1390 | se = parent_entity(se); | ||
| 1391 | } | ||
| 1392 | |||
| 1393 | while (pse_depth > se_depth) { | ||
| 1394 | pse_depth--; | ||
| 1395 | pse = parent_entity(pse); | ||
| 1396 | } | ||
| 1397 | |||
| 1398 | while (!is_same_group(se, pse)) { | ||
| 1399 | se = parent_entity(se); | ||
| 1400 | pse = parent_entity(pse); | ||
| 1401 | } | ||
| 1402 | |||
| 1403 | if (wakeup_preempt_entity(se, pse) == 1) | ||
| 1404 | resched_task(curr); | 1279 | resched_task(curr); |
| 1405 | } | 1280 | } |
| 1406 | 1281 | ||
