|
@@ -2689,16 +2689,20 @@ static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
|
|
|
|
|
|
static inline int throttled_hierarchy(struct cfs_rq *cfs_rq);
|
|
static inline int throttled_hierarchy(struct cfs_rq *cfs_rq);
|
|
|
|
|
|
-static void update_cfs_shares(struct cfs_rq *cfs_rq)
|
|
|
|
|
|
+static void update_cfs_shares(struct sched_entity *se)
|
|
{
|
|
{
|
|
|
|
+ struct cfs_rq *cfs_rq = group_cfs_rq(se);
|
|
struct task_group *tg;
|
|
struct task_group *tg;
|
|
- struct sched_entity *se;
|
|
|
|
long shares;
|
|
long shares;
|
|
|
|
|
|
- tg = cfs_rq->tg;
|
|
|
|
- se = tg->se[cpu_of(rq_of(cfs_rq))];
|
|
|
|
- if (!se || throttled_hierarchy(cfs_rq))
|
|
|
|
|
|
+ if (!cfs_rq)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ if (throttled_hierarchy(cfs_rq))
|
|
return;
|
|
return;
|
|
|
|
+
|
|
|
|
+ tg = cfs_rq->tg;
|
|
|
|
+
|
|
#ifndef CONFIG_SMP
|
|
#ifndef CONFIG_SMP
|
|
if (likely(se->load.weight == tg->shares))
|
|
if (likely(se->load.weight == tg->shares))
|
|
return;
|
|
return;
|
|
@@ -2707,8 +2711,9 @@ static void update_cfs_shares(struct cfs_rq *cfs_rq)
|
|
|
|
|
|
reweight_entity(cfs_rq_of(se), se, shares);
|
|
reweight_entity(cfs_rq_of(se), se, shares);
|
|
}
|
|
}
|
|
|
|
+
|
|
#else /* CONFIG_FAIR_GROUP_SCHED */
|
|
#else /* CONFIG_FAIR_GROUP_SCHED */
|
|
-static inline void update_cfs_shares(struct cfs_rq *cfs_rq)
|
|
|
|
|
|
+static inline void update_cfs_shares(struct sched_entity *se)
|
|
{
|
|
{
|
|
}
|
|
}
|
|
#endif /* CONFIG_FAIR_GROUP_SCHED */
|
|
#endif /* CONFIG_FAIR_GROUP_SCHED */
|
|
@@ -3582,10 +3587,18 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
|
|
if (renorm && !curr)
|
|
if (renorm && !curr)
|
|
se->vruntime += cfs_rq->min_vruntime;
|
|
se->vruntime += cfs_rq->min_vruntime;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * When enqueuing a sched_entity, we must:
|
|
|
|
+ * - Update loads to have both entity and cfs_rq synced with now.
|
|
|
|
+ * - Add its load to cfs_rq->runnable_avg
|
|
|
|
+ * - For group_entity, update its weight to reflect the new share of
|
|
|
|
+ * its group cfs_rq
|
|
|
|
+ * - Add its new weight to cfs_rq->load.weight
|
|
|
|
+ */
|
|
update_load_avg(se, UPDATE_TG);
|
|
update_load_avg(se, UPDATE_TG);
|
|
enqueue_entity_load_avg(cfs_rq, se);
|
|
enqueue_entity_load_avg(cfs_rq, se);
|
|
|
|
+ update_cfs_shares(se);
|
|
account_entity_enqueue(cfs_rq, se);
|
|
account_entity_enqueue(cfs_rq, se);
|
|
- update_cfs_shares(cfs_rq);
|
|
|
|
|
|
|
|
if (flags & ENQUEUE_WAKEUP)
|
|
if (flags & ENQUEUE_WAKEUP)
|
|
place_entity(cfs_rq, se, 0);
|
|
place_entity(cfs_rq, se, 0);
|
|
@@ -3657,6 +3670,15 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
|
|
* Update run-time statistics of the 'current'.
|
|
* Update run-time statistics of the 'current'.
|
|
*/
|
|
*/
|
|
update_curr(cfs_rq);
|
|
update_curr(cfs_rq);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * When dequeuing a sched_entity, we must:
|
|
|
|
+ * - Update loads to have both entity and cfs_rq synced with now.
|
|
|
|
+ * - Substract its load from the cfs_rq->runnable_avg.
|
|
|
|
+ * - Substract its previous weight from cfs_rq->load.weight.
|
|
|
|
+ * - For group entity, update its weight to reflect the new share
|
|
|
|
+ * of its group cfs_rq.
|
|
|
|
+ */
|
|
update_load_avg(se, UPDATE_TG);
|
|
update_load_avg(se, UPDATE_TG);
|
|
dequeue_entity_load_avg(cfs_rq, se);
|
|
dequeue_entity_load_avg(cfs_rq, se);
|
|
|
|
|
|
@@ -3681,7 +3703,7 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
|
|
/* return excess runtime on last dequeue */
|
|
/* return excess runtime on last dequeue */
|
|
return_cfs_rq_runtime(cfs_rq);
|
|
return_cfs_rq_runtime(cfs_rq);
|
|
|
|
|
|
- update_cfs_shares(cfs_rq);
|
|
|
|
|
|
+ update_cfs_shares(se);
|
|
|
|
|
|
/*
|
|
/*
|
|
* Now advance min_vruntime if @se was the entity holding it back,
|
|
* Now advance min_vruntime if @se was the entity holding it back,
|
|
@@ -3864,7 +3886,7 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued)
|
|
* Ensure that runnable average is periodically updated.
|
|
* Ensure that runnable average is periodically updated.
|
|
*/
|
|
*/
|
|
update_load_avg(curr, UPDATE_TG);
|
|
update_load_avg(curr, UPDATE_TG);
|
|
- update_cfs_shares(cfs_rq);
|
|
|
|
|
|
+ update_cfs_shares(curr);
|
|
|
|
|
|
#ifdef CONFIG_SCHED_HRTICK
|
|
#ifdef CONFIG_SCHED_HRTICK
|
|
/*
|
|
/*
|
|
@@ -4761,7 +4783,7 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
|
|
break;
|
|
break;
|
|
|
|
|
|
update_load_avg(se, UPDATE_TG);
|
|
update_load_avg(se, UPDATE_TG);
|
|
- update_cfs_shares(cfs_rq);
|
|
|
|
|
|
+ update_cfs_shares(se);
|
|
}
|
|
}
|
|
|
|
|
|
if (!se)
|
|
if (!se)
|
|
@@ -4820,7 +4842,7 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags)
|
|
break;
|
|
break;
|
|
|
|
|
|
update_load_avg(se, UPDATE_TG);
|
|
update_load_avg(se, UPDATE_TG);
|
|
- update_cfs_shares(cfs_rq);
|
|
|
|
|
|
+ update_cfs_shares(se);
|
|
}
|
|
}
|
|
|
|
|
|
if (!se)
|
|
if (!se)
|
|
@@ -9362,8 +9384,10 @@ int sched_group_set_shares(struct task_group *tg, unsigned long shares)
|
|
|
|
|
|
/* Possible calls to update_curr() need rq clock */
|
|
/* Possible calls to update_curr() need rq clock */
|
|
update_rq_clock(rq);
|
|
update_rq_clock(rq);
|
|
- for_each_sched_entity(se)
|
|
|
|
- update_cfs_shares(group_cfs_rq(se));
|
|
|
|
|
|
+ for_each_sched_entity(se) {
|
|
|
|
+ update_load_avg(se, UPDATE_TG);
|
|
|
|
+ update_cfs_shares(se);
|
|
|
|
+ }
|
|
raw_spin_unlock_irqrestore(&rq->lock, flags);
|
|
raw_spin_unlock_irqrestore(&rq->lock, flags);
|
|
}
|
|
}
|
|
|
|
|