]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] set_cpus_allowed fix
authorRobert Love <rml@tech9.net>
Sat, 8 Jun 2002 09:26:14 +0000 (02:26 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sat, 8 Jun 2002 09:26:14 +0000 (02:26 -0700)
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.

kernel/sched.c

index b3a7de65707214723054bc6ddfbe88d93cab78bb..deff2d62ac05ec8a4281c34cbdc720e7cd7d77c4 100644 (file)
@@ -782,7 +782,7 @@ need_resched:
         */
        if (unlikely(preempt_get_count() & PREEMPT_ACTIVE))
                goto pick_next_task;
-       
+
        switch (prev->state) {
        case TASK_INTERRUPTIBLE:
                if (unlikely(signal_pending(prev))) {
@@ -1144,7 +1144,7 @@ static int setscheduler(pid_t pid, int policy, struct sched_param *param)
                                policy != SCHED_OTHER)
                        goto out_unlock;
        }
-       
+
        /*
         * Valid priorities for SCHED_FIFO and SCHED_RR are
         * 1..MAX_USER_RT_PRIO, valid priority for SCHED_OTHER is 0.
@@ -1377,6 +1377,7 @@ asmlinkage long sys_sched_yield(void)
 
        return 0;
 }
+
 asmlinkage long sys_sched_get_priority_max(int policy)
 {
        int ret = -EINVAL;
@@ -1687,16 +1688,6 @@ void set_cpus_allowed(task_t *p, unsigned long new_mask)
                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);
        req.task = p;
        list_add(&req.list, &rq->migration_queue);