]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - kernel/sched/fair.c
sched/fair: Fix fairness issue on migration
[mirror_ubuntu-bionic-kernel.git] / kernel / sched / fair.c
index 33130529e9b5628b53cd7031c4914da0de0e7148..3c114d971d84fbe641c8d7bc6a20be6e91454752 100644 (file)
@@ -3157,17 +3157,25 @@ static inline void check_schedstat_required(void)
 static void
 enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
 {
+       bool renorm = !(flags & ENQUEUE_WAKEUP) || (flags & ENQUEUE_WAKING);
+       bool curr = cfs_rq->curr == se;
+
        /*
-        * Update the normalized vruntime before updating min_vruntime
-        * through calling update_curr().
+        * If we're the current task, we must renormalise before calling
+        * update_curr().
         */
-       if (!(flags & ENQUEUE_WAKEUP) || (flags & ENQUEUE_WAKING))
+       if (renorm && curr)
                se->vruntime += cfs_rq->min_vruntime;
 
+       update_curr(cfs_rq);
+
        /*
-        * Update run-time statistics of the 'current'.
+        * Otherwise, renormalise after, such that we're placed at the current
+        * moment in time, instead of some random moment in the past.
         */
-       update_curr(cfs_rq);
+       if (renorm && !curr)
+               se->vruntime += cfs_rq->min_vruntime;
+
        enqueue_entity_load_avg(cfs_rq, se);
        account_entity_enqueue(cfs_rq, se);
        update_cfs_shares(cfs_rq);
@@ -3183,7 +3191,7 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
                update_stats_enqueue(cfs_rq, se);
                check_spread(cfs_rq, se);
        }
-       if (se != cfs_rq->curr)
+       if (!curr)
                __enqueue_entity(cfs_rq, se);
        se->on_rq = 1;