Commit 9cc083a6 authored by Robert Love's avatar Robert Love Committed by Linus Torvalds

[PATCH] set_cpus_allowed fix

Mike Kravetz pointed out that the set_cpus_allowed optimization he
suggested has a small but possible race condition wherein the system
could still be operating in the context of the task but it is not
running.  On top of this, the runqueue lock can be dropped in
load_balance and thus we can race and set task->cpu at a very unpleasant
time.

My solution is to just remove the optimization.
parent 7771a043
...@@ -782,7 +782,7 @@ asmlinkage void schedule(void) ...@@ -782,7 +782,7 @@ asmlinkage void schedule(void)
*/ */
if (unlikely(preempt_get_count() & PREEMPT_ACTIVE)) if (unlikely(preempt_get_count() & PREEMPT_ACTIVE))
goto pick_next_task; goto pick_next_task;
switch (prev->state) { switch (prev->state) {
case TASK_INTERRUPTIBLE: case TASK_INTERRUPTIBLE:
if (unlikely(signal_pending(prev))) { if (unlikely(signal_pending(prev))) {
...@@ -1144,7 +1144,7 @@ static int setscheduler(pid_t pid, int policy, struct sched_param *param) ...@@ -1144,7 +1144,7 @@ static int setscheduler(pid_t pid, int policy, struct sched_param *param)
policy != SCHED_OTHER) policy != SCHED_OTHER)
goto out_unlock; goto out_unlock;
} }
/* /*
* Valid priorities for SCHED_FIFO and SCHED_RR are * Valid priorities for SCHED_FIFO and SCHED_RR are
* 1..MAX_USER_RT_PRIO, valid priority for SCHED_OTHER is 0. * 1..MAX_USER_RT_PRIO, valid priority for SCHED_OTHER is 0.
...@@ -1377,6 +1377,7 @@ asmlinkage long sys_sched_yield(void) ...@@ -1377,6 +1377,7 @@ asmlinkage long sys_sched_yield(void)
return 0; return 0;
} }
asmlinkage long sys_sched_get_priority_max(int policy) asmlinkage long sys_sched_get_priority_max(int policy)
{ {
int ret = -EINVAL; int ret = -EINVAL;
...@@ -1687,16 +1688,6 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask) ...@@ -1687,16 +1688,6 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask)
goto out; goto out;
} }
/*
* If the task is not on a runqueue, then it is sufficient
* to simply update the task's cpu field.
*/
if (!p->array) {
p->thread_info->cpu = __ffs(p->cpus_allowed);
task_rq_unlock(rq, &flags);
goto out;
}
init_MUTEX_LOCKED(&req.sem); init_MUTEX_LOCKED(&req.sem);
req.task = p; req.task = p;
list_add(&req.list, &rq->migration_queue); list_add(&req.list, &rq->migration_queue);
......
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