lkml.org 
[lkml]   [2007]   [Mar]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: 2.6.21-rc suspend regression: sysfs deadlock
    On Tue, 13 Mar 2007 11:00:21 -0400 (EDT),
    Alan Stern <stern@rowland.harvard.edu> wrote:

    > The consensus is that we would be better off keeping Oliver's original
    > patch without your silly change, and instead fixing the particular method
    > call that deadlocked.

    Another call that deadlocked with Oliver's patch is ungroup for s390
    ccwgroup devices. It can be made to work again with a similar patch.

    Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>

    ---
    drivers/s390/cio/ccwgroup.c | 35 +++++++++++++++++++++++++++++++----
    1 file changed, 31 insertions(+), 4 deletions(-)

    --- linux-2.6.orig/drivers/s390/cio/ccwgroup.c
    +++ linux-2.6/drivers/s390/cio/ccwgroup.c
    @@ -67,22 +67,49 @@ __ccwgroup_remove_symlinks(struct ccwgro

    }

    +struct ccwgroup_work_struct {
    + struct ccwgroup_device *gdev;
    + struct work_struct work;
    +};
    +
    +static void ccwgroup_ungroup_work(struct work_struct *work)
    +{
    + struct ccwgroup_work_struct *ungroup_work
    + = container_of(work, struct ccwgroup_work_struct, work);
    +
    + __ccwgroup_remove_symlinks(ungroup_work->gdev);
    + device_unregister(&ungroup_work->gdev->dev);
    + put_device(&ungroup_work->gdev->dev);
    + kfree(ungroup_work);
    +}
    +
    /*
    * Provide an 'ungroup' attribute so the user can remove group devices no
    * longer needed or accidentially created. Saves memory :)
    + * Note that we cannot unregister the device from one of its attribute
    + * methods, so we have to delay it.
    */
    -static ssize_t
    -ccwgroup_ungroup_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
    +static ssize_t ccwgroup_ungroup_store(struct device *dev,
    + struct device_attribute *attr,
    + const char *buf, size_t count)
    {
    struct ccwgroup_device *gdev;
    + struct ccwgroup_work_struct *ungroup_work;

    gdev = to_ccwgroupdev(dev);

    if (gdev->state != CCWGROUP_OFFLINE)
    return -EINVAL;

    - __ccwgroup_remove_symlinks(gdev);
    - device_unregister(dev);
    + ungroup_work = kmalloc(sizeof(*ungroup_work), GFP_KERNEL);
    + if (!ungroup_work)
    + return -ENOMEM;
    + ungroup_work->gdev = gdev;
    + INIT_WORK(&ungroup_work->work, ccwgroup_ungroup_work);
    + if (!get_device(&gdev->dev))
    + kfree(ungroup_work);
    + else
    + schedule_work(&ungroup_work->work);

    return count;
    }
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2007-03-13 19:43    [W:2.764 / U:0.056 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site