]> err.no Git - linux-2.6/commitdiff
[S390] smp: Fix locking order.
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Wed, 30 Apr 2008 11:38:36 +0000 (13:38 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 30 Apr 2008 11:38:44 +0000 (13:38 +0200)
On some smp sysfs store attributes get_online_cpus() may block on
cpu_hotplug.lock, but we hold already smp_cpu_state_mutex. Since the
locking order on cpu hotplug via arch_update_cpu_topology is inverse
this might lead to deadlocks.
So make sure locking order is always the same.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/kernel/smp.c

index 0dfa988c1b26d74abae8411d92afb0f709d8fc2a..6bb5c050640ff615da18b869748b63518d9bcc09 100644 (file)
@@ -890,8 +890,8 @@ static ssize_t cpu_configure_store(struct sys_device *dev, const char *buf,
        if (val != 0 && val != 1)
                return -EINVAL;
 
-       mutex_lock(&smp_cpu_state_mutex);
        get_online_cpus();
+       mutex_lock(&smp_cpu_state_mutex);
        rc = -EBUSY;
        if (cpu_online(cpu))
                goto out;
@@ -919,8 +919,8 @@ static ssize_t cpu_configure_store(struct sys_device *dev, const char *buf,
                break;
        }
 out:
-       put_online_cpus();
        mutex_unlock(&smp_cpu_state_mutex);
+       put_online_cpus();
        return rc ? rc : count;
 }
 static SYSDEV_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store);
@@ -1095,8 +1095,8 @@ static ssize_t __ref rescan_store(struct sys_device *dev,
        int cpu;
        int rc;
 
-       mutex_lock(&smp_cpu_state_mutex);
        get_online_cpus();
+       mutex_lock(&smp_cpu_state_mutex);
        newcpus = cpu_present_map;
        rc = smp_rescan_cpus();
        if (rc)
@@ -1109,8 +1109,8 @@ static ssize_t __ref rescan_store(struct sys_device *dev,
        }
        rc = 0;
 out:
-       put_online_cpus();
        mutex_unlock(&smp_cpu_state_mutex);
+       put_online_cpus();
        if (!cpus_empty(newcpus))
                topology_schedule_update();
        return rc ? rc : count;
@@ -1139,16 +1139,16 @@ static ssize_t dispatching_store(struct sys_device *dev, const char *buf,
        if (val != 0 && val != 1)
                return -EINVAL;
        rc = 0;
-       mutex_lock(&smp_cpu_state_mutex);
        get_online_cpus();
+       mutex_lock(&smp_cpu_state_mutex);
        if (cpu_management == val)
                goto out;
        rc = topology_set_cpu_management(val);
        if (!rc)
                cpu_management = val;
 out:
-       put_online_cpus();
        mutex_unlock(&smp_cpu_state_mutex);
+       put_online_cpus();
        return rc ? rc : count;
 }
 static SYSDEV_ATTR(dispatching, 0644, dispatching_show, dispatching_store);