From: Hans-Joachim Picht <hpicht@redhat.com> Date: Tue, 20 Jan 2009 16:58:23 +0100 Subject: [s390] cio: ccwgroup online vs. ungroup race condition Message-id: 20090120155823.GC21694@redhat.com O-Subject: [RHEL5 U4 PATCH 3/8] s390 - cio: ccwgroup online vs. ungroup race condition Bugzilla: 479879 RH-Acked-by: Pete Zaitcev <zaitcev@redhat.com> Description ============ Ensure the atomicity of the ungroup operation to prevent concurrent ungroup and online processing which may lead to use-after-release situations. Bugzilla ========= BZ 479879 https://bugzilla.redhat.com/show_bug.cgi?id=479879 Upstream status of the patch: ============================= The patch is upstream as of git commit c619d4223eaa063dd15ce44235b04487235f8cb7 Test status: ============ The patch has been tested and fixes the problem. The fix has been verified by the IBM test department. Please ACK. With best regards, --Hans diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 38954f5..885a5f5 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -77,9 +77,14 @@ ccwgroup_ungroup_store(struct device *dev, struct device_attribute *attr, const struct ccwgroup_device *gdev; gdev = to_ccwgroupdev(dev); - - if (gdev->state != CCWGROUP_OFFLINE) + /* Prevent concurrent online/offline processing and ungrouping. */ + if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0) + return -EAGAIN; + if (gdev->state != CCWGROUP_OFFLINE) { + /* Release onoff "lock" when ungrouping failed. */ + atomic_set(&gdev->onoff, 0); return -EINVAL; + } __ccwgroup_remove_symlinks(gdev); device_unregister(dev);