Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1208440 > unrolled thread

[PATCH v2 0/3] sched: sync a se with its cfs_rq when attaching and dettaching

Started bybyungchul.park@lge.com
First post2015-08-17 09:50 +0200
Last post2015-08-17 11:40 +0200
Articles 6 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 0/3] sched: sync a se with its cfs_rq when attaching and dettaching byungchul.park@lge.com - 2015-08-17 09:50 +0200
    [PATCH v2 3/3] sched: decay a detached se when it's attached to its cfs_rq byungchul.park@lge.com - 2015-08-17 09:50 +0200
    [PATCH v2 1/3] sched: sync a se with its cfs_rq when attaching and dettaching byungchul.park@lge.com - 2015-08-17 09:50 +0200
      Re: [PATCH v2 1/3] sched: sync a se with its cfs_rq when attaching  and dettaching "T. Zhou" <t.s.zhou@hotmail.com> - 2015-08-18 18:40 +0200
        Re: [PATCH v2 1/3] sched: sync a se with its cfs_rq when attaching  and dettaching Byungchul Park <byungchul.park@lge.com> - 2015-08-19 01:50 +0200
    Re: [PATCH v2 0/3] sched: sync a se with its cfs_rq when attaching  and dettaching Byungchul Park <byungchul.park@lge.com> - 2015-08-17 11:40 +0200

#1208440 — [PATCH v2 0/3] sched: sync a se with its cfs_rq when attaching and dettaching

Frombyungchul.park@lge.com
Date2015-08-17 09:50 +0200
Subject[PATCH v2 0/3] sched: sync a se with its cfs_rq when attaching and dettaching
Message-ID<pYnl8-Qf-15@gated-at.bofh.it>
From: Byungchul Park <byungchul.park@lge.com>

change from v1 to v2
* introduce two functions for adjusting vruntime and load when attaching
  and detaching.
* call the introduced functions instead of switched_from(to)_fair() directly
  in task_move_group_fair().
* add decaying logic for a se which has detached from a cfs_rq.

Byungchul Park (3):
  sched: sync a se with its cfs_rq when attaching and dettaching
  sched: introduce functions for attaching(detaching) a task to cfs_rq
  sched: decay a detached se when it's attached to its cfs_rq

 kernel/sched/fair.c |  210 ++++++++++++++++++++++++++-------------------------
 1 file changed, 109 insertions(+), 101 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1208441 — [PATCH v2 3/3] sched: decay a detached se when it's attached to its cfs_rq

Frombyungchul.park@lge.com
Date2015-08-17 09:50 +0200
Subject[PATCH v2 3/3] sched: decay a detached se when it's attached to its cfs_rq
Message-ID<pYnl8-Qf-25@gated-at.bofh.it>
In reply to#1208440
From: Byungchul Park <byungchul.park@lge.com>

se's load can be valuable just after being detached from cfs_rq, however
it will become useless over time, e.g. in case of switching to another
sched class and switching back to fair class.

therefore even in case where se is already detached from cfs, decaying
its load is necessary when it gets attached back to cfs_rq.

Signed-off-by: Byungchul Park <byungchul.park@lge.com>
---
 kernel/sched/fair.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 346f2a6..554c9b7 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -2711,6 +2711,14 @@ static inline void update_load_avg(struct sched_entity *se, int update_tg)
 
 static void attach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
+	/*
+	 * in case of migration and cgroup-change, cfs_rq has been changed.
+	 * therfore, updating load should be already performed before.
+	 */
+	if (se->avg.last_update_time)
+		__update_load_avg(cfs_rq->avg.last_update_time, cpu_of(rq_of(cfs_rq)),
+				&se->avg, 0, 0, NULL);
+
 	se->avg.last_update_time = cfs_rq->avg.last_update_time;
 	cfs_rq->avg.load_avg += se->avg.load_avg;
 	cfs_rq->avg.load_sum += se->avg.load_sum;
@@ -8045,6 +8053,9 @@ static void task_move_group_fair(struct task_struct *p, int queued)
 {
 	detach_task_cfs_rq(p, queued);
 	set_task_rq(p, task_cpu(p));
+
+	/* Tell cfs_rq has been changed */
+	p->se.avg.last_update_time = 0;
 	attach_task_cfs_rq(p, queued);
 }
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1208444 — [PATCH v2 1/3] sched: sync a se with its cfs_rq when attaching and dettaching

