diff options
-rw-r--r-- | include/linux/sched.h | 2 | ||||
-rw-r--r-- | kernel/sched.c | 6 | ||||
-rw-r--r-- | kernel/sched_fair.c | 50 |
3 files changed, 46 insertions, 12 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 2c9fa1ccebff..973b2b89f86d 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1116,7 +1116,7 @@ struct sched_class { | |||
1116 | struct task_struct *task); | 1116 | struct task_struct *task); |
1117 | 1117 | ||
1118 | #ifdef CONFIG_FAIR_GROUP_SCHED | 1118 | #ifdef CONFIG_FAIR_GROUP_SCHED |
1119 | void (*moved_group) (struct task_struct *p); | 1119 | void (*moved_group) (struct task_struct *p, int on_rq); |
1120 | #endif | 1120 | #endif |
1121 | }; | 1121 | }; |
1122 | 1122 | ||
diff --git a/kernel/sched.c b/kernel/sched.c index 6c571bdd5658..f92ce63edfff 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -2038,8 +2038,6 @@ task_hot(struct task_struct *p, u64 now, struct sched_domain *sd) | |||
2038 | void set_task_cpu(struct task_struct *p, unsigned int new_cpu) | 2038 | void set_task_cpu(struct task_struct *p, unsigned int new_cpu) |
2039 | { | 2039 | { |
2040 | int old_cpu = task_cpu(p); | 2040 | int old_cpu = task_cpu(p); |
2041 | struct cfs_rq *old_cfsrq = task_cfs_rq(p), | ||
2042 | *new_cfsrq = cpu_cfs_rq(old_cfsrq, new_cpu); | ||
2043 | 2041 | ||
2044 | #ifdef CONFIG_SCHED_DEBUG | 2042 | #ifdef CONFIG_SCHED_DEBUG |
2045 | /* | 2043 | /* |
@@ -2056,8 +2054,6 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) | |||
2056 | perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS, | 2054 | perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS, |
2057 | 1, 1, NULL, 0); | 2055 | 1, 1, NULL, 0); |
2058 | } | 2056 | } |
2059 | p->se.vruntime -= old_cfsrq->min_vruntime - | ||
2060 | new_cfsrq->min_vruntime; | ||
2061 | 2057 | ||
2062 | __set_task_cpu(p, new_cpu); | 2058 | __set_task_cpu(p, new_cpu); |
2063 | } | 2059 | } |
@@ -10102,7 +10098,7 @@ void sched_move_task(struct task_struct *tsk) | |||
10102 | 10098 | ||
10103 | #ifdef CONFIG_FAIR_GROUP_SCHED | 10099 | #ifdef CONFIG_FAIR_GROUP_SCHED |
10104 | if (tsk->sched_class->moved_group) | 10100 | if (tsk->sched_class->moved_group) |
10105 | tsk->sched_class->moved_group(tsk); | 10101 | tsk->sched_class->moved_group(tsk, on_rq); |
10106 | #endif | 10102 | #endif |
10107 | 10103 | ||
10108 | if (unlikely(running)) | 10104 | if (unlikely(running)) |
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index ec1d2715620c..42ac3c9f66f6 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -510,6 +510,7 @@ __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr, | |||
510 | curr->sum_exec_runtime += delta_exec; | 510 | curr->sum_exec_runtime += delta_exec; |
511 | schedstat_add(cfs_rq, exec_clock, delta_exec); | 511 | schedstat_add(cfs_rq, exec_clock, delta_exec); |
512 | delta_exec_weighted = calc_delta_fair(delta_exec, curr); | 512 | delta_exec_weighted = calc_delta_fair(delta_exec, curr); |
513 | |||
513 | curr->vruntime += delta_exec_weighted; | 514 | curr->vruntime += delta_exec_weighted; |
514 | update_min_vruntime(cfs_rq); | 515 | update_min_vruntime(cfs_rq); |
515 | } | 516 | } |
@@ -765,16 +766,26 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) | |||
765 | se->vruntime = vruntime; | 766 | se->vruntime = vruntime; |
766 | } | 767 | } |
767 | 768 | ||
769 | #define ENQUEUE_WAKEUP 1 | ||
770 | #define ENQUEUE_MIGRATE 2 | ||
771 | |||
768 | static void | 772 | static void |
769 | enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup) | 773 | enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) |
770 | { | 774 | { |
771 | /* | 775 | /* |
776 | * Update the normalized vruntime before updating min_vruntime | ||
777 | * through callig update_curr(). | ||
778 | */ | ||
779 | if (!(flags & ENQUEUE_WAKEUP) || (flags & ENQUEUE_MIGRATE)) | ||
780 | se->vruntime += cfs_rq->min_vruntime; | ||
781 | |||
782 | /* | ||
772 | * Update run-time statistics of the 'current'. | 783 | * Update run-time statistics of the 'current'. |
773 | */ | 784 | */ |
774 | update_curr(cfs_rq); | 785 | update_curr(cfs_rq); |
775 | account_entity_enqueue(cfs_rq, se); | 786 | account_entity_enqueue(cfs_rq, se); |
776 | 787 | ||
777 | if (wakeup) { | 788 | if (flags & ENQUEUE_WAKEUP) { |
778 | place_entity(cfs_rq, se, 0); | 789 | place_entity(cfs_rq, se, 0); |
779 | enqueue_sleeper(cfs_rq, se); | 790 | enqueue_sleeper(cfs_rq, se); |
780 | } | 791 | } |
@@ -828,6 +839,14 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep) | |||
828 | __dequeue_entity(cfs_rq, se); | 839 | __dequeue_entity(cfs_rq, se); |
829 | account_entity_dequeue(cfs_rq, se); | 840 | account_entity_dequeue(cfs_rq, se); |
830 | update_min_vruntime(cfs_rq); | 841 | update_min_vruntime(cfs_rq); |
842 | |||
843 | /* | ||
844 | * Normalize the entity after updating the min_vruntime because the | ||
845 | * update can refer to the ->curr item and we need to reflect this | ||
846 | * movement in our normalized position. | ||
847 | */ | ||
848 | if (!sleep) | ||
849 | se->vruntime -= cfs_rq->min_vruntime; | ||
831 | } | 850 | } |
832 | 851 | ||
833 | /* | 852 | /* |
@@ -1038,13 +1057,19 @@ static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup) | |||
1038 | { | 1057 | { |
1039 | struct cfs_rq *cfs_rq; | 1058 | struct cfs_rq *cfs_rq; |
1040 | struct sched_entity *se = &p->se; | 1059 | struct sched_entity *se = &p->se; |
1060 | int flags = 0; | ||
1061 | |||
1062 | if (wakeup) | ||
1063 | flags |= ENQUEUE_WAKEUP; | ||
1064 | if (p->state == TASK_WAKING) | ||
1065 | flags |= ENQUEUE_MIGRATE; | ||
1041 | 1066 | ||
1042 | for_each_sched_entity(se) { | 1067 | for_each_sched_entity(se) { |
1043 | if (se->on_rq) | 1068 | if (se->on_rq) |
1044 | break; | 1069 | break; |
1045 | cfs_rq = cfs_rq_of(se); | 1070 | cfs_rq = cfs_rq_of(se); |
1046 | enqueue_entity(cfs_rq, se, wakeup); | 1071 | enqueue_entity(cfs_rq, se, flags); |
1047 | wakeup = 1; | 1072 | flags = ENQUEUE_WAKEUP; |
1048 | } | 1073 | } |
1049 | 1074 | ||
1050 | hrtick_update(rq); | 1075 | hrtick_update(rq); |
@@ -1120,6 +1145,14 @@ static void yield_task_fair(struct rq *rq) | |||
1120 | 1145 | ||
1121 | #ifdef CONFIG_SMP | 1146 | #ifdef CONFIG_SMP |
1122 | 1147 | ||
1148 | static void task_waking_fair(struct rq *rq, struct task_struct *p) | ||
1149 | { | ||
1150 | struct sched_entity *se = &p->se; | ||
1151 | struct cfs_rq *cfs_rq = cfs_rq_of(se); | ||
1152 | |||
1153 | se->vruntime -= cfs_rq->min_vruntime; | ||
1154 | } | ||
1155 | |||
1123 | #ifdef CONFIG_FAIR_GROUP_SCHED | 1156 | #ifdef CONFIG_FAIR_GROUP_SCHED |
1124 | /* | 1157 | /* |
1125 | * effective_load() calculates the load change as seen from the root_task_group | 1158 | * effective_load() calculates the load change as seen from the root_task_group |
@@ -1978,6 +2011,8 @@ static void task_fork_fair(struct task_struct *p) | |||
1978 | resched_task(rq->curr); | 2011 | resched_task(rq->curr); |
1979 | } | 2012 | } |
1980 | 2013 | ||
2014 | se->vruntime -= cfs_rq->min_vruntime; | ||
2015 | |||
1981 | raw_spin_unlock_irqrestore(&rq->lock, flags); | 2016 | raw_spin_unlock_irqrestore(&rq->lock, flags); |
1982 | } | 2017 | } |
1983 | 2018 | ||
@@ -2031,12 +2066,13 @@ static void set_curr_task_fair(struct rq *rq) | |||
2031 | } | 2066 | } |
2032 | 2067 | ||
2033 | #ifdef CONFIG_FAIR_GROUP_SCHED | 2068 | #ifdef CONFIG_FAIR_GROUP_SCHED |
2034 | static void moved_group_fair(struct task_struct *p) | 2069 | static void moved_group_fair(struct task_struct *p, int on_rq) |
2035 | { | 2070 | { |
2036 | struct cfs_rq *cfs_rq = task_cfs_rq(p); | 2071 | struct cfs_rq *cfs_rq = task_cfs_rq(p); |
2037 | 2072 | ||
2038 | update_curr(cfs_rq); | 2073 | update_curr(cfs_rq); |
2039 | place_entity(cfs_rq, &p->se, 1); | 2074 | if (!on_rq) |
2075 | place_entity(cfs_rq, &p->se, 1); | ||
2040 | } | 2076 | } |
2041 | #endif | 2077 | #endif |
2042 | 2078 | ||
@@ -2076,6 +2112,8 @@ static const struct sched_class fair_sched_class = { | |||
2076 | .move_one_task = move_one_task_fair, | 2112 | .move_one_task = move_one_task_fair, |
2077 | .rq_online = rq_online_fair, | 2113 | .rq_online = rq_online_fair, |
2078 | .rq_offline = rq_offline_fair, | 2114 | .rq_offline = rq_offline_fair, |
2115 | |||
2116 | .task_waking = task_waking_fair, | ||
2079 | #endif | 2117 | #endif |
2080 | 2118 | ||
2081 | .set_curr_task = set_curr_task_fair, | 2119 | .set_curr_task = set_curr_task_fair, |