diff options
Diffstat (limited to 'kernel/sched_fair.c')
| -rw-r--r-- | kernel/sched_fair.c | 213 |
1 files changed, 96 insertions, 117 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 6f579ff5a9bc..c5af38948a1e 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
| @@ -222,21 +222,25 @@ niced_granularity(struct sched_entity *curr, unsigned long granularity) | |||
| 222 | { | 222 | { |
| 223 | u64 tmp; | 223 | u64 tmp; |
| 224 | 224 | ||
| 225 | if (likely(curr->load.weight == NICE_0_LOAD)) | ||
| 226 | return granularity; | ||
| 225 | /* | 227 | /* |
| 226 | * Negative nice levels get the same granularity as nice-0: | 228 | * Positive nice levels get the same granularity as nice-0: |
| 227 | */ | 229 | */ |
| 228 | if (likely(curr->load.weight >= NICE_0_LOAD)) | 230 | if (likely(curr->load.weight < NICE_0_LOAD)) { |
| 229 | return granularity; | 231 | tmp = curr->load.weight * (u64)granularity; |
| 232 | return (long) (tmp >> NICE_0_SHIFT); | ||
| 233 | } | ||
| 230 | /* | 234 | /* |
| 231 | * Positive nice level tasks get linearly finer | 235 | * Negative nice level tasks get linearly finer |
| 232 | * granularity: | 236 | * granularity: |
| 233 | */ | 237 | */ |
| 234 | tmp = curr->load.weight * (u64)granularity; | 238 | tmp = curr->load.inv_weight * (u64)granularity; |
| 235 | 239 | ||
| 236 | /* | 240 | /* |
| 237 | * It will always fit into 'long': | 241 | * It will always fit into 'long': |
| 238 | */ | 242 | */ |
| 239 | return (long) (tmp >> NICE_0_SHIFT); | 243 | return (long) (tmp >> WMULT_SHIFT); |
| 240 | } | 244 | } |
| 241 | 245 | ||
| 242 | static inline void | 246 | static inline void |
| @@ -281,26 +285,25 @@ add_wait_runtime(struct cfs_rq *cfs_rq, struct sched_entity *se, long delta) | |||
| 281 | * are not in our scheduling class. | 285 | * are not in our scheduling class. |
| 282 | */ | 286 | */ |
| 283 | static inline void | 287 | static inline void |
| 284 | __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr, u64 now) | 288 | __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr) |
| 285 | { | 289 | { |
| 286 | unsigned long delta, delta_exec, delta_fair; | 290 | unsigned long delta, delta_exec, delta_fair, delta_mine; |
| 287 | long delta_mine; | ||
| 288 | struct load_weight *lw = &cfs_rq->load; | 291 | struct load_weight *lw = &cfs_rq->load; |
| 289 | unsigned long load = lw->weight; | 292 | unsigned long load = lw->weight; |
| 290 | 293 | ||
| 291 | if (unlikely(!load)) | ||
| 292 | return; | ||
| 293 | |||
| 294 | delta_exec = curr->delta_exec; | 294 | delta_exec = curr->delta_exec; |
| 295 | schedstat_set(curr->exec_max, max((u64)delta_exec, curr->exec_max)); | 295 | schedstat_set(curr->exec_max, max((u64)delta_exec, curr->exec_max)); |
| 296 | 296 | ||
| 297 | curr->sum_exec_runtime += delta_exec; | 297 | curr->sum_exec_runtime += delta_exec; |
| 298 | cfs_rq->exec_clock += delta_exec; | 298 | cfs_rq->exec_clock += delta_exec; |
| 299 | 299 | ||
| 300 | if (unlikely(!load)) | ||
| 301 | return; | ||
| 302 | |||
| 300 | delta_fair = calc_delta_fair(delta_exec, lw); | 303 | delta_fair = calc_delta_fair(delta_exec, lw); |
| 301 | delta_mine = calc_delta_mine(delta_exec, curr->load.weight, lw); | 304 | delta_mine = calc_delta_mine(delta_exec, curr->load.weight, lw); |
| 302 | 305 | ||
| 303 | if (cfs_rq->sleeper_bonus > sysctl_sched_stat_granularity) { | 306 | if (cfs_rq->sleeper_bonus > sysctl_sched_granularity) { |
| 304 | delta = calc_delta_mine(cfs_rq->sleeper_bonus, | 307 | delta = calc_delta_mine(cfs_rq->sleeper_bonus, |
| 305 | curr->load.weight, lw); | 308 | curr->load.weight, lw); |
| 306 | if (unlikely(delta > cfs_rq->sleeper_bonus)) | 309 | if (unlikely(delta > cfs_rq->sleeper_bonus)) |
| @@ -321,7 +324,7 @@ __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr, u64 now) | |||
| 321 | add_wait_runtime(cfs_rq, curr, delta_mine - delta_exec); | 324 | add_wait_runtime(cfs_rq, curr, delta_mine - delta_exec); |
| 322 | } | 325 | } |
| 323 | 326 | ||
| 324 | static void update_curr(struct cfs_rq *cfs_rq, u64 now) | 327 | static void update_curr(struct cfs_rq *cfs_rq) |
| 325 | { | 328 | { |
| 326 | struct sched_entity *curr = cfs_rq_curr(cfs_rq); | 329 | struct sched_entity *curr = cfs_rq_curr(cfs_rq); |
| 327 | unsigned long delta_exec; | 330 | unsigned long delta_exec; |
| @@ -334,22 +337,22 @@ static void update_curr(struct cfs_rq *cfs_rq, u64 now) | |||
| 334 | * since the last time we changed load (this cannot | 337 | * since the last time we changed load (this cannot |
| 335 | * overflow on 32 bits): | 338 | * overflow on 32 bits): |
| 336 | */ | 339 | */ |
| 337 | delta_exec = (unsigned long)(now - curr->exec_start); | 340 | delta_exec = (unsigned long)(rq_of(cfs_rq)->clock - curr->exec_start); |
| 338 | 341 | ||
| 339 | curr->delta_exec += delta_exec; | 342 | curr->delta_exec += delta_exec; |
| 340 | 343 | ||
| 341 | if (unlikely(curr->delta_exec > sysctl_sched_stat_granularity)) { | 344 | if (unlikely(curr->delta_exec > sysctl_sched_stat_granularity)) { |
| 342 | __update_curr(cfs_rq, curr, now); | 345 | __update_curr(cfs_rq, curr); |
| 343 | curr->delta_exec = 0; | 346 | curr->delta_exec = 0; |
| 344 | } | 347 | } |
| 345 | curr->exec_start = now; | 348 | curr->exec_start = rq_of(cfs_rq)->clock; |
| 346 | } | 349 | } |
| 347 | 350 | ||
| 348 | static inline void | 351 | static inline void |
| 349 | update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | 352 | update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se) |
| 350 | { | 353 | { |
| 351 | se->wait_start_fair = cfs_rq->fair_clock; | 354 | se->wait_start_fair = cfs_rq->fair_clock; |
| 352 | schedstat_set(se->wait_start, now); | 355 | schedstat_set(se->wait_start, rq_of(cfs_rq)->clock); |
| 353 | } | 356 | } |
| 354 | 357 | ||
| 355 | /* | 358 | /* |
| @@ -377,8 +380,7 @@ calc_weighted(unsigned long delta, unsigned long weight, int shift) | |||
| 377 | /* | 380 | /* |
| 378 | * Task is being enqueued - update stats: | 381 | * Task is being enqueued - update stats: |
| 379 | */ | 382 | */ |
| 380 | static void | 383 | static void update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se) |
| 381 | update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | ||
| 382 | { | 384 | { |
| 383 | s64 key; | 385 | s64 key; |
| 384 | 386 | ||
| @@ -387,7 +389,7 @@ update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | |||
| 387 | * a dequeue/enqueue event is a NOP) | 389 | * a dequeue/enqueue event is a NOP) |
| 388 | */ | 390 | */ |
| 389 | if (se != cfs_rq_curr(cfs_rq)) | 391 | if (se != cfs_rq_curr(cfs_rq)) |
| 390 | update_stats_wait_start(cfs_rq, se, now); | 392 | update_stats_wait_start(cfs_rq, se); |
| 391 | /* | 393 | /* |
| 392 | * Update the key: | 394 | * Update the key: |
| 393 | */ | 395 | */ |
| @@ -407,7 +409,8 @@ update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | |||
| 407 | (WMULT_SHIFT - NICE_0_SHIFT); | 409 | (WMULT_SHIFT - NICE_0_SHIFT); |
| 408 | } else { | 410 | } else { |
| 409 | tmp = se->wait_runtime; | 411 | tmp = se->wait_runtime; |
| 410 | key -= (tmp * se->load.weight) >> NICE_0_SHIFT; | 412 | key -= (tmp * se->load.inv_weight) >> |
| 413 | (WMULT_SHIFT - NICE_0_SHIFT); | ||
| 411 | } | 414 | } |
| 412 | } | 415 | } |
| 413 | 416 | ||
| @@ -418,11 +421,12 @@ update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | |||
| 418 | * Note: must be called with a freshly updated rq->fair_clock. | 421 | * Note: must be called with a freshly updated rq->fair_clock. |
| 419 | */ | 422 | */ |
| 420 | static inline void | 423 | static inline void |
| 421 | __update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | 424 | __update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se) |
| 422 | { | 425 | { |
| 423 | unsigned long delta_fair = se->delta_fair_run; | 426 | unsigned long delta_fair = se->delta_fair_run; |
| 424 | 427 | ||
| 425 | schedstat_set(se->wait_max, max(se->wait_max, now - se->wait_start)); | 428 | schedstat_set(se->wait_max, max(se->wait_max, |
| 429 | rq_of(cfs_rq)->clock - se->wait_start)); | ||
| 426 | 430 | ||
| 427 | if (unlikely(se->load.weight != NICE_0_LOAD)) | 431 | if (unlikely(se->load.weight != NICE_0_LOAD)) |
| 428 | delta_fair = calc_weighted(delta_fair, se->load.weight, | 432 | delta_fair = calc_weighted(delta_fair, se->load.weight, |
| @@ -432,7 +436,7 @@ __update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | |||
| 432 | } | 436 | } |
| 433 | 437 | ||
| 434 | static void | 438 | static void |
| 435 | update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | 439 | update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se) |
| 436 | { | 440 | { |
| 437 | unsigned long delta_fair; | 441 | unsigned long delta_fair; |
| 438 | 442 | ||
| @@ -442,7 +446,7 @@ update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | |||
| 442 | se->delta_fair_run += delta_fair; | 446 | se->delta_fair_run += delta_fair; |
| 443 | if (unlikely(abs(se->delta_fair_run) >= | 447 | if (unlikely(abs(se->delta_fair_run) >= |
| 444 | sysctl_sched_stat_granularity)) { | 448 | sysctl_sched_stat_granularity)) { |
| 445 | __update_stats_wait_end(cfs_rq, se, now); | 449 | __update_stats_wait_end(cfs_rq, se); |
| 446 | se->delta_fair_run = 0; | 450 | se->delta_fair_run = 0; |
| 447 | } | 451 | } |
| 448 | 452 | ||
| @@ -451,34 +455,34 @@ update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | |||
| 451 | } | 455 | } |
| 452 | 456 | ||
| 453 | static inline void | 457 | static inline void |
| 454 | update_stats_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | 458 | update_stats_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se) |
| 455 | { | 459 | { |
| 456 | update_curr(cfs_rq, now); | 460 | update_curr(cfs_rq); |
| 457 | /* | 461 | /* |
| 458 | * Mark the end of the wait period if dequeueing a | 462 | * Mark the end of the wait period if dequeueing a |
| 459 | * waiting task: | 463 | * waiting task: |
| 460 | */ | 464 | */ |
| 461 | if (se != cfs_rq_curr(cfs_rq)) | 465 | if (se != cfs_rq_curr(cfs_rq)) |
| 462 | update_stats_wait_end(cfs_rq, se, now); | 466 | update_stats_wait_end(cfs_rq, se); |
| 463 | } | 467 | } |
| 464 | 468 | ||
| 465 | /* | 469 | /* |
| 466 | * We are picking a new current task - update its stats: | 470 | * We are picking a new current task - update its stats: |
| 467 | */ | 471 | */ |
| 468 | static inline void | 472 | static inline void |
| 469 | update_stats_curr_start(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | 473 | update_stats_curr_start(struct cfs_rq *cfs_rq, struct sched_entity *se) |
| 470 | { | 474 | { |
| 471 | /* | 475 | /* |
| 472 | * We are starting a new run period: | 476 | * We are starting a new run period: |
| 473 | */ | 477 | */ |
| 474 | se->exec_start = now; | 478 | se->exec_start = rq_of(cfs_rq)->clock; |
| 475 | } | 479 | } |
| 476 | 480 | ||
| 477 | /* | 481 | /* |
| 478 | * We are descheduling a task - update its stats: | 482 | * We are descheduling a task - update its stats: |
| 479 | */ | 483 | */ |
| 480 | static inline void | 484 | static inline void |
| 481 | update_stats_curr_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | 485 | update_stats_curr_end(struct cfs_rq *cfs_rq, struct sched_entity *se) |
| 482 | { | 486 | { |
| 483 | se->exec_start = 0; | 487 | se->exec_start = 0; |
| 484 | } | 488 | } |
| @@ -487,8 +491,7 @@ update_stats_curr_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | |||
| 487 | * Scheduling class queueing methods: | 491 | * Scheduling class queueing methods: |
| 488 | */ | 492 | */ |
| 489 | 493 | ||
| 490 | static void | 494 | static void __enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se) |
| 491 | __enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | ||
| 492 | { | 495 | { |
| 493 | unsigned long load = cfs_rq->load.weight, delta_fair; | 496 | unsigned long load = cfs_rq->load.weight, delta_fair; |
| 494 | long prev_runtime; | 497 | long prev_runtime; |
| @@ -522,8 +525,7 @@ __enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | |||
| 522 | schedstat_add(cfs_rq, wait_runtime, se->wait_runtime); | 525 | schedstat_add(cfs_rq, wait_runtime, se->wait_runtime); |
| 523 | } | 526 | } |
| 524 | 527 | ||
| 525 | static void | 528 | static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se) |
| 526 | enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | ||
| 527 | { | 529 | { |
| 528 | struct task_struct *tsk = task_of(se); | 530 | struct task_struct *tsk = task_of(se); |
| 529 | unsigned long delta_fair; | 531 | unsigned long delta_fair; |
| @@ -538,7 +540,7 @@ enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | |||
| 538 | se->delta_fair_sleep += delta_fair; | 540 | se->delta_fair_sleep += delta_fair; |
| 539 | if (unlikely(abs(se->delta_fair_sleep) >= | 541 | if (unlikely(abs(se->delta_fair_sleep) >= |
| 540 | sysctl_sched_stat_granularity)) { | 542 | sysctl_sched_stat_granularity)) { |
| 541 | __enqueue_sleeper(cfs_rq, se, now); | 543 | __enqueue_sleeper(cfs_rq, se); |
| 542 | se->delta_fair_sleep = 0; | 544 | se->delta_fair_sleep = 0; |
| 543 | } | 545 | } |
| 544 | 546 | ||
| @@ -546,7 +548,7 @@ enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | |||
| 546 | 548 | ||
| 547 | #ifdef CONFIG_SCHEDSTATS | 549 | #ifdef CONFIG_SCHEDSTATS |
| 548 | if (se->sleep_start) { | 550 | if (se->sleep_start) { |
| 549 | u64 delta = now - se->sleep_start; | 551 | u64 delta = rq_of(cfs_rq)->clock - se->sleep_start; |
| 550 | 552 | ||
| 551 | if ((s64)delta < 0) | 553 | if ((s64)delta < 0) |
| 552 | delta = 0; | 554 | delta = 0; |
| @@ -558,7 +560,7 @@ enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | |||
| 558 | se->sum_sleep_runtime += delta; | 560 | se->sum_sleep_runtime += delta; |
| 559 | } | 561 | } |
| 560 | if (se->block_start) { | 562 | if (se->block_start) { |
| 561 | u64 delta = now - se->block_start; | 563 | u64 delta = rq_of(cfs_rq)->clock - se->block_start; |
| 562 | 564 | ||
| 563 | if ((s64)delta < 0) | 565 | if ((s64)delta < 0) |
| 564 | delta = 0; | 566 | delta = 0; |
| @@ -573,26 +575,24 @@ enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | |||
| 573 | } | 575 | } |
| 574 | 576 | ||
| 575 | static void | 577 | static void |
| 576 | enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, | 578 | enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup) |
| 577 | int wakeup, u64 now) | ||
| 578 | { | 579 | { |
| 579 | /* | 580 | /* |
| 580 | * Update the fair clock. | 581 | * Update the fair clock. |
| 581 | */ | 582 | */ |
| 582 | update_curr(cfs_rq, now); | 583 | update_curr(cfs_rq); |
| 583 | 584 | ||
| 584 | if (wakeup) | 585 | if (wakeup) |
| 585 | enqueue_sleeper(cfs_rq, se, now); | 586 | enqueue_sleeper(cfs_rq, se); |
| 586 | 587 | ||
| 587 | update_stats_enqueue(cfs_rq, se, now); | 588 | update_stats_enqueue(cfs_rq, se); |
| 588 | __enqueue_entity(cfs_rq, se); | 589 | __enqueue_entity(cfs_rq, se); |
| 589 | } | 590 | } |
| 590 | 591 | ||
| 591 | static void | 592 | static void |
| 592 | dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, | 593 | dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep) |
| 593 | int sleep, u64 now) | ||
| 594 | { | 594 | { |
| 595 | update_stats_dequeue(cfs_rq, se, now); | 595 | update_stats_dequeue(cfs_rq, se); |
| 596 | if (sleep) { | 596 | if (sleep) { |
| 597 | se->sleep_start_fair = cfs_rq->fair_clock; | 597 | se->sleep_start_fair = cfs_rq->fair_clock; |
| 598 | #ifdef CONFIG_SCHEDSTATS | 598 | #ifdef CONFIG_SCHEDSTATS |
| @@ -600,9 +600,9 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, | |||
| 600 | struct task_struct *tsk = task_of(se); | 600 | struct task_struct *tsk = task_of(se); |
| 601 | 601 | ||
| 602 | if (tsk->state & TASK_INTERRUPTIBLE) | 602 | if (tsk->state & TASK_INTERRUPTIBLE) |
| 603 | se->sleep_start = now; | 603 | se->sleep_start = rq_of(cfs_rq)->clock; |
| 604 | if (tsk->state & TASK_UNINTERRUPTIBLE) | 604 | if (tsk->state & TASK_UNINTERRUPTIBLE) |
| 605 | se->block_start = now; | 605 | se->block_start = rq_of(cfs_rq)->clock; |
| 606 | } | 606 | } |
| 607 | cfs_rq->wait_runtime -= se->wait_runtime; | 607 | cfs_rq->wait_runtime -= se->wait_runtime; |
| 608 | #endif | 608 | #endif |
| @@ -629,7 +629,7 @@ __check_preempt_curr_fair(struct cfs_rq *cfs_rq, struct sched_entity *se, | |||
| 629 | } | 629 | } |
| 630 | 630 | ||
| 631 | static inline void | 631 | static inline void |
| 632 | set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | 632 | set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) |
| 633 | { | 633 | { |
| 634 | /* | 634 | /* |
| 635 | * Any task has to be enqueued before it get to execute on | 635 | * Any task has to be enqueued before it get to execute on |
| @@ -638,49 +638,46 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now) | |||
| 638 | * done a put_prev_task_fair() shortly before this, which | 638 | * done a put_prev_task_fair() shortly before this, which |
| 639 | * updated rq->fair_clock - used by update_stats_wait_end()) | 639 | * updated rq->fair_clock - used by update_stats_wait_end()) |
| 640 | */ | 640 | */ |
| 641 | update_stats_wait_end(cfs_rq, se, now); | 641 | update_stats_wait_end(cfs_rq, se); |
| 642 | update_stats_curr_start(cfs_rq, se, now); | 642 | update_stats_curr_start(cfs_rq, se); |
| 643 | set_cfs_rq_curr(cfs_rq, se); | 643 | set_cfs_rq_curr(cfs_rq, se); |
| 644 | } | 644 | } |
| 645 | 645 | ||
| 646 | static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq, u64 now) | 646 | static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq) |
| 647 | { | 647 | { |
| 648 | struct sched_entity *se = __pick_next_entity(cfs_rq); | 648 | struct sched_entity *se = __pick_next_entity(cfs_rq); |
| 649 | 649 | ||
| 650 | set_next_entity(cfs_rq, se, now); | 650 | set_next_entity(cfs_rq, se); |
| 651 | 651 | ||
| 652 | return se; | 652 | return se; |
| 653 | } | 653 | } |
| 654 | 654 | ||
| 655 | static void | 655 | static void put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev) |
| 656 | put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev, u64 now) | ||
| 657 | { | 656 | { |
| 658 | /* | 657 | /* |
| 659 | * If still on the runqueue then deactivate_task() | 658 | * If still on the runqueue then deactivate_task() |
| 660 | * was not called and update_curr() has to be done: | 659 | * was not called and update_curr() has to be done: |
| 661 | */ | 660 | */ |
| 662 | if (prev->on_rq) | 661 | if (prev->on_rq) |
| 663 | update_curr(cfs_rq, now); | 662 | update_curr(cfs_rq); |
| 664 | 663 | ||
| 665 | update_stats_curr_end(cfs_rq, prev, now); | 664 | update_stats_curr_end(cfs_rq, prev); |
| 666 | 665 | ||
| 667 | if (prev->on_rq) | 666 | if (prev->on_rq) |
| 668 | update_stats_wait_start(cfs_rq, prev, now); | 667 | update_stats_wait_start(cfs_rq, prev); |
| 669 | set_cfs_rq_curr(cfs_rq, NULL); | 668 | set_cfs_rq_curr(cfs_rq, NULL); |
| 670 | } | 669 | } |
| 671 | 670 | ||
| 672 | static void entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr) | 671 | static void entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr) |
| 673 | { | 672 | { |
| 674 | struct rq *rq = rq_of(cfs_rq); | ||
| 675 | struct sched_entity *next; | 673 | struct sched_entity *next; |
| 676 | u64 now = __rq_clock(rq); | ||
| 677 | 674 | ||
| 678 | /* | 675 | /* |
| 679 | * Dequeue and enqueue the task to update its | 676 | * Dequeue and enqueue the task to update its |
| 680 | * position within the tree: | 677 | * position within the tree: |
| 681 | */ | 678 | */ |
| 682 | dequeue_entity(cfs_rq, curr, 0, now); | 679 | dequeue_entity(cfs_rq, curr, 0); |
| 683 | enqueue_entity(cfs_rq, curr, 0, now); | 680 | enqueue_entity(cfs_rq, curr, 0); |
| 684 | 681 | ||
| 685 | /* | 682 | /* |
| 686 | * Reschedule if another task tops the current one. | 683 | * Reschedule if another task tops the current one. |
| @@ -785,8 +782,7 @@ static inline int is_same_group(struct task_struct *curr, struct task_struct *p) | |||
| 785 | * increased. Here we update the fair scheduling stats and | 782 | * increased. Here we update the fair scheduling stats and |
| 786 | * then put the task into the rbtree: | 783 | * then put the task into the rbtree: |
| 787 | */ | 784 | */ |
| 788 | static void | 785 | static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup) |
| 789 | enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup, u64 now) | ||
| 790 | { | 786 | { |
| 791 | struct cfs_rq *cfs_rq; | 787 | struct cfs_rq *cfs_rq; |
| 792 | struct sched_entity *se = &p->se; | 788 | struct sched_entity *se = &p->se; |
| @@ -795,7 +791,7 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup, u64 now) | |||
| 795 | if (se->on_rq) | 791 | if (se->on_rq) |
| 796 | break; | 792 | break; |
| 797 | cfs_rq = cfs_rq_of(se); | 793 | cfs_rq = cfs_rq_of(se); |
| 798 | enqueue_entity(cfs_rq, se, wakeup, now); | 794 | enqueue_entity(cfs_rq, se, wakeup); |
| 799 | } | 795 | } |
| 800 | } | 796 | } |
| 801 | 797 | ||
| @@ -804,15 +800,14 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup, u64 now) | |||
| 804 | * decreased. We remove the task from the rbtree and | 800 | * decreased. We remove the task from the rbtree and |
| 805 | * update the fair scheduling stats: | 801 | * update the fair scheduling stats: |
| 806 | */ | 802 | */ |
| 807 | static void | 803 | static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep) |
| 808 | dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep, u64 now) | ||
| 809 | { | 804 | { |
| 810 | struct cfs_rq *cfs_rq; | 805 | struct cfs_rq *cfs_rq; |
| 811 | struct sched_entity *se = &p->se; | 806 | struct sched_entity *se = &p->se; |
| 812 | 807 | ||
| 813 | for_each_sched_entity(se) { | 808 | for_each_sched_entity(se) { |
| 814 | cfs_rq = cfs_rq_of(se); | 809 | cfs_rq = cfs_rq_of(se); |
| 815 | dequeue_entity(cfs_rq, se, sleep, now); | 810 | dequeue_entity(cfs_rq, se, sleep); |
| 816 | /* Don't dequeue parent if it has other entities besides us */ | 811 | /* Don't dequeue parent if it has other entities besides us */ |
| 817 | if (cfs_rq->load.weight) | 812 | if (cfs_rq->load.weight) |
| 818 | break; | 813 | break; |
| @@ -825,14 +820,14 @@ dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep, u64 now) | |||
| 825 | static void yield_task_fair(struct rq *rq, struct task_struct *p) | 820 | static void yield_task_fair(struct rq *rq, struct task_struct *p) |
| 826 | { | 821 | { |
| 827 | struct cfs_rq *cfs_rq = task_cfs_rq(p); | 822 | struct cfs_rq *cfs_rq = task_cfs_rq(p); |
| 828 | u64 now = __rq_clock(rq); | ||
| 829 | 823 | ||
| 824 | __update_rq_clock(rq); | ||
| 830 | /* | 825 | /* |
| 831 | * Dequeue and enqueue the task to update its | 826 | * Dequeue and enqueue the task to update its |
| 832 | * position within the tree: | 827 | * position within the tree: |
| 833 | */ | 828 | */ |
| 834 | dequeue_entity(cfs_rq, &p->se, 0, now); | 829 | dequeue_entity(cfs_rq, &p->se, 0); |
| 835 | enqueue_entity(cfs_rq, &p->se, 0, now); | 830 | enqueue_entity(cfs_rq, &p->se, 0); |
| 836 | } | 831 | } |
| 837 | 832 | ||
| 838 | /* | 833 | /* |
| @@ -845,7 +840,8 @@ static void check_preempt_curr_fair(struct rq *rq, struct task_struct *p) | |||
| 845 | unsigned long gran; | 840 | unsigned long gran; |
| 846 | 841 | ||
| 847 | if (unlikely(rt_prio(p->prio))) { | 842 | if (unlikely(rt_prio(p->prio))) { |
| 848 | update_curr(cfs_rq, rq_clock(rq)); | 843 | update_rq_clock(rq); |
| 844 | update_curr(cfs_rq); | ||
| 849 | resched_task(curr); | 845 | resched_task(curr); |
| 850 | return; | 846 | return; |
| 851 | } | 847 | } |
| @@ -861,7 +857,7 @@ static void check_preempt_curr_fair(struct rq *rq, struct task_struct *p) | |||
| 861 | __check_preempt_curr_fair(cfs_rq, &p->se, &curr->se, gran); | 857 | __check_preempt_curr_fair(cfs_rq, &p->se, &curr->se, gran); |
| 862 | } | 858 | } |
| 863 | 859 | ||
| 864 | static struct task_struct *pick_next_task_fair(struct rq *rq, u64 now) | 860 | static struct task_struct *pick_next_task_fair(struct rq *rq) |
| 865 | { | 861 | { |
| 866 | struct cfs_rq *cfs_rq = &rq->cfs; | 862 | struct cfs_rq *cfs_rq = &rq->cfs; |
| 867 | struct sched_entity *se; | 863 | struct sched_entity *se; |
| @@ -870,7 +866,7 @@ static struct task_struct *pick_next_task_fair(struct rq *rq, u64 now) | |||
| 870 | return NULL; | 866 | return NULL; |
| 871 | 867 | ||
| 872 | do { | 868 | do { |
| 873 | se = pick_next_entity(cfs_rq, now); | 869 | se = pick_next_entity(cfs_rq); |
| 874 | cfs_rq = group_cfs_rq(se); | 870 | cfs_rq = group_cfs_rq(se); |
| 875 | } while (cfs_rq); | 871 | } while (cfs_rq); |
| 876 | 872 | ||
| @@ -880,14 +876,14 @@ static struct task_struct *pick_next_task_fair(struct rq *rq, u64 now) | |||
| 880 | /* | 876 | /* |
| 881 | * Account for a descheduled task: | 877 | * Account for a descheduled task: |
| 882 | */ | 878 | */ |
| 883 | static void put_prev_task_fair(struct rq *rq, struct task_struct *prev, u64 now) | 879 | static void put_prev_task_fair(struct rq *rq, struct task_struct *prev) |
| 884 | { | 880 | { |
| 885 | struct sched_entity *se = &prev->se; | 881 | struct sched_entity *se = &prev->se; |
| 886 | struct cfs_rq *cfs_rq; | 882 | struct cfs_rq *cfs_rq; |
| 887 | 883 | ||
| 888 | for_each_sched_entity(se) { | 884 | for_each_sched_entity(se) { |
| 889 | cfs_rq = cfs_rq_of(se); | 885 | cfs_rq = cfs_rq_of(se); |
| 890 | put_prev_entity(cfs_rq, se, now); | 886 | put_prev_entity(cfs_rq, se); |
| 891 | } | 887 | } |
| 892 | } | 888 | } |
| 893 | 889 | ||
| @@ -930,6 +926,7 @@ static struct task_struct *load_balance_next_fair(void *arg) | |||
| 930 | return __load_balance_iterator(cfs_rq, cfs_rq->rb_load_balance_curr); | 926 | return __load_balance_iterator(cfs_rq, cfs_rq->rb_load_balance_curr); |
| 931 | } | 927 | } |
| 932 | 928 | ||
| 929 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
| 933 | static int cfs_rq_best_prio(struct cfs_rq *cfs_rq) | 930 | static int cfs_rq_best_prio(struct cfs_rq *cfs_rq) |
| 934 | { | 931 | { |
| 935 | struct sched_entity *curr; | 932 | struct sched_entity *curr; |
| @@ -943,12 +940,13 @@ static int cfs_rq_best_prio(struct cfs_rq *cfs_rq) | |||
| 943 | 940 | ||
| 944 | return p->prio; | 941 | return p->prio; |
| 945 | } | 942 | } |
| 943 | #endif | ||
| 946 | 944 | ||
| 947 | static int | 945 | static unsigned long |
| 948 | load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, | 946 | load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, |
| 949 | unsigned long max_nr_move, unsigned long max_load_move, | 947 | unsigned long max_nr_move, unsigned long max_load_move, |
| 950 | struct sched_domain *sd, enum cpu_idle_type idle, | 948 | struct sched_domain *sd, enum cpu_idle_type idle, |
| 951 | int *all_pinned, unsigned long *total_load_moved) | 949 | int *all_pinned, int *this_best_prio) |
| 952 | { | 950 | { |
| 953 | struct cfs_rq *busy_cfs_rq; | 951 | struct cfs_rq *busy_cfs_rq; |
| 954 | unsigned long load_moved, total_nr_moved = 0, nr_moved; | 952 | unsigned long load_moved, total_nr_moved = 0, nr_moved; |
| @@ -959,15 +957,14 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
| 959 | cfs_rq_iterator.next = load_balance_next_fair; | 957 | cfs_rq_iterator.next = load_balance_next_fair; |
| 960 | 958 | ||
| 961 | for_each_leaf_cfs_rq(busiest, busy_cfs_rq) { | 959 | for_each_leaf_cfs_rq(busiest, busy_cfs_rq) { |
| 960 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
| 962 | struct cfs_rq *this_cfs_rq; | 961 | struct cfs_rq *this_cfs_rq; |
| 963 | long imbalance; | 962 | long imbalance; |
| 964 | unsigned long maxload; | 963 | unsigned long maxload; |
| 965 | int this_best_prio, best_prio, best_prio_seen = 0; | ||
| 966 | 964 | ||
| 967 | this_cfs_rq = cpu_cfs_rq(busy_cfs_rq, this_cpu); | 965 | this_cfs_rq = cpu_cfs_rq(busy_cfs_rq, this_cpu); |
| 968 | 966 | ||
| 969 | imbalance = busy_cfs_rq->load.weight - | 967 | imbalance = busy_cfs_rq->load.weight - this_cfs_rq->load.weight; |
| 970 | this_cfs_rq->load.weight; | ||
| 971 | /* Don't pull if this_cfs_rq has more load than busy_cfs_rq */ | 968 | /* Don't pull if this_cfs_rq has more load than busy_cfs_rq */ |
| 972 | if (imbalance <= 0) | 969 | if (imbalance <= 0) |
| 973 | continue; | 970 | continue; |
| @@ -976,27 +973,17 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
| 976 | imbalance /= 2; | 973 | imbalance /= 2; |
| 977 | maxload = min(rem_load_move, imbalance); | 974 | maxload = min(rem_load_move, imbalance); |
| 978 | 975 | ||
| 979 | this_best_prio = cfs_rq_best_prio(this_cfs_rq); | 976 | *this_best_prio = cfs_rq_best_prio(this_cfs_rq); |
| 980 | best_prio = cfs_rq_best_prio(busy_cfs_rq); | 977 | #else |
| 981 | 978 | # define maxload rem_load_move | |
| 982 | /* | 979 | #endif |
| 983 | * Enable handling of the case where there is more than one task | ||
| 984 | * with the best priority. If the current running task is one | ||
| 985 | * of those with prio==best_prio we know it won't be moved | ||
| 986 | * and therefore it's safe to override the skip (based on load) | ||
| 987 | * of any task we find with that prio. | ||
| 988 | */ | ||
| 989 | if (cfs_rq_curr(busy_cfs_rq) == &busiest->curr->se) | ||
| 990 | best_prio_seen = 1; | ||
| 991 | |||
| 992 | /* pass busy_cfs_rq argument into | 980 | /* pass busy_cfs_rq argument into |
| 993 | * load_balance_[start|next]_fair iterators | 981 | * load_balance_[start|next]_fair iterators |
| 994 | */ | 982 | */ |
| 995 | cfs_rq_iterator.arg = busy_cfs_rq; | 983 | cfs_rq_iterator.arg = busy_cfs_rq; |
| 996 | nr_moved = balance_tasks(this_rq, this_cpu, busiest, | 984 | nr_moved = balance_tasks(this_rq, this_cpu, busiest, |
| 997 | max_nr_move, maxload, sd, idle, all_pinned, | 985 | max_nr_move, maxload, sd, idle, all_pinned, |
| 998 | &load_moved, this_best_prio, best_prio, | 986 | &load_moved, this_best_prio, &cfs_rq_iterator); |
| 999 | best_prio_seen, &cfs_rq_iterator); | ||
| 1000 | 987 | ||
| 1001 | total_nr_moved += nr_moved; | 988 | total_nr_moved += nr_moved; |
| 1002 | max_nr_move -= nr_moved; | 989 | max_nr_move -= nr_moved; |
| @@ -1006,9 +993,7 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
| 1006 | break; | 993 | break; |
| 1007 | } | 994 | } |
| 1008 | 995 | ||
| 1009 | *total_load_moved = max_load_move - rem_load_move; | 996 | return max_load_move - rem_load_move; |
| 1010 | |||
| 1011 | return total_nr_moved; | ||
| 1012 | } | 997 | } |
| 1013 | 998 | ||
| 1014 | /* | 999 | /* |
| @@ -1032,14 +1017,14 @@ static void task_tick_fair(struct rq *rq, struct task_struct *curr) | |||
| 1032 | * monopolize the CPU. Note: the parent runqueue is locked, | 1017 | * monopolize the CPU. Note: the parent runqueue is locked, |
| 1033 | * the child is not running yet. | 1018 | * the child is not running yet. |
| 1034 | */ | 1019 | */ |
| 1035 | static void task_new_fair(struct rq *rq, struct task_struct *p, u64 now) | 1020 | static void task_new_fair(struct rq *rq, struct task_struct *p) |
| 1036 | { | 1021 | { |
| 1037 | struct cfs_rq *cfs_rq = task_cfs_rq(p); | 1022 | struct cfs_rq *cfs_rq = task_cfs_rq(p); |
| 1038 | struct sched_entity *se = &p->se; | 1023 | struct sched_entity *se = &p->se; |
| 1039 | 1024 | ||
| 1040 | sched_info_queued(p); | 1025 | sched_info_queued(p); |
| 1041 | 1026 | ||
| 1042 | update_stats_enqueue(cfs_rq, se, now); | 1027 | update_stats_enqueue(cfs_rq, se); |
| 1043 | /* | 1028 | /* |
| 1044 | * Child runs first: we let it run before the parent | 1029 | * Child runs first: we let it run before the parent |
| 1045 | * until it reschedules once. We set up the key so that | 1030 | * until it reschedules once. We set up the key so that |
| @@ -1072,15 +1057,10 @@ static void task_new_fair(struct rq *rq, struct task_struct *p, u64 now) | |||
| 1072 | */ | 1057 | */ |
| 1073 | static void set_curr_task_fair(struct rq *rq) | 1058 | static void set_curr_task_fair(struct rq *rq) |
| 1074 | { | 1059 | { |
| 1075 | struct task_struct *curr = rq->curr; | 1060 | struct sched_entity *se = &rq->curr.se; |
| 1076 | struct sched_entity *se = &curr->se; | ||
| 1077 | u64 now = rq_clock(rq); | ||
| 1078 | struct cfs_rq *cfs_rq; | ||
| 1079 | 1061 | ||
| 1080 | for_each_sched_entity(se) { | 1062 | for_each_sched_entity(se) |
| 1081 | cfs_rq = cfs_rq_of(se); | 1063 | set_next_entity(cfs_rq_of(se), se); |
| 1082 | set_next_entity(cfs_rq, se, now); | ||
| 1083 | } | ||
| 1084 | } | 1064 | } |
| 1085 | #else | 1065 | #else |
| 1086 | static void set_curr_task_fair(struct rq *rq) | 1066 | static void set_curr_task_fair(struct rq *rq) |
| @@ -1109,12 +1089,11 @@ struct sched_class fair_sched_class __read_mostly = { | |||
| 1109 | }; | 1089 | }; |
| 1110 | 1090 | ||
| 1111 | #ifdef CONFIG_SCHED_DEBUG | 1091 | #ifdef CONFIG_SCHED_DEBUG |
| 1112 | void print_cfs_stats(struct seq_file *m, int cpu, u64 now) | 1092 | static void print_cfs_stats(struct seq_file *m, int cpu) |
| 1113 | { | 1093 | { |
| 1114 | struct rq *rq = cpu_rq(cpu); | ||
| 1115 | struct cfs_rq *cfs_rq; | 1094 | struct cfs_rq *cfs_rq; |
| 1116 | 1095 | ||
| 1117 | for_each_leaf_cfs_rq(rq, cfs_rq) | 1096 | for_each_leaf_cfs_rq(cpu_rq(cpu), cfs_rq) |
| 1118 | print_cfs_rq(m, cpu, cfs_rq, now); | 1097 | print_cfs_rq(m, cpu, cfs_rq); |
| 1119 | } | 1098 | } |
| 1120 | #endif | 1099 | #endif |
