diff options
Diffstat (limited to 'kernel/sched_fair.c')
-rw-r--r-- | kernel/sched_fair.c | 55 |
1 files changed, 25 insertions, 30 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 4dd256d46853..568e922255c6 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -472,9 +472,20 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) | |||
472 | } | 472 | } |
473 | 473 | ||
474 | static void | 474 | static void |
475 | enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup) | 475 | enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, |
476 | int wakeup, int set_curr) | ||
476 | { | 477 | { |
477 | /* | 478 | /* |
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 | /* | ||
478 | * Update the fair clock. | 489 | * Update the fair clock. |
479 | */ | 490 | */ |
480 | update_curr(cfs_rq); | 491 | update_curr(cfs_rq); |
@@ -485,8 +496,7 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup) | |||
485 | } | 496 | } |
486 | 497 | ||
487 | update_stats_enqueue(cfs_rq, se); | 498 | update_stats_enqueue(cfs_rq, se); |
488 | if (se != cfs_rq->curr) | 499 | __enqueue_entity(cfs_rq, se); |
489 | __enqueue_entity(cfs_rq, se); | ||
490 | account_entity_enqueue(cfs_rq, se); | 500 | account_entity_enqueue(cfs_rq, se); |
491 | } | 501 | } |
492 | 502 | ||
@@ -506,8 +516,12 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep) | |||
506 | } | 516 | } |
507 | } | 517 | } |
508 | #endif | 518 | #endif |
509 | if (se != cfs_rq->curr) | 519 | if (likely(se != cfs_rq->curr)) |
510 | __dequeue_entity(cfs_rq, se); | 520 | __dequeue_entity(cfs_rq, se); |
521 | else { | ||
522 | update_stats_curr_end(cfs_rq, se); | ||
523 | cfs_rq->curr = NULL; | ||
524 | } | ||
511 | account_entity_dequeue(cfs_rq, se); | 525 | account_entity_dequeue(cfs_rq, se); |
512 | } | 526 | } |
513 | 527 | ||
@@ -689,12 +703,17 @@ static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup) | |||
689 | { | 703 | { |
690 | struct cfs_rq *cfs_rq; | 704 | struct cfs_rq *cfs_rq; |
691 | struct sched_entity *se = &p->se; | 705 | 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; | ||
692 | 711 | ||
693 | for_each_sched_entity(se) { | 712 | for_each_sched_entity(se) { |
694 | if (se->on_rq) | 713 | if (se->on_rq) |
695 | break; | 714 | break; |
696 | cfs_rq = cfs_rq_of(se); | 715 | cfs_rq = cfs_rq_of(se); |
697 | enqueue_entity(cfs_rq, se, wakeup); | 716 | enqueue_entity(cfs_rq, se, wakeup, set_curr); |
698 | } | 717 | } |
699 | } | 718 | } |
700 | 719 | ||
@@ -742,7 +761,7 @@ static void yield_task_fair(struct rq *rq) | |||
742 | * position within the tree: | 761 | * position within the tree: |
743 | */ | 762 | */ |
744 | dequeue_entity(cfs_rq, se, 0); | 763 | dequeue_entity(cfs_rq, se, 0); |
745 | enqueue_entity(cfs_rq, se, 0); | 764 | enqueue_entity(cfs_rq, se, 0, 1); |
746 | 765 | ||
747 | return; | 766 | return; |
748 | } | 767 | } |
@@ -985,29 +1004,6 @@ static void task_new_fair(struct rq *rq, struct task_struct *p) | |||
985 | resched_task(rq->curr); | 1004 | resched_task(rq->curr); |
986 | } | 1005 | } |
987 | 1006 | ||
988 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
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 | */ | ||
994 | static 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 | #else | ||
1002 | static void set_curr_task_fair(struct rq *rq) | ||
1003 | { | ||
1004 | struct sched_entity *se = &rq->curr->se; | ||
1005 | struct cfs_rq *cfs_rq = cfs_rq_of(se); | ||
1006 | |||
1007 | cfs_rq->curr = se; | ||
1008 | } | ||
1009 | #endif | ||
1010 | |||
1011 | /* | 1007 | /* |
1012 | * All the scheduling class methods: | 1008 | * All the scheduling class methods: |
1013 | */ | 1009 | */ |
@@ -1023,7 +1019,6 @@ struct sched_class fair_sched_class __read_mostly = { | |||
1023 | 1019 | ||
1024 | .load_balance = load_balance_fair, | 1020 | .load_balance = load_balance_fair, |
1025 | 1021 | ||
1026 | .set_curr_task = set_curr_task_fair, | ||
1027 | .task_tick = task_tick_fair, | 1022 | .task_tick = task_tick_fair, |
1028 | .task_new = task_new_fair, | 1023 | .task_new = task_new_fair, |
1029 | }; | 1024 | }; |