linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Byungchul Park <byungchul.park@lge.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Yuyang Du <yuyang.du@intel.com>,
	mingo@kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] sched: sync with the cfs_rq when changing sched class
Date: Sat, 15 Aug 2015 15:52:48 +0900	[thread overview]
Message-ID: <20150815065248.GA16992@byungchulpark-X58A-UD3R> (raw)
In-Reply-To: <20150813152212.GE16853@twins.programming.kicks-ass.net>

On Thu, Aug 13, 2015 at 05:22:12PM +0200, Peter Zijlstra wrote:
> On Thu, Aug 13, 2015 at 10:15:28AM +0800, Yuyang Du wrote:
> > On Thu, Aug 13, 2015 at 05:21:27PM +0900, Byungchul Park wrote:
> > > 
> > > yuyang said that switched_to don't need to consider task's load because it
> > > can have meaningless value. but i think considering task's load is better
> > > than leaving it unattended at all. and we can also use switched_to if we 
> > > consider task's load in switched_to.
> > 
> > when did I say "don't need to consider..."?
> > 
> > Doing more does not mean better, or just trivial. BTW, the task switched_to
> > does not have to be switched_from before. 
> 
> Correct, there's a few corner cases we need to consider.
> 
> However, I think we unconditionally call init_entity_runnable_average()
> on all tasks, regardless of their 'initial' sched class, so it should
> have a valid state.
> 
> Another thing to consider is the state being very stale, suppose it
> started live as FAIR, ran for a bit, got switched to !FAIR by means of
> sys_sched_setscheduler()/sys_sched_setattr() or similar, runs for a long
> time and for some reason gets switched back to FAIR, we need to age and
> or re-init things.

hello,

what do you think about this approch for solving this problem ?
it makes se's loads decay for detached periods for that rq. and i used
rq instead of cfs_rq because it does not have dependency to cfs_rq
any more.

---

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 5b50082..8f5e2de 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1191,6 +1191,8 @@ struct load_weight {
  */
 struct sched_avg {
 	u64 last_update_time, load_sum;
+	u64 last_detached_time;
+	int last_detached_cpu;
 	u32 util_sum, period_contrib;
 	unsigned long load_avg, util_avg;
 };
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 72d13af..b2d22c8 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -673,6 +673,8 @@ void init_entity_runnable_average(struct sched_entity *se)
 	struct sched_avg *sa = &se->avg;
 
 	sa->last_update_time = 0;
+	sa->last_detached_time = 0;
+	sa->last_detached_cpu = -1;
 	/*
 	 * sched_avg's period_contrib should be strictly less then 1024, so
 	 * we give it 1023 to make sure it is almost a period (1024us), and
@@ -2711,16 +2713,47 @@ 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)
 {
-	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;
+	struct sched_avg *sa = &se->avg;
+	int cpu = sa->last_detached_cpu;
+	u64 delta;
+
+	if (cpu != -1) {
+		delta = rq_clock_task(cpu_rq(cpu)) - sa->last_detached_time;
+		/*
+		 * compute the number of period passed, where a period is 1 msec,
+		 * since the entity had detached from the rq, and ignore decaying
+		 * delta which is less than a period for fast calculation.
+		 */
+		delta >>= 20;
+		if (!delta)
+			goto do_attach;
+
+		sa->load_sum = decay_load(sa->load_sum, delta);
+		sa->util_sum = decay_load((u64)(sa->util_sum), delta);
+		sa->load_avg = div_u64(sa->load_sum, LOAD_AVG_MAX);
+		sa->util_avg = (sa->util_sum << SCHED_LOAD_SHIFT) / LOAD_AVG_MAX;
+	}
+
+do_attach:
+	sa->last_detached_cpu = -1;
+	sa->last_detached_time = 0;
+	sa->period_contrib = 0;
+
+	sa->last_update_time = cfs_rq->avg.last_update_time;
+	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;
 }
 
 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)),
+	int cpu = cpu_of(rq_of(cfs_rq));
+
+	se->avg.last_detached_cpu = cpu;
+	se->avg.last_detached_time = rq_clock_task(rq_of(cfs_rq));
+
+	__update_load_avg(cfs_rq->avg.last_update_time, cpu,
 			&se->avg, se->on_rq * scale_load_down(se->load.weight),
 			cfs_rq->curr == se, NULL);

> 
> I _think_ we can use last_update_time for that, but I've not looked too
> hard.
> 
> That is, age based on last_update_time, if all 0, reinit, or somesuch.
> 
> 
> The most common case of switched_from()/switched_to() is Priority
> Inheritance, and that typically results in very short lived stints as
> !FAIR and the avg data should be still accurate by the time we return.
> --
> 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/

  parent reply	other threads:[~2015-08-15  6:53 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-13  5:55 [PATCH] sched: sync with the cfs_rq when changing sched class byungchul.park
2015-08-12 22:41 ` Yuyang Du
2015-08-13  7:19   ` Byungchul Park
2015-08-13  2:30     ` Yuyang Du
2015-08-13  7:46 ` Peter Zijlstra
2015-08-13  8:21   ` Byungchul Park
2015-08-13  2:15     ` Yuyang Du
2015-08-13 10:56       ` Byungchul Park
2015-08-13 15:22       ` Peter Zijlstra
2015-08-13 23:20         ` Yuyang Du
2015-08-14  8:46           ` Peter Zijlstra
2015-08-15  6:52         ` Byungchul Park [this message]
2015-08-15  7:16           ` Byungchul Park
2015-08-13  8:42   ` Byungchul Park
2015-08-14 12:59 ` T. Zhou
2015-08-15  4:24   ` Byungchul Park
2015-08-15 12:34     ` T. Zhou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150815065248.GA16992@byungchulpark-X58A-UD3R \
    --to=byungchul.park@lge.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=yuyang.du@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).