diff options
Diffstat (limited to 'kernel/sched_fair.c')
-rw-r--r-- | kernel/sched_fair.c | 68 |
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 | ||
474 | static void | 474 | static void |
475 | enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, | 475 | enqueue_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 | ||
542 | static inline void | 528 | static void |
543 | set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) | 529 | set_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 | */ | ||
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 | |||
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 | }; |