From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Martin Schwidefsky" , "Stefan Haberland" Date: Tue, 29 Mar 2016 20:18:22 +0100 Message-ID: Subject: [PATCH 3.2 11/62] s390/dasd: fix refcount for PAV reassignment In-Reply-To: Sender: linux-kernel-owner@vger.kernel.org List-ID: 3.2.79-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Stefan Haberland commit 9d862ababb609439c5d6987f6d3ddd09e703aa0b upstream. Add refcount to the DASD device when a summary unit check worker is scheduled. This prevents that the device is set offline with worker in place. Signed-off-by: Stefan Haberland Signed-off-by: Martin Schwidefsky Signed-off-by: Ben Hutchings --- drivers/s390/block/dasd_alias.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) --- a/drivers/s390/block/dasd_alias.c +++ b/drivers/s390/block/dasd_alias.c @@ -326,8 +326,10 @@ void dasd_alias_disconnect_device_from_l spin_unlock_irqrestore(&lcu->lock, flags); cancel_work_sync(&lcu->suc_data.worker); spin_lock_irqsave(&lcu->lock, flags); - if (device == lcu->suc_data.device) + if (device == lcu->suc_data.device) { + dasd_put_device(device); lcu->suc_data.device = NULL; + } } was_pending = 0; if (device == lcu->ruac_data.device) { @@ -335,8 +337,10 @@ void dasd_alias_disconnect_device_from_l was_pending = 1; cancel_delayed_work_sync(&lcu->ruac_data.dwork); spin_lock_irqsave(&lcu->lock, flags); - if (device == lcu->ruac_data.device) + if (device == lcu->ruac_data.device) { + dasd_put_device(device); lcu->ruac_data.device = NULL; + } } private->lcu = NULL; spin_unlock_irqrestore(&lcu->lock, flags); @@ -586,8 +590,10 @@ static void lcu_update_work(struct work_ if (rc || (lcu->flags & NEED_UAC_UPDATE)) { DBF_DEV_EVENT(DBF_WARNING, device, "could not update" " alias data in lcu (rc = %d), retry later", rc); - schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ); + if (!schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ)) + dasd_put_device(device); } else { + dasd_put_device(device); lcu->ruac_data.device = NULL; lcu->flags &= ~UPDATE_PENDING; } @@ -630,8 +636,10 @@ static int _schedule_lcu_update(struct a */ if (!usedev) return -EINVAL; + dasd_get_device(usedev); lcu->ruac_data.device = usedev; - schedule_delayed_work(&lcu->ruac_data.dwork, 0); + if (!schedule_delayed_work(&lcu->ruac_data.dwork, 0)) + dasd_put_device(usedev); return 0; } @@ -953,6 +961,7 @@ static void summary_unit_check_handling_ /* 3. read new alias configuration */ _schedule_lcu_update(lcu, device); lcu->suc_data.device = NULL; + dasd_put_device(device); spin_unlock_irqrestore(&lcu->lock, flags); } @@ -1012,6 +1021,8 @@ void dasd_alias_handle_summary_unit_chec } lcu->suc_data.reason = reason; lcu->suc_data.device = device; + dasd_get_device(device); spin_unlock(&lcu->lock); - schedule_work(&lcu->suc_data.worker); + if (!schedule_work(&lcu->suc_data.worker)) + dasd_put_device(device); };