Commit c619d422 authored by Peter Oberparleiter's avatar Peter Oberparleiter Committed by Martin Schwidefsky

[S390] cio: fix ccwgroup online vs. ungroup race condition

Ensure atomicity of ungroup operation to prevent concurrent ungroup
and online processing which may lead to use-after-release situations.
Signed-off-by: default avatarPeter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 111e95a4
...@@ -91,15 +91,23 @@ ccwgroup_ungroup_store(struct device *dev, struct device_attribute *attr, const ...@@ -91,15 +91,23 @@ ccwgroup_ungroup_store(struct device *dev, struct device_attribute *attr, const
gdev = to_ccwgroupdev(dev); gdev = to_ccwgroupdev(dev);
if (gdev->state != CCWGROUP_OFFLINE) /* Prevent concurrent online/offline processing and ungrouping. */
return -EINVAL; if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
return -EAGAIN;
if (gdev->state != CCWGROUP_OFFLINE) {
rc = -EINVAL;
goto out;
}
/* Note that we cannot unregister the device from one of its /* Note that we cannot unregister the device from one of its
* attribute methods, so we have to use this roundabout approach. * attribute methods, so we have to use this roundabout approach.
*/ */
rc = device_schedule_callback(dev, ccwgroup_ungroup_callback); rc = device_schedule_callback(dev, ccwgroup_ungroup_callback);
if (rc) out:
count = rc; if (rc) {
/* Release onoff "lock" when ungrouping failed. */
atomic_set(&gdev->onoff, 0);
return rc;
}
return count; return count;
} }
......
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