[PATCH v3 1/3] sched: introduce a new migration flag to task_struct

From: byungchul.park
Date: Thu Oct 15 2015 - 05:03:31 EST


From: Byungchul Park <byungchul.park@xxxxxxx>

This patch removes a weird coupling between se->avg.last_update_time and
the condition checking for migration, and introduce a new migration flag.
Now, scheduler can use the flag instead of se->avg.last_update_time to
check if migration already happened or not.

Signed-off-by: Byungchul Park <byungchul.park@xxxxxxx>
---
include/linux/sched.h | 3 +++
kernel/sched/core.c | 1 +
kernel/sched/fair.c | 22 ++++++++++++----------
kernel/sched/sched.h | 1 +
4 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 699228b..a104c72 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1379,6 +1379,9 @@ struct task_struct {
#endif
int on_rq;

+ /* For indicating if a migration has happened. */
+ int migrated;
+
int prio, static_prio, normal_prio;
unsigned int rt_priority;
const struct sched_class *sched_class;
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index a91df61..57f4300 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2068,6 +2068,7 @@ void __dl_clear_params(struct task_struct *p)
static void __sched_fork(unsigned long clone_flags, struct task_struct *p)
{
p->on_rq = 0;
+ p->migrated = 0;

p->se.on_rq = 0;
p->se.exec_start = 0;
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 077076f..0f76903 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -2771,14 +2771,15 @@ static void detach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *s

/* 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)
+enqueue_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
{
struct sched_avg *sa = &se->avg;
u64 now = cfs_rq_clock_task(cfs_rq);
- int migrated, decayed;
+ int decayed;
+ int migrated = flags & ENQUEUE_MIGRATED;
+ int created = !sa->last_update_time;

- migrated = !sa->last_update_time;
- if (!migrated) {
+ if (!migrated && !created) {
__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);
@@ -2789,10 +2790,10 @@ enqueue_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
cfs_rq->runnable_load_avg += sa->load_avg;
cfs_rq->runnable_load_sum += sa->load_sum;

- if (migrated)
+ if (migrated || created)
attach_entity_load_avg(cfs_rq, se);

- if (decayed || migrated)
+ if (decayed || migrated || created)
update_tg_load_avg(cfs_rq, 0);
}

@@ -2868,7 +2869,7 @@ static int idle_balance(struct rq *this_rq);

static inline void update_load_avg(struct sched_entity *se, int update_tg) {}
static inline void
-enqueue_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) {}
+enqueue_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) {}
static inline void
dequeue_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) {}
static inline void remove_entity_load_avg(struct sched_entity *se) {}
@@ -3008,7 +3009,7 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
* Update run-time statistics of the 'current'.
*/
update_curr(cfs_rq);
- enqueue_entity_load_avg(cfs_rq, se);
+ enqueue_entity_load_avg(cfs_rq, se, flags);
account_entity_enqueue(cfs_rq, se);
update_cfs_shares(cfs_rq);

@@ -4136,6 +4137,7 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
struct cfs_rq *cfs_rq;
struct sched_entity *se = &p->se;

+ flags = flags | (xchg(&p->migrated, 0) ? ENQUEUE_MIGRATED : 0);
for_each_sched_entity(se) {
if (se->on_rq)
break;
@@ -5021,7 +5023,7 @@ static void migrate_task_rq_fair(struct task_struct *p, int next_cpu)
remove_entity_load_avg(&p->se);

/* Tell new CPU we are migrated */
- p->se.avg.last_update_time = 0;
+ p->migrated = 1;

/* We have migrated, no longer consider this task hot */
p->se.exec_start = 0;
@@ -8082,7 +8084,7 @@ static void task_move_group_fair(struct task_struct *p)
set_task_rq(p, task_cpu(p));

#ifdef CONFIG_SMP
- /* Tell se's cfs_rq has been changed -- migrated */
+ /* Tell se's cfs_rq has been changed */
p->se.avg.last_update_time = 0;
#endif
attach_task_cfs_rq(p);
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index af6f252..66d0552 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1158,6 +1158,7 @@ static const u32 prio_to_wmult[40] = {
#define ENQUEUE_WAKING 0
#endif
#define ENQUEUE_REPLENISH 8
+#define ENQUEUE_MIGRATED 16

#define DEQUEUE_SLEEP 1

--
1.7.9.5

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