Commit 31989cba authored by Ingo Molnar's avatar Ingo Molnar Committed by Anton Blanchard

[PATCH] sched-2.5.41-A0

This fixes the scheduler's migration code to not disable preemption.  It
also fixes the bug that was hidden by the broken disable-preempt change:
the migration thread did not kick idle CPUs if a task is migrated to
them, which causes a hung boot when ksoftirqds are started.  It was pure
luck it worked until now, it was broken pretty much from day 1 on.
parent c0c7e476
...@@ -1953,7 +1953,6 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask) ...@@ -1953,7 +1953,6 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask)
BUG(); BUG();
#endif #endif
preempt_disable();
rq = task_rq_lock(p, &flags); rq = task_rq_lock(p, &flags);
p->cpus_allowed = new_mask; p->cpus_allowed = new_mask;
/* /*
...@@ -1962,7 +1961,7 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask) ...@@ -1962,7 +1961,7 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask)
*/ */
if (new_mask & (1UL << task_cpu(p))) { if (new_mask & (1UL << task_cpu(p))) {
task_rq_unlock(rq, &flags); task_rq_unlock(rq, &flags);
goto out; return;
} }
/* /*
* If the task is not on a runqueue (and not running), then * If the task is not on a runqueue (and not running), then
...@@ -1971,17 +1970,16 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask) ...@@ -1971,17 +1970,16 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask)
if (!p->array && !task_running(rq, p)) { if (!p->array && !task_running(rq, p)) {
set_task_cpu(p, __ffs(p->cpus_allowed)); set_task_cpu(p, __ffs(p->cpus_allowed));
task_rq_unlock(rq, &flags); task_rq_unlock(rq, &flags);
goto out; return;
} }
init_completion(&req.done); init_completion(&req.done);
req.task = p; req.task = p;
list_add(&req.list, &rq->migration_queue); list_add(&req.list, &rq->migration_queue);
task_rq_unlock(rq, &flags); task_rq_unlock(rq, &flags);
wake_up_process(rq->migration_thread); wake_up_process(rq->migration_thread);
wait_for_completion(&req.done); wait_for_completion(&req.done);
out:
preempt_enable();
} }
/* /*
...@@ -1999,16 +1997,12 @@ static int migration_thread(void * data) ...@@ -1999,16 +1997,12 @@ static int migration_thread(void * data)
sigfillset(&current->blocked); sigfillset(&current->blocked);
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
set_cpus_allowed(current, 1UL << cpu);
/* /*
* Migration can happen without a migration thread on the * Either we are running on the right CPU, or there's a
* target CPU because here we remove the thread from the * a migration thread on the target CPU, guaranteed.
* runqueue and the helper thread then moves this thread
* to the target CPU - we'll wake up there.
*/ */
if (smp_processor_id() != cpu) set_cpus_allowed(current, 1UL << cpu);
printk("migration_task %d on cpu=%d\n", cpu, smp_processor_id());
ret = setscheduler(0, SCHED_FIFO, &param); ret = setscheduler(0, SCHED_FIFO, &param);
rq = this_rq(); rq = this_rq();
...@@ -2055,6 +2049,8 @@ static int migration_thread(void * data) ...@@ -2055,6 +2049,8 @@ static int migration_thread(void * data)
if (p->array) { if (p->array) {
deactivate_task(p, rq_src); deactivate_task(p, rq_src);
activate_task(p, rq_dest); activate_task(p, rq_dest);
if (p->prio < rq_dest->curr->prio)
resched_task(rq_dest->curr);
} }
} }
double_rq_unlock(rq_src, rq_dest); double_rq_unlock(rq_src, rq_dest);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment