Messages in this thread Patch in this message | | | Date | Wed, 20 Feb 2013 13:13:27 +0800 | From | Alex Shi <> | Subject | Re: [patch v4 07/18] sched: set initial load avg of new forked task |
| |
> This is my concern about making this a special case with the > introduction ENQUEUE_NEWTASK flag; enqueue jumps through enough hoops > as it is. > > I still don't see why we can't resolve this at init time in > __sched_fork(); your patch above just moves an explicit initialization > of load_avg_contrib into the enqueue path. Adding a call to > __update_task_entity_contrib() to the previous alternate suggestion > would similarly seem to resolve this? >
Without ENQUEUE_NEWTASK flag, we can use the following patch. That embeds the new fork with a implicate way.
but since the newtask flag just follows existing enqueue path, it also looks natural and is a explicit way.
I am ok for alternate of solutions.
======= From 0f5dd6babe899e27cfb78ea49d337e4f0918591b Mon Sep 17 00:00:00 2001 From: Alex Shi <alex.shi@intel.com> Date: Wed, 20 Feb 2013 12:51:28 +0800 Subject: [PATCH 02/15] sched: set initial load avg of new forked task
New task has no runnable sum at its first runnable time, so its runnable load is zero. That makes burst forking balancing just select few idle cpus to assign tasks if we engage runnable load in balancing.
Set initial load avg of new forked task as its load weight to resolve this issue.
Signed-off-by: Alex Shi <alex.shi@intel.com> --- kernel/sched/core.c | 2 ++ kernel/sched/fair.c | 4 ++++ 2 files changed, 6 insertions(+)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 1743746..93a7590 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1648,6 +1648,8 @@ void sched_fork(struct task_struct *p) p->sched_reset_on_fork = 0; } + p->se.avg.load_avg_contrib = p->se.load.weight; + if (!rt_prio(p->prio)) p->sched_class = &fair_sched_class; diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 81fa536..cae5134 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -1509,6 +1509,10 @@ static inline void enqueue_entity_load_avg(struct cfs_rq *cfs_rq, * We track migrations using entity decay_count <= 0, on a wake-up * migration we use a negative decay count to track the remote decays * accumulated while sleeping. + * + * When enqueue a new forked task, the se->avg.decay_count == 0, so + * we bypass update_entity_load_avg(), use avg.load_avg_contrib initial + * value: se->load.weight. */ if (unlikely(se->avg.decay_count <= 0)) { se->avg.last_runnable_update = rq_of(cfs_rq)->clock_task; -- 1.7.12
| |