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 4.9 140/175] s390/dasd: fix list corruption of pavgroup group list
    Date
    From: Stefan Haberland <sth@linux.ibm.com>

    commit 0ede91f83aa335da1c3ec68eb0f9e228f269f6d8 upstream.

    dasd_alias_add_device() moves devices to the active_devices list in case
    of a scheduled LCU update regardless if they have previously been in a
    pavgroup or not.

    Example: device A and B are in the same pavgroup.

    Device A has already been in a pavgroup and the private->pavgroup pointer
    is set and points to a valid pavgroup. While going through dasd_add_device
    it is moved from the pavgroup to the active_devices list.

    In parallel device B might be removed from the same pavgroup in
    remove_device_from_lcu() which in turn checks if the group is empty
    and deletes it accordingly because device A has already been removed from
    there.

    When now device A enters remove_device_from_lcu() it is tried to remove it
    from the pavgroup again because the pavgroup pointer is still set and again
    the empty group will be cleaned up which leads to a list corruption.

    Fix by setting private->pavgroup to NULL in dasd_add_device.

    If the device has been the last device on the pavgroup an empty pavgroup
    remains but this will be cleaned up by the scheduled lcu_update which
    iterates over all existing pavgroups.

    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 | 1 +
    1 file changed, 1 insertion(+)

    --- a/drivers/s390/block/dasd_alias.c
    +++ b/drivers/s390/block/dasd_alias.c
    @@ -633,6 +633,7 @@ int dasd_alias_add_device(struct dasd_de
    }
    if (lcu->flags & UPDATE_PENDING) {
    list_move(&device->alias_list, &lcu->active_devices);
    + private->pavgroup = NULL;
    _schedule_lcu_update(lcu, device);
    }
    spin_unlock_irqrestore(&lcu->lock, flags);

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