aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched_fair.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched_fair.c')
-rw-r--r--kernel/sched_fair.c68
1 files changed, 32 insertions, 36 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 9f93a5c127e8..92563cd5af75 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -472,20 +472,9 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
472} 472}
473 473
474static void 474static void
475enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, 475enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup)
476 int wakeup, int set_curr)
477{ 476{
478 /* 477 /*
479 * In case of the 'current'.
480 */
481 if (unlikely(set_curr)) {
482 update_stats_curr_start(cfs_rq, se);
483 cfs_rq->curr = se;
484 account_entity_enqueue(cfs_rq, se);
485 return;
486 }
487
488 /*
489 * Update the fair clock. 478 * Update the fair clock.
490 */ 479 */
491 update_curr(cfs_rq); 480 update_curr(cfs_rq);
@@ -496,7 +485,8 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
496 } 485 }
497 486
498 update_stats_enqueue(cfs_rq, se); 487 update_stats_enqueue(cfs_rq, se);
499 __enqueue_entity(cfs_rq, se); 488 if (se != cfs_rq->curr)
489 __enqueue_entity(cfs_rq, se);
500 account_entity_enqueue(cfs_rq, se); 490 account_entity_enqueue(cfs_rq, se);
501} 491}
502 492
@@ -516,12 +506,8 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep)
516 } 506 }
517 } 507 }
518#endif 508#endif
519 if (likely(se != cfs_rq->curr)) 509 if (se != cfs_rq->curr)
520 __dequeue_entity(cfs_rq, se); 510 __dequeue_entity(cfs_rq, se);
521 else {
522 update_stats_curr_end(cfs_rq, se);
523 cfs_rq->curr = NULL;
524 }
525 account_entity_dequeue(cfs_rq, se); 511 account_entity_dequeue(cfs_rq, se);
526} 512}
527 513
@@ -539,15 +525,20 @@ check_preempt_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr)
539 resched_task(rq_of(cfs_rq)->curr); 525 resched_task(rq_of(cfs_rq)->curr);
540} 526}
541 527
542static inline void 528static void
543set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) 529set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
544{ 530{
545 /* 531 /* 'current' is not kept within the tree. */
546 * Any task has to be enqueued before it get to execute on 532 if (se->on_rq) {
547 * a CPU. So account for the time it spent waiting on the 533 /*
548 * runqueue. 534 * Any task has to be enqueued before it get to execute on
549 */ 535 * a CPU. So account for the time it spent waiting on the
550 update_stats_wait_end(cfs_rq, se); 536 * runqueue.
537 */
538 update_stats_wait_end(cfs_rq, se);
539 __dequeue_entity(cfs_rq, se);
540 }
541
551 update_stats_curr_start(cfs_rq, se); 542 update_stats_curr_start(cfs_rq, se);
552 cfs_rq->curr = se; 543 cfs_rq->curr = se;
553#ifdef CONFIG_SCHEDSTATS 544#ifdef CONFIG_SCHEDSTATS
@@ -568,10 +559,6 @@ static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq)
568{ 559{
569 struct sched_entity *se = __pick_next_entity(cfs_rq); 560 struct sched_entity *se = __pick_next_entity(cfs_rq);
570 561
571 /* 'current' is not kept within the tree. */
572 if (se)
573 __dequeue_entity(cfs_rq, se);
574
575 set_next_entity(cfs_rq, se); 562 set_next_entity(cfs_rq, se);
576 563
577 return se; 564 return se;
@@ -703,17 +690,12 @@ static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup)
703{ 690{
704 struct cfs_rq *cfs_rq; 691 struct cfs_rq *cfs_rq;
705 struct sched_entity *se = &p->se; 692 struct sched_entity *se = &p->se;
706 int set_curr = 0;
707
708 /* Are we enqueuing the current task? */
709 if (unlikely(task_running(rq, p)))
710 set_curr = 1;
711 693
712 for_each_sched_entity(se) { 694 for_each_sched_entity(se) {
713 if (se->on_rq) 695 if (se->on_rq)
714 break; 696 break;
715 cfs_rq = cfs_rq_of(se); 697 cfs_rq = cfs_rq_of(se);
716 enqueue_entity(cfs_rq, se, wakeup, set_curr); 698 enqueue_entity(cfs_rq, se, wakeup);
717 } 699 }
718} 700}
719 701
@@ -761,7 +743,7 @@ static void yield_task_fair(struct rq *rq)
761 * position within the tree: 743 * position within the tree:
762 */ 744 */
763 dequeue_entity(cfs_rq, se, 0); 745 dequeue_entity(cfs_rq, se, 0);
764 enqueue_entity(cfs_rq, se, 0, 1); 746 enqueue_entity(cfs_rq, se, 0);
765 747
766 return; 748 return;
767 } 749 }
@@ -1004,6 +986,19 @@ static void task_new_fair(struct rq *rq, struct task_struct *p)
1004 resched_task(rq->curr); 986 resched_task(rq->curr);
1005} 987}
1006 988
989/* Account for a task changing its policy or group.
990 *
991 * This routine is mostly called to set cfs_rq->curr field when a task
992 * migrates between groups/classes.
993 */
994static void set_curr_task_fair(struct rq *rq)
995{
996 struct sched_entity *se = &rq->curr->se;
997
998 for_each_sched_entity(se)
999 set_next_entity(cfs_rq_of(se), se);
1000}
1001
1007/* 1002/*
1008 * All the scheduling class methods: 1003 * All the scheduling class methods:
1009 */ 1004 */
@@ -1019,6 +1014,7 @@ struct sched_class fair_sched_class __read_mostly = {
1019 1014
1020 .load_balance = load_balance_fair, 1015 .load_balance = load_balance_fair,
1021 1016
1017 .set_curr_task = set_curr_task_fair,
1022 .task_tick = task_tick_fair, 1018 .task_tick = task_tick_fair,
1023 .task_new = task_new_fair, 1019 .task_new = task_new_fair,
1024}; 1020};