Frombyungchul.park@lge.com
Date2015-08-17 09:50 +0200
Subject[PATCH v2 1/3] sched: sync a se with its cfs_rq when attaching and dettaching
Message-ID<pYnl8-Qf-29@gated-at.bofh.it>
In reply to#1208440
From: Byungchul Park <byungchul.park@lge.com>

current code is wrong with cfs_rq's avg loads when changing a task's
cfs_rq to another. i tested with "echo pid > cgroup" and found that
e.g. cfs_rq->avg.load_avg became larger and larger whenever i changed
a cgroup to another again and again. we have to sync se's avg loads
with both *prev* cfs_rq and next cfs_rq when changing its group.

not only for changing cgroup, but also for changing sched class, we
also need to sync a se with its cfs_rq, that is, when leaving from
fair class and returning back to fair class.

in addition, i introduced two functions for attaching/detaching a se
from/to its cfs_rq, and let them use those functions. and i place
that function call to where a se is attached/detached to/from cfs_rq.

Signed-off-by: Byungchul Park <byungchul.park@lge.com>
---
 kernel/sched/fair.c |   82 ++++++++++++++++++++++++++++++---------------------
 1 file changed, 48 insertions(+), 34 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 4d5f97b..fc6b39c 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -2709,6 +2709,31 @@ static inline void update_load_avg(struct sched_entity *se, int update_tg)
 		update_tg_load_avg(cfs_rq, 0);
 }
 
+static void attach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
+{
+	se->avg.last_update_time = cfs_rq->avg.last_update_time;
+	cfs_rq->avg.load_avg += se->avg.load_avg;
+	cfs_rq->avg.load_sum += se->avg.load_sum;
+	cfs_rq->avg.util_avg += se->avg.util_avg;
+	cfs_rq->avg.util_sum += se->avg.util_sum;
+}
+
+static void detach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
+{
+	__update_load_avg(cfs_rq->avg.last_update_time, cpu_of(rq_of(cfs_rq)),
+			&se->avg, se->on_rq * scale_load_down(se->load.weight),
+			cfs_rq->curr == se, NULL);
+
+	cfs_rq->avg.load_avg =
+		max_t(long, cfs_rq->avg.load_avg - se->avg.load_avg, 0);
+	cfs_rq->avg.load_sum =
+		max_t(s64, cfs_rq->avg.load_sum - se->avg.load_sum, 0);
+	cfs_rq->avg.util_avg =
+		max_t(long, cfs_rq->avg.util_avg - se->avg.util_avg, 0);
+	cfs_rq->avg.util_sum =
+		max_t(s32, cfs_rq->avg.util_sum - se->avg.util_sum, 0);
+}
+
 /* Add the load generated by se into cfs_rq's load average */
 static inline void
 enqueue_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
@@ -2717,27 +2742,20 @@ enqueue_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
 	u64 now = cfs_rq_clock_task(cfs_rq);
 	int migrated = 0, decayed;
 
-	if (sa->last_update_time == 0) {
-		sa->last_update_time = now;
+	if (sa->last_update_time == 0)
 		migrated = 1;
-	}
-	else {
+	else
 		__update_load_avg(now, cpu_of(rq_of(cfs_rq)), sa,
-			se->on_rq * scale_load_down(se->load.weight),
-			cfs_rq->curr == se, NULL);
-	}
+				se->on_rq * scale_load_down(se->load.weight),
+				cfs_rq->curr == se, NULL);
 
 	decayed = update_cfs_rq_load_avg(now, cfs_rq);
 
 	cfs_rq->runnable_load_avg += sa->load_avg;
 	cfs_rq->runnable_load_sum += sa->load_sum;
 
-	if (migrated) {
-		cfs_rq->avg.load_avg += sa->load_avg;
-		cfs_rq->avg.load_sum += sa->load_sum;
-		cfs_rq->avg.util_avg += sa->util_avg;
-		cfs_rq->avg.util_sum += sa->util_sum;
-	}
+	if (migrated)
+		attach_entity_load_avg(cfs_rq, se);
 
 	if (decayed || migrated)
 		update_tg_load_avg(cfs_rq, 0);
