Commit e1efc1f3 authored by Robert Love's avatar Robert Love Committed by Linus Torvalds

[PATCH] migration_thread preempt fix

This fixes a race in migration_thread which results in a deadlock on
boot for some SMP systems.  The fix is to to disable preemption inside
of set_cpus_allowed.

Andrew Morton first noticed the problem and provided the following patch
a few weeks back.  I was not affected until the recent migration_init
fix, for some odd reason.  Neither Andrew nor I think this is actually
kernel preemption's fault but perhaps a race in the tricky behavior of
the migration code.
parent 57df9900
...@@ -1649,6 +1649,7 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask) ...@@ -1649,6 +1649,7 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask)
if (!new_mask) if (!new_mask)
BUG(); BUG();
preempt_disable();
rq = task_rq_lock(p, &flags); rq = task_rq_lock(p, &flags);
p->cpus_allowed = new_mask; p->cpus_allowed = new_mask;
/* /*
...@@ -1657,7 +1658,7 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask) ...@@ -1657,7 +1658,7 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask)
*/ */
if (new_mask & (1UL << p->thread_info->cpu)) { if (new_mask & (1UL << p->thread_info->cpu)) {
task_rq_unlock(rq, &flags); task_rq_unlock(rq, &flags);
return; goto out;
} }
init_MUTEX_LOCKED(&req.sem); init_MUTEX_LOCKED(&req.sem);
...@@ -1667,6 +1668,8 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask) ...@@ -1667,6 +1668,8 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask)
wake_up_process(rq->migration_thread); wake_up_process(rq->migration_thread);
down(&req.sem); down(&req.sem);
out:
preempt_enable();
} }
static volatile unsigned long migration_mask; static volatile unsigned long migration_mask;
......
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