Re: [PATCH 37/50] sched: Introduce migrate_swap()

From: Peter Zijlstra
Date: Tue Sep 17 2013 - 10:32:51 EST


On Tue, Sep 10, 2013 at 10:32:17AM +0100, Mel Gorman wrote:
> TODO: I'm fairly sure we can get rid of the wake_cpu != -1 test by keeping
> wake_cpu to the actual task cpu; just couldn't be bothered to think through
> all the cases.

> + * XXX worry about hotplug

Combined with the {get,put}_online_cpus() optimization patch, the below
should address the two outstanding issues.

Completely untested for now.. will try and get it some runtime later.

Not-yet-signed-off-by: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
---
kernel/sched/core.c | 37 ++++++++++++++++++++-----------------
kernel/sched/sched.h | 1 +
2 files changed, 21 insertions(+), 17 deletions(-)

--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1035,7 +1035,7 @@ static void __migrate_swap_task(struct t
/*
* Task isn't running anymore; make it appear like we migrated
* it before it went to sleep. This means on wakeup we make the
- * previous cpu or targer instead of where it really is.
+ * previous cpu our target instead of where it really is.
*/
p->wake_cpu = cpu;
}
@@ -1080,11 +1080,16 @@ static int migrate_swap_stop(void *data)
}

/*
- * XXX worry about hotplug
+ * Cross migrate two tasks
*/
int migrate_swap(struct task_struct *cur, struct task_struct *p)
{
- struct migration_swap_arg arg = {
+ struct migration_swap_arg arg;
+ int ret = -EINVAL;
+
+ get_online_cpus();
+
+ arg = (struct migration_swap_arg){
.src_task = cur,
.src_cpu = task_cpu(cur),
.dst_task = p,
@@ -1092,15 +1097,22 @@ int migrate_swap(struct task_struct *cur
};

if (arg.src_cpu == arg.dst_cpu)
- return -EINVAL;
+ goto out;
+
+ if (!cpu_active(arg.src_cpu) || !cpu_active(arg.dst_cpu))
+ goto out;

if (!cpumask_test_cpu(arg.dst_cpu, tsk_cpus_allowed(arg.src_task)))
- return -EINVAL;
+ goto out;

if (!cpumask_test_cpu(arg.src_cpu, tsk_cpus_allowed(arg.dst_task)))
- return -EINVAL;
+ goto out;
+
+ ret = stop_two_cpus(arg.dst_cpu, arg.src_cpu, migrate_swap_stop, &arg);

- return stop_two_cpus(arg.dst_cpu, arg.src_cpu, migrate_swap_stop, &arg);
+out:
+ put_online_cpus();
+ return ret;
}

struct migration_arg {
@@ -1608,12 +1620,7 @@ try_to_wake_up(struct task_struct *p, un
if (p->sched_class->task_waking)
p->sched_class->task_waking(p);

- if (p->wake_cpu != -1) { /* XXX make this condition go away */
- cpu = p->wake_cpu;
- p->wake_cpu = -1;
- }
-
- cpu = select_task_rq(p, cpu, SD_BALANCE_WAKE, wake_flags);
+ cpu = select_task_rq(p, p->wake_cpu, SD_BALANCE_WAKE, wake_flags);
if (task_cpu(p) != cpu) {
wake_flags |= WF_MIGRATED;
set_task_cpu(p, cpu);
@@ -1699,10 +1706,6 @@ static void __sched_fork(struct task_str
{
p->on_rq = 0;

-#ifdef CONFIG_SMP
- p->wake_cpu = -1;
-#endif
-
p->se.on_rq = 0;
p->se.exec_start = 0;
p->se.sum_exec_runtime = 0;
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -737,6 +737,7 @@ static inline void __set_task_cpu(struct
*/
smp_wmb();
task_thread_info(p)->cpu = cpu;
+ p->wake_cpu = cpu;
#endif
}

--
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/