rpc: call release_pipe only on last close
[safe/jmp/linux-2.6] / kernel / stop_machine.c
index 0e688c6..24e8cea 100644 (file)
@@ -66,6 +66,7 @@ static void stop_cpu(struct work_struct *unused)
        enum stopmachine_state curstate = STOPMACHINE_NONE;
        struct stop_machine_data *smdata = &idle;
        int cpu = smp_processor_id();
+       int err;
 
        if (!active_cpus) {
                if (cpu == first_cpu(cpu_online_map))
@@ -86,9 +87,11 @@ static void stop_cpu(struct work_struct *unused)
                                hard_irq_disable();
                                break;
                        case STOPMACHINE_RUN:
-                               /* |= allows error detection if functions on
-                                * multiple CPUs. */
-                               smdata->fnret |= smdata->fn(smdata->data);
+                               /* On multiple CPUs only a single error code
+                                * is needed to tell that something failed. */
+                               err = smdata->fn(smdata->data);
+                               if (err)
+                                       smdata->fnret = err;
                                break;
                        default:
                                break;
@@ -109,7 +112,7 @@ static int chill(void *unused)
 int __stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus)
 {
        struct work_struct *sm_work;
-       int i;
+       int i, ret;
 
        /* Set up initial state. */
        mutex_lock(&lock);
@@ -134,8 +137,9 @@ int __stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus)
        /* This will release the thread on our CPU. */
        put_cpu();
        flush_workqueue(stop_machine_wq);
+       ret = active.fnret;
        mutex_unlock(&lock);
-       return active.fnret;
+       return ret;
 }
 
 int stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus)
@@ -157,4 +161,4 @@ static int __init stop_machine_init(void)
        stop_machine_work = alloc_percpu(struct work_struct);
        return 0;
 }
-early_initcall(stop_machine_init);
+core_initcall(stop_machine_init);