Petr Tesarik f5a02d
From: Stefan Haberland <sth@linux.ibm.com>
Petr Tesarik f5a02d
Date: Fri, 5 Mar 2021 13:54:38 +0100
Petr Tesarik f5a02d
Subject: s390/dasd: fix hanging DASD driver unbind
Petr Tesarik f5a02d
Git-commit: 7d365bd0bff3c0310c39ebaffc9a8458e036d666
Petr Tesarik f5a02d
Patch-mainline: v5.12-rc3
Petr Tesarik f5a02d
References: bsc#1183932 LTC#192153
Petr Tesarik f5a02d
Petr Tesarik f5a02d
In case of an unbind of the DASD device driver the function
Petr Tesarik f5a02d
dasd_generic_remove() is called which shuts down the device.
Petr Tesarik f5a02d
Among others this functions removes the int_handler from the cdev.
Petr Tesarik f5a02d
During shutdown the device cancels all outstanding IO requests and waits
Petr Tesarik f5a02d
for completion of the clear request.
Petr Tesarik f5a02d
Unfortunately the clear interrupt will never be received when there is no
Petr Tesarik f5a02d
interrupt handler connected.
Petr Tesarik f5a02d
Petr Tesarik f5a02d
Fix by moving the int_handler removal after the call to the state machine
Petr Tesarik f5a02d
where no request or interrupt is outstanding.
Petr Tesarik f5a02d
Petr Tesarik f5a02d
Cc: stable@vger.kernel.org
Petr Tesarik f5a02d
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Petr Tesarik f5a02d
Tested-by: Bjoern Walk <bwalk@linux.ibm.com>
Petr Tesarik f5a02d
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Petr Tesarik f5a02d
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Petr Tesarik f5a02d
Acked-by: Petr Tesarik <ptesarik@suse.com>
Petr Tesarik f5a02d
---
Petr Tesarik f5a02d
 drivers/s390/block/dasd.c |    3 +--
Petr Tesarik f5a02d
 1 file changed, 1 insertion(+), 2 deletions(-)
Petr Tesarik f5a02d
Petr Tesarik f5a02d
--- a/drivers/s390/block/dasd.c
Petr Tesarik f5a02d
+++ b/drivers/s390/block/dasd.c
Petr Tesarik f5a02d
@@ -3522,8 +3522,6 @@ void dasd_generic_remove(struct ccw_devi
Petr Tesarik f5a02d
 	struct dasd_device *device;
Petr Tesarik f5a02d
 	struct dasd_block *block;
Petr Tesarik f5a02d
 
Petr Tesarik f5a02d
-	cdev->handler = NULL;
Petr Tesarik f5a02d
-
Petr Tesarik f5a02d
 	device = dasd_device_from_cdev(cdev);
Petr Tesarik f5a02d
 	if (IS_ERR(device)) {
Petr Tesarik f5a02d
 		dasd_remove_sysfs_files(cdev);
Petr Tesarik f5a02d
@@ -3542,6 +3540,7 @@ void dasd_generic_remove(struct ccw_devi
Petr Tesarik f5a02d
 	 * no quite down yet.
Petr Tesarik f5a02d
 	 */
Petr Tesarik f5a02d
 	dasd_set_target_state(device, DASD_STATE_NEW);
Petr Tesarik f5a02d
+	cdev->handler = NULL;
Petr Tesarik f5a02d
 	/* dasd_delete_device destroys the device reference. */
Petr Tesarik f5a02d
 	block = device->block;
Petr Tesarik f5a02d
 	dasd_delete_device(device);