diff options
author | Peter Zijlstra <peterz@infradead.org> | 2016-06-21 08:27:50 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-06-27 06:17:54 -0400 |
commit | 3d30544f02120b884bba2a9466c87dba980e3be5 (patch) | |
tree | 86667a44a8bb7af2365e5bd501fc9b37008b8c24 /kernel/sched/fair.c | |
parent | 7dc603c9028ea5d4354e0e317e8481df99b06d7e (diff) |
sched/fair: Apply more PELT fixes
One additional 'rule' for using update_cfs_rq_load_avg() is that one
should call update_tg_load_avg() if it returns true.
Add a bunch of comments to hopefully clarify some of the rules:
o You need to update cfs_rq _before_ any entity attach/detach,
this is important, because while for mathmatical consisency this
isn't strictly needed, it is required for the physical
interpretation of the model, you attach/detach _now_.
o When you modify the cfs_rq avg, you have to then call
update_tg_load_avg() in order to propagate changes upwards.
o (Fair) entities are always attached, switched_{to,from}_fair()
deal with !fair. This directly follows from the definition of the
cfs_rq averages, namely that they are a direct sum of all
(runnable or blocked) entities on that rq.
It is the second rule that this patch enforces, but it adds comments
pertaining to all of them.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/sched/fair.c')
-rw-r--r-- | kernel/sched/fair.c | 53 |
1 files changed, 49 insertions, 4 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 0c21a12c0205..781788d54736 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -692,6 +692,7 @@ void init_entity_runnable_average(struct sched_entity *se) | |||
692 | 692 | ||
693 | static inline u64 cfs_rq_clock_task(struct cfs_rq *cfs_rq); | 693 | static inline u64 cfs_rq_clock_task(struct cfs_rq *cfs_rq); |
694 | static int update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq, bool update_freq); | 694 | static int update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq, bool update_freq); |
695 | static void update_tg_load_avg(struct cfs_rq *cfs_rq, int force); | ||
695 | static void attach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se); | 696 | static void attach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se); |
696 | 697 | ||
697 | /* | 698 | /* |
@@ -725,6 +726,7 @@ void post_init_entity_util_avg(struct sched_entity *se) | |||
725 | struct sched_avg *sa = &se->avg; | 726 | struct sched_avg *sa = &se->avg; |
726 | long cap = (long)(SCHED_CAPACITY_SCALE - cfs_rq->avg.util_avg) / 2; | 727 | long cap = (long)(SCHED_CAPACITY_SCALE - cfs_rq->avg.util_avg) / 2; |
727 | u64 now = cfs_rq_clock_task(cfs_rq); | 728 | u64 now = cfs_rq_clock_task(cfs_rq); |
729 | int tg_update; | ||
728 | 730 | ||
729 | if (cap > 0) { | 731 | if (cap > 0) { |
730 | if (cfs_rq->avg.util_avg != 0) { | 732 | if (cfs_rq->avg.util_avg != 0) { |
@@ -757,8 +759,10 @@ void post_init_entity_util_avg(struct sched_entity *se) | |||
757 | } | 759 | } |
758 | } | 760 | } |
759 | 761 | ||
760 | update_cfs_rq_load_avg(now, cfs_rq, false); | 762 | tg_update = update_cfs_rq_load_avg(now, cfs_rq, false); |
761 | attach_entity_load_avg(cfs_rq, se); | 763 | attach_entity_load_avg(cfs_rq, se); |
764 | if (tg_update) | ||
765 | update_tg_load_avg(cfs_rq, false); | ||
762 | } | 766 | } |
763 | 767 | ||
764 | #else /* !CONFIG_SMP */ | 768 | #else /* !CONFIG_SMP */ |
@@ -768,6 +772,9 @@ void init_entity_runnable_average(struct sched_entity *se) | |||
768 | void post_init_entity_util_avg(struct sched_entity *se) | 772 | void post_init_entity_util_avg(struct sched_entity *se) |
769 | { | 773 | { |
770 | } | 774 | } |
775 | static void update_tg_load_avg(struct cfs_rq *cfs_rq, int force) | ||
776 | { | ||
777 | } | ||
771 | #endif /* CONFIG_SMP */ | 778 | #endif /* CONFIG_SMP */ |
772 | 779 | ||
773 | /* | 780 | /* |
@@ -2912,7 +2919,23 @@ static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq) | |||
2912 | WRITE_ONCE(*ptr, res); \ | 2919 | WRITE_ONCE(*ptr, res); \ |
2913 | } while (0) | 2920 | } while (0) |
2914 | 2921 | ||
2915 | /* Group cfs_rq's load_avg is used for task_h_load and update_cfs_share */ | 2922 | /** |
2923 | * update_cfs_rq_load_avg - update the cfs_rq's load/util averages | ||
2924 | * @now: current time, as per cfs_rq_clock_task() | ||
2925 | * @cfs_rq: cfs_rq to update | ||
2926 | * @update_freq: should we call cfs_rq_util_change() or will the call do so | ||
2927 | * | ||
2928 | * The cfs_rq avg is the direct sum of all its entities (blocked and runnable) | ||
2929 | * avg. The immediate corollary is that all (fair) tasks must be attached, see | ||
2930 | * post_init_entity_util_avg(). | ||
2931 | * | ||
2932 | * cfs_rq->avg is used for task_h_load() and update_cfs_share() for example. | ||
2933 | * | ||
2934 | * Returns true if the load decayed or we removed utilization. It is expected | ||
2935 | * that one calls update_tg_load_avg() on this condition, but after you've | ||
2936 | * modified the cfs_rq avg (attach/detach), such that we propagate the new | ||
2937 | * avg up. | ||
2938 | */ | ||
2916 | static inline int | 2939 | static inline int |
2917 | update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq, bool update_freq) | 2940 | update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq, bool update_freq) |
2918 | { | 2941 | { |
@@ -2967,6 +2990,14 @@ static inline void update_load_avg(struct sched_entity *se, int update_tg) | |||
2967 | update_tg_load_avg(cfs_rq, 0); | 2990 | update_tg_load_avg(cfs_rq, 0); |
2968 | } | 2991 | } |
2969 | 2992 | ||
2993 | /** | ||
2994 | * attach_entity_load_avg - attach this entity to its cfs_rq load avg | ||
2995 | * @cfs_rq: cfs_rq to attach to | ||
2996 | * @se: sched_entity to attach | ||
2997 | * | ||
2998 | * Must call update_cfs_rq_load_avg() before this, since we rely on | ||
2999 | * cfs_rq->avg.last_update_time being current. | ||
3000 | */ | ||
2970 | static void attach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) | 3001 | static void attach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) |
2971 | { | 3002 | { |
2972 | if (!sched_feat(ATTACH_AGE_LOAD)) | 3003 | if (!sched_feat(ATTACH_AGE_LOAD)) |
@@ -2998,6 +3029,14 @@ skip_aging: | |||
2998 | cfs_rq_util_change(cfs_rq); | 3029 | cfs_rq_util_change(cfs_rq); |
2999 | } | 3030 | } |
3000 | 3031 | ||
3032 | /** | ||
3033 | * detach_entity_load_avg - detach this entity from its cfs_rq load avg | ||
3034 | * @cfs_rq: cfs_rq to detach from | ||
3035 | * @se: sched_entity to detach | ||
3036 | * | ||
3037 | * Must call update_cfs_rq_load_avg() before this, since we rely on | ||
3038 | * cfs_rq->avg.last_update_time being current. | ||
3039 | */ | ||
3001 | static void detach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) | 3040 | static void detach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) |
3002 | { | 3041 | { |
3003 | __update_load_avg(cfs_rq->avg.last_update_time, cpu_of(rq_of(cfs_rq)), | 3042 | __update_load_avg(cfs_rq->avg.last_update_time, cpu_of(rq_of(cfs_rq)), |
@@ -8404,6 +8443,7 @@ static void detach_task_cfs_rq(struct task_struct *p) | |||
8404 | struct sched_entity *se = &p->se; | 8443 | struct sched_entity *se = &p->se; |
8405 | struct cfs_rq *cfs_rq = cfs_rq_of(se); | 8444 | struct cfs_rq *cfs_rq = cfs_rq_of(se); |
8406 | u64 now = cfs_rq_clock_task(cfs_rq); | 8445 | u64 now = cfs_rq_clock_task(cfs_rq); |
8446 | int tg_update; | ||
8407 | 8447 | ||
8408 | if (!vruntime_normalized(p)) { | 8448 | if (!vruntime_normalized(p)) { |
8409 | /* | 8449 | /* |
@@ -8415,8 +8455,10 @@ static void detach_task_cfs_rq(struct task_struct *p) | |||
8415 | } | 8455 | } |
8416 | 8456 | ||
8417 | /* Catch up with the cfs_rq and remove our load when we leave */ | 8457 | /* Catch up with the cfs_rq and remove our load when we leave */ |
8418 | update_cfs_rq_load_avg(now, cfs_rq, false); | 8458 | tg_update = update_cfs_rq_load_avg(now, cfs_rq, false); |
8419 | detach_entity_load_avg(cfs_rq, se); | 8459 | detach_entity_load_avg(cfs_rq, se); |
8460 | if (tg_update) | ||
8461 | update_tg_load_avg(cfs_rq, false); | ||
8420 | } | 8462 | } |
8421 | 8463 | ||
8422 | static void attach_task_cfs_rq(struct task_struct *p) | 8464 | static void attach_task_cfs_rq(struct task_struct *p) |
@@ -8424,6 +8466,7 @@ static void attach_task_cfs_rq(struct task_struct *p) | |||
8424 | struct sched_entity *se = &p->se; | 8466 | struct sched_entity *se = &p->se; |
8425 | struct cfs_rq *cfs_rq = cfs_rq_of(se); | 8467 | struct cfs_rq *cfs_rq = cfs_rq_of(se); |
8426 | u64 now = cfs_rq_clock_task(cfs_rq); | 8468 | u64 now = cfs_rq_clock_task(cfs_rq); |
8469 | int tg_update; | ||
8427 | 8470 | ||
8428 | #ifdef CONFIG_FAIR_GROUP_SCHED | 8471 | #ifdef CONFIG_FAIR_GROUP_SCHED |
8429 | /* | 8472 | /* |
@@ -8434,8 +8477,10 @@ static void attach_task_cfs_rq(struct task_struct *p) | |||
8434 | #endif | 8477 | #endif |
8435 | 8478 | ||
8436 | /* Synchronize task with its cfs_rq */ | 8479 | /* Synchronize task with its cfs_rq */ |
8437 | update_cfs_rq_load_avg(now, cfs_rq, false); | 8480 | tg_update = update_cfs_rq_load_avg(now, cfs_rq, false); |
8438 | attach_entity_load_avg(cfs_rq, se); | 8481 | attach_entity_load_avg(cfs_rq, se); |
8482 | if (tg_update) | ||
8483 | update_tg_load_avg(cfs_rq, false); | ||
8439 | 8484 | ||
8440 | if (!vruntime_normalized(p)) | 8485 | if (!vruntime_normalized(p)) |
8441 | se->vruntime += cfs_rq->min_vruntime; | 8486 | se->vruntime += cfs_rq->min_vruntime; |