Commit 0b18d318 authored by Heiko Carstens's avatar Heiko Carstens Committed by Martin Schwidefsky

[S390] smp: Fix locking order.

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: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent f291e172
...@@ -890,8 +890,8 @@ static ssize_t cpu_configure_store(struct sys_device *dev, const char *buf, ...@@ -890,8 +890,8 @@ static ssize_t cpu_configure_store(struct sys_device *dev, const char *buf,
if (val != 0 && val != 1) if (val != 0 && val != 1)
return -EINVAL; return -EINVAL;
mutex_lock(&smp_cpu_state_mutex);
get_online_cpus(); get_online_cpus();
mutex_lock(&smp_cpu_state_mutex);
rc = -EBUSY; rc = -EBUSY;
if (cpu_online(cpu)) if (cpu_online(cpu))
goto out; goto out;
...@@ -919,8 +919,8 @@ static ssize_t cpu_configure_store(struct sys_device *dev, const char *buf, ...@@ -919,8 +919,8 @@ static ssize_t cpu_configure_store(struct sys_device *dev, const char *buf,
break; break;
} }
out: out:
put_online_cpus();
mutex_unlock(&smp_cpu_state_mutex); mutex_unlock(&smp_cpu_state_mutex);
put_online_cpus();
return rc ? rc : count; return rc ? rc : count;
} }
static SYSDEV_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store); 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, ...@@ -1095,8 +1095,8 @@ static ssize_t __ref rescan_store(struct sys_device *dev,
int cpu; int cpu;
int rc; int rc;
mutex_lock(&smp_cpu_state_mutex);
get_online_cpus(); get_online_cpus();
mutex_lock(&smp_cpu_state_mutex);
newcpus = cpu_present_map; newcpus = cpu_present_map;
rc = smp_rescan_cpus(); rc = smp_rescan_cpus();
if (rc) if (rc)
...@@ -1109,8 +1109,8 @@ static ssize_t __ref rescan_store(struct sys_device *dev, ...@@ -1109,8 +1109,8 @@ static ssize_t __ref rescan_store(struct sys_device *dev,
} }
rc = 0; rc = 0;
out: out:
put_online_cpus();
mutex_unlock(&smp_cpu_state_mutex); mutex_unlock(&smp_cpu_state_mutex);
put_online_cpus();
if (!cpus_empty(newcpus)) if (!cpus_empty(newcpus))
topology_schedule_update(); topology_schedule_update();
return rc ? rc : count; return rc ? rc : count;
...@@ -1139,16 +1139,16 @@ static ssize_t dispatching_store(struct sys_device *dev, const char *buf, ...@@ -1139,16 +1139,16 @@ static ssize_t dispatching_store(struct sys_device *dev, const char *buf,
if (val != 0 && val != 1) if (val != 0 && val != 1)
return -EINVAL; return -EINVAL;
rc = 0; rc = 0;
mutex_lock(&smp_cpu_state_mutex);
get_online_cpus(); get_online_cpus();
mutex_lock(&smp_cpu_state_mutex);
if (cpu_management == val) if (cpu_management == val)
goto out; goto out;
rc = topology_set_cpu_management(val); rc = topology_set_cpu_management(val);
if (!rc) if (!rc)
cpu_management = val; cpu_management = val;
out: out:
put_online_cpus();
mutex_unlock(&smp_cpu_state_mutex); mutex_unlock(&smp_cpu_state_mutex);
put_online_cpus();
return rc ? rc : count; return rc ? rc : count;
} }
static SYSDEV_ATTR(dispatching, 0644, dispatching_show, dispatching_store); static SYSDEV_ATTR(dispatching, 0644, dispatching_show, dispatching_store);
......
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