Skip to content

Commit 9487cfd

Browse files
stefan-haberlandMartin Schwidefsky
authored andcommitted
s390/dasd: fix handling of internal requests
Internal DASD device driver I/O such as query host access count or path verification is started using the _sleep_on() function. To mark a request as started or ended the callback_data is set to either DASD_SLEEPON_START_TAG or DASD_SLEEPON_END_TAG. In cases where the request has to be stopped unconditionally the status is set to DASD_SLEEPON_END_TAG as well which leads to immediate clearing of the request. But the request might still be on a device request queue for normal operation which might lead to a panic because of a BUG() statement in __dasd_device_process_final_queue() or a list corruption of the device request queue. Fix by removing the setting of DASD_SLEEPON_END_TAG in the dasd_cancel_req() and dasd_generic_requeue_all_requests() functions and ensure that the request is not deleted in the requeue function. Trigger the device tasklet in the requeue function and let the normal processing cleanup the request. Signed-off-by: Stefan Haberland <sth@linux.vnet.ibm.com> Reviewed-by: Jan Hoeppner <hoeppner@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
1 parent 91ab883 commit 9487cfd

File tree

1 file changed

+7
-14
lines changed

1 file changed

+7
-14
lines changed

drivers/s390/block/dasd.c

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2581,8 +2581,6 @@ int dasd_cancel_req(struct dasd_ccw_req *cqr)
25812581
case DASD_CQR_QUEUED:
25822582
/* request was not started - just set to cleared */
25832583
cqr->status = DASD_CQR_CLEARED;
2584-
if (cqr->callback_data == DASD_SLEEPON_START_TAG)
2585-
cqr->callback_data = DASD_SLEEPON_END_TAG;
25862584
break;
25872585
case DASD_CQR_IN_IO:
25882586
/* request in IO - terminate IO and release again */
@@ -3902,9 +3900,12 @@ static int dasd_generic_requeue_all_requests(struct dasd_device *device)
39023900
wait_event(dasd_flush_wq,
39033901
(cqr->status != DASD_CQR_CLEAR_PENDING));
39043902

3905-
/* mark sleepon requests as ended */
3906-
if (cqr->callback_data == DASD_SLEEPON_START_TAG)
3907-
cqr->callback_data = DASD_SLEEPON_END_TAG;
3903+
/*
3904+
* requeue requests to blocklayer will only work
3905+
* for block device requests
3906+
*/
3907+
if (_dasd_requeue_request(cqr))
3908+
continue;
39083909

39093910
/* remove requests from device and block queue */
39103911
list_del_init(&cqr->devlist);
@@ -3917,13 +3918,6 @@ static int dasd_generic_requeue_all_requests(struct dasd_device *device)
39173918
cqr = refers;
39183919
}
39193920

3920-
/*
3921-
* requeue requests to blocklayer will only work
3922-
* for block device requests
3923-
*/
3924-
if (_dasd_requeue_request(cqr))
3925-
continue;
3926-
39273921
if (cqr->block)
39283922
list_del_init(&cqr->blocklist);
39293923
cqr->block->base->discipline->free_cp(
@@ -3940,8 +3934,7 @@ static int dasd_generic_requeue_all_requests(struct dasd_device *device)
39403934
list_splice_tail(&requeue_queue, &device->ccw_queue);
39413935
spin_unlock_irq(get_ccwdev_lock(device->cdev));
39423936
}
3943-
/* wake up generic waitqueue for eventually ended sleepon requests */
3944-
wake_up(&generic_waitq);
3937+
dasd_schedule_device_bh(device);
39453938
return rc;
39463939
}
39473940

0 commit comments

Comments
 (0)