lkml.org 
[lkml]   [2020]   [Dec]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 558/717] s390/dasd: fix list corruption of lcu list
    Date
    From: Stefan Haberland <sth@linux.ibm.com>

    commit 53a7f655834c7c335bf683f248208d4fbe4b47bc upstream.

    In dasd_alias_disconnect_device_from_lcu the device is removed from any
    list on the LCU. Afterwards the LCU is removed from the lcu list if it
    does not contain devices any longer.

    The lcu->lock protects the lcu from parallel updates. But to cancel all
    workers and wait for completion the lcu->lock has to be unlocked.

    If two devices are removed in parallel and both are removed from the LCU
    the first device that takes the lcu->lock again will delete the LCU because
    it is already empty but the second device also tries to free the LCU which
    leads to a list corruption of the lcu list.

    Fix by removing the device right before the lcu is checked without
    unlocking the lcu->lock in between.

    Fixes: 8e09f21574ea ("[S390] dasd: add hyper PAV support to DASD device driver, part 1")
    Cc: stable@vger.kernel.org
    Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
    Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/s390/block/dasd_alias.c | 2 +-
    1 file changed, 1 insertion(+), 1 deletion(-)

    --- a/drivers/s390/block/dasd_alias.c
    +++ b/drivers/s390/block/dasd_alias.c
    @@ -256,7 +256,6 @@ void dasd_alias_disconnect_device_from_l
    return;
    device->discipline->get_uid(device, &uid);
    spin_lock_irqsave(&lcu->lock, flags);
    - list_del_init(&device->alias_list);
    /* make sure that the workers don't use this device */
    if (device == lcu->suc_data.device) {
    spin_unlock_irqrestore(&lcu->lock, flags);
    @@ -283,6 +282,7 @@ void dasd_alias_disconnect_device_from_l

    spin_lock_irqsave(&aliastree.lock, flags);
    spin_lock(&lcu->lock);
    + list_del_init(&device->alias_list);
    if (list_empty(&lcu->grouplist) &&
    list_empty(&lcu->active_devices) &&
    list_empty(&lcu->inactive_devices)) {

    \
     
     \ /
      Last update: 2020-12-28 15:44    [W:4.644 / U:0.272 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site