@@ -7911,17 +7929,7 @@ static void switched_from_fair(struct rq *rq, struct task_struct *p)
 
 #ifdef CONFIG_SMP
 	/* Catch up with the cfs_rq and remove our load when we leave */
-	__update_load_avg(cfs_rq->avg.last_update_time, cpu_of(rq), &se->avg,
-		se->on_rq * scale_load_down(se->load.weight), cfs_rq->curr == se, NULL);
-
-	cfs_rq->avg.load_avg =
-		max_t(long, cfs_rq->avg.load_avg - se->avg.load_avg, 0);
-	cfs_rq->avg.load_sum =
-		max_t(s64, cfs_rq->avg.load_sum - se->avg.load_sum, 0);
-	cfs_rq->avg.util_avg =
-		max_t(long, cfs_rq->avg.util_avg - se->avg.util_avg, 0);
-	cfs_rq->avg.util_sum =
-		max_t(s32, cfs_rq->avg.util_sum - se->avg.util_sum, 0);
+	detach_entity_load_avg(cfs_rq, se);
 #endif
 }
 
@@ -7940,6 +7948,11 @@ static void switched_to_fair(struct rq *rq, struct task_struct *p)
 	se->depth = se->parent ? se->parent->depth + 1 : 0;
 #endif
 
+#ifdef CONFIG_SMP
+	/* synchronize task with its cfs_rq */
+	attach_entity_load_avg(cfs_rq_of(&p->se), &p->se);
+#endif
+
 	if (!task_on_rq_queued(p)) {
 
 		/*
@@ -8032,23 +8045,24 @@ static void task_move_group_fair(struct task_struct *p, int queued)
 	if (!queued && (!se->sum_exec_runtime || p->state == TASK_WAKING))
 		queued = 1;
 
+	cfs_rq = cfs_rq_of(se);
 	if (!queued)
-		se->vruntime -= cfs_rq_of(se)->min_vruntime;
+		se->vruntime -= cfs_rq->min_vruntime;
+
+#ifdef CONFIG_SMP
+	/* synchronize task with its prev cfs_rq */
+	detach_entity_load_avg(cfs_rq, se);
+#endif
 	set_task_rq(p, task_cpu(p));
 	se->depth = se->parent ? se->parent->depth + 1 : 0;
-	if (!queued) {
-		cfs_rq = cfs_rq_of(se);
+	cfs_rq = cfs_rq_of(se);
+	if (!queued)
 		se->vruntime += cfs_rq->min_vruntime;
 
 #ifdef CONFIG_SMP
-		/* Virtually synchronize task with its new cfs_rq */
-		p->se.avg.last_update_time = cfs_rq->avg.last_update_time;
-		cfs_rq->avg.load_avg += p->se.avg.load_avg;
-		cfs_rq->avg.load_sum += p->se.avg.load_sum;
-		cfs_rq->avg.util_avg += p->se.avg.util_avg;
-		cfs_rq->avg.util_sum += p->se.avg.util_sum;
+	/* Virtually synchronize task with its new cfs_rq */
+	attach_entity_load_avg(cfs_rq, se);
 #endif
-	}
 }
 
 void free_fair_sched_group(struct task_group *tg)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1209342 — Re: [PATCH v2 1/3] sched: sync a se with its cfs_rq when attaching and dettaching

From"T. Zhou" <t.s.zhou@hotmail.com>
Date2015-08-18 18:40 +0200
SubjectRe: [PATCH v2 1/3] sched: sync a se with its cfs_rq when attaching and dettaching
Message-ID<pYS5B-3kN-41@gated-at.bofh.it>
In reply to#1208444
Hi,

On Mon, Aug 17, 2015 at 04:45:50PM +0900, byungchul.park@lge.com wrote:
> From: Byungchul Park <byungchul.park@lge.com>
> 
> current code is wrong with cfs_rq's avg loads when changing a task's
> cfs_rq to another. i tested with "echo pid > cgroup" and found that
> e.g. cfs_rq->avg.load_avg became larger and larger whenever i changed
> a cgroup to another again and again. we have to sync se's avg loads
> with both *prev* cfs_rq and next cfs_rq when changing its group.
> 

my simple think about above, may be nothing or wrong, just ignore it.

if a load balance migration happened just before cgroup change, prev
cfs_rq and next cfs_rq will be on different cpu. migrate_task_rq_fair()
and update_cfs_rq_load_avg() will sync and remove se's load avg from
prev cfs_rq. whether or not queued, well done. dequeue_task() decay se
and pre_cfs before calling task_move_group_fair(). after set cfs_rq in
task_move_group_fair(), if queued, se's load avg do not add to next
cfs_rq(try set last_update_time to 0 like migration to add), if !queued,
also need to add se's load avg to next cfs_rq.

if no load balance migration happened when change cgroup. prev cfs_rq
and next cfs_rq may be on same cpu(not sure), this time, need to remove
se's load avg by ourself, also need to add se's load avg on next cfs_rq.

thinks,
-- 
Tao
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1209551 — Re: [PATCH v2 1/3] sched: sync a se with its cfs_rq when attaching and dettaching

FromByungchul Park <byungchul.park@lge.com>
Date2015-08-19 01:50 +0200
SubjectRe: [PATCH v2 1/3] sched: sync a se with its cfs_rq when attaching and dettaching
Message-ID<pYYNJ-5lR-19@gated-at.bofh.it>
In reply to#1209342
On Wed, Aug 19, 2015 at 12:32:43AM +0800, T. Zhou wrote:
> Hi,
> 
> On Mon, Aug 17, 2015 at 04:45:50PM +0900, byungchul.park@lge.com wrote:
> > From: Byungchul Park <byungchul.park@lge.com>
> > 
> > current code is wrong with cfs_rq's avg loads when changing a task's
> > cfs_rq to another. i tested with "echo pid > cgroup" and found that
> > e.g. cfs_rq->avg.load_avg became larger and larger whenever i changed
> > a cgroup to another again and again. we have to sync se's avg loads
> > with both *prev* cfs_rq and next cfs_rq when changing its group.
> > 
> 
> my simple think about above, may be nothing or wrong, just ignore it.
> 
> if a load balance migration happened just before cgroup change, prev
> cfs_rq and next cfs_rq will be on different cpu. migrate_task_rq_fair()

hello,

two oerations, migration and cgroup change, are protected by lock.
therefore it would never happen. :)

thanks,
byungchul

> and update_cfs_rq_load_avg() will sync and remove se's load avg from
> prev cfs_rq. whether or not queued, well done. dequeue_task() decay se
> and pre_cfs before calling task_move_group_fair(). after set cfs_rq in
> task_move_group_fair(), if queued, se's load avg do not add to next
> cfs_rq(try set last_update_time to 0 like migration to add), if !queued,
> also need to add se's load avg to next cfs_rq.
> 
> if no load balance migration happened when change cgroup. prev cfs_rq
> and next cfs_rq may be on same cpu(not sure), this time, need to remove
> se's load avg by ourself, also need to add se's load avg on next cfs_rq.
> 
> thinks,
> -- 
> Tao
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1208500 — Re: [PATCH v2 0/3] sched: sync a se with its cfs_rq when attaching and dettaching

FromByungchul Park <byungchul.park@lge.com>
Date2015-08-17 11:40 +0200
SubjectRe: [PATCH v2 0/3] sched: sync a se with its cfs_rq when attaching and dettaching
Message-ID<pYp3A-3mN-23@gated-at.bofh.it>
In reply to#1208440
On Mon, Aug 17, 2015 at 04:45:49PM +0900, byungchul.park@lge.com wrote:
> From: Byungchul Park <byungchul.park@lge.com>

i am very sorry for ugly versioning..

while i proposed several indivisual patches and was feedbacked, i felt
that i needed to pack some patches into one series.

thanks,
byungchul

> 
> change from v1 to v2
> * introduce two functions for adjusting vruntime and load when attaching
>   and detaching.
> * call the introduced functions instead of switched_from(to)_fair() directly
>   in task_move_group_fair().
> * add decaying logic for a se which has detached from a cfs_rq.
> 
> Byungchul Park (3):
>   sched: sync a se with its cfs_rq when attaching and dettaching
>   sched: introduce functions for attaching(detaching) a task to cfs_rq
>   sched: decay a detached se when it's attached to its cfs_rq
> 
>  kernel/sched/fair.c |  210 ++++++++++++++++++++++++++-------------------------
>  1 file changed, 109 insertions(+), 101 deletions(-)
> 
> -- 
> 1.7.9.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web