@@ -2943,41 +2943,32 @@ static void _dasd_wake_block_flush_cb(struct dasd_ccw_req *cqr, void *data)
2943
2943
* Requeue a request back to the block request queue
2944
2944
* only works for block requests
2945
2945
*/
2946
- static int _dasd_requeue_request (struct dasd_ccw_req * cqr )
2946
+ static void _dasd_requeue_request (struct dasd_ccw_req * cqr )
2947
2947
{
2948
- struct dasd_block * block = cqr -> block ;
2949
2948
struct request * req ;
2950
2949
2951
- if (!block )
2952
- return - EINVAL ;
2953
2950
/*
2954
2951
* If the request is an ERP request there is nothing to requeue.
2955
2952
* This will be done with the remaining original request.
2956
2953
*/
2957
2954
if (cqr -> refers )
2958
- return 0 ;
2955
+ return ;
2959
2956
spin_lock_irq (& cqr -> dq -> lock );
2960
2957
req = (struct request * ) cqr -> callback_data ;
2961
2958
blk_mq_requeue_request (req , true);
2962
2959
spin_unlock_irq (& cqr -> dq -> lock );
2963
2960
2964
- return 0 ;
2961
+ return ;
2965
2962
}
2966
2963
2967
- /*
2968
- * Go through all request on the dasd_block request queue, cancel them
2969
- * on the respective dasd_device, and return them to the generic
2970
- * block layer.
2971
- */
2972
- static int dasd_flush_block_queue (struct dasd_block * block )
2964
+ static int _dasd_requests_to_flushqueue (struct dasd_block * block ,
2965
+ struct list_head * flush_queue )
2973
2966
{
2974
2967
struct dasd_ccw_req * cqr , * n ;
2975
- int rc , i ;
2976
- struct list_head flush_queue ;
2977
2968
unsigned long flags ;
2969
+ int rc , i ;
2978
2970
2979
- INIT_LIST_HEAD (& flush_queue );
2980
- spin_lock_bh (& block -> queue_lock );
2971
+ spin_lock_irqsave (& block -> queue_lock , flags );
2981
2972
rc = 0 ;
2982
2973
restart :
2983
2974
list_for_each_entry_safe (cqr , n , & block -> ccw_queue , blocklist ) {
@@ -2992,13 +2983,32 @@ static int dasd_flush_block_queue(struct dasd_block *block)
2992
2983
* is returned from the dasd_device layer.
2993
2984
*/
2994
2985
cqr -> callback = _dasd_wake_block_flush_cb ;
2995
- for (i = 0 ; cqr != NULL ; cqr = cqr -> refers , i ++ )
2996
- list_move_tail (& cqr -> blocklist , & flush_queue );
2986
+ for (i = 0 ; cqr ; cqr = cqr -> refers , i ++ )
2987
+ list_move_tail (& cqr -> blocklist , flush_queue );
2997
2988
if (i > 1 )
2998
2989
/* moved more than one request - need to restart */
2999
2990
goto restart ;
3000
2991
}
3001
- spin_unlock_bh (& block -> queue_lock );
2992
+ spin_unlock_irqrestore (& block -> queue_lock , flags );
2993
+
2994
+ return rc ;
2995
+ }
2996
+
2997
+ /*
2998
+ * Go through all request on the dasd_block request queue, cancel them
2999
+ * on the respective dasd_device, and return them to the generic
3000
+ * block layer.
3001
+ */
3002
+ static int dasd_flush_block_queue (struct dasd_block * block )
3003
+ {
3004
+ struct dasd_ccw_req * cqr , * n ;
3005
+ struct list_head flush_queue ;
3006
+ unsigned long flags ;
3007
+ int rc ;
3008
+
3009
+ INIT_LIST_HEAD (& flush_queue );
3010
+ rc = _dasd_requests_to_flushqueue (block , & flush_queue );
3011
+
3002
3012
/* Now call the callback function of flushed requests */
3003
3013
restart_cb :
3004
3014
list_for_each_entry_safe (cqr , n , & flush_queue , blocklist ) {
@@ -3881,75 +3891,36 @@ EXPORT_SYMBOL_GPL(dasd_generic_space_avail);
3881
3891
*/
3882
3892
int dasd_generic_requeue_all_requests (struct dasd_device * device )
3883
3893
{
3894
+ struct dasd_block * block = device -> block ;
3884
3895
struct list_head requeue_queue ;
3885
3896
struct dasd_ccw_req * cqr , * n ;
3886
- struct dasd_ccw_req * refers ;
3887
3897
int rc ;
3888
3898
3889
- INIT_LIST_HEAD (& requeue_queue );
3890
- spin_lock_irq (get_ccwdev_lock (device -> cdev ));
3891
- rc = 0 ;
3892
- list_for_each_entry_safe (cqr , n , & device -> ccw_queue , devlist ) {
3893
- /* Check status and move request to flush_queue */
3894
- if (cqr -> status == DASD_CQR_IN_IO ) {
3895
- rc = device -> discipline -> term_IO (cqr );
3896
- if (rc ) {
3897
- /* unable to terminate requeust */
3898
- dev_err (& device -> cdev -> dev ,
3899
- "Unable to terminate request %p "
3900
- "on suspend\n" , cqr );
3901
- spin_unlock_irq (get_ccwdev_lock (device -> cdev ));
3902
- dasd_put_device (device );
3903
- return rc ;
3904
- }
3905
- }
3906
- list_move_tail (& cqr -> devlist , & requeue_queue );
3907
- }
3908
- spin_unlock_irq (get_ccwdev_lock (device -> cdev ));
3909
-
3910
- list_for_each_entry_safe (cqr , n , & requeue_queue , devlist ) {
3911
- wait_event (dasd_flush_wq ,
3912
- (cqr -> status != DASD_CQR_CLEAR_PENDING ));
3899
+ if (!block )
3900
+ return 0 ;
3913
3901
3914
- /*
3915
- * requeue requests to blocklayer will only work
3916
- * for block device requests
3917
- */
3918
- if (_dasd_requeue_request (cqr ))
3919
- continue ;
3902
+ INIT_LIST_HEAD (& requeue_queue );
3903
+ rc = _dasd_requests_to_flushqueue (block , & requeue_queue );
3920
3904
3921
- /* remove requests from device and block queue */
3922
- list_del_init (& cqr -> devlist );
3923
- while (cqr -> refers != NULL ) {
3924
- refers = cqr -> refers ;
3925
- /* remove the request from the block queue */
3926
- list_del (& cqr -> blocklist );
3927
- /* free the finished erp request */
3928
- dasd_free_erp_request (cqr , cqr -> memdev );
3929
- cqr = refers ;
3905
+ /* Now call the callback function of flushed requests */
3906
+ restart_cb :
3907
+ list_for_each_entry_safe (cqr , n , & requeue_queue , blocklist ) {
3908
+ wait_event (dasd_flush_wq , (cqr -> status < DASD_CQR_QUEUED ));
3909
+ /* Process finished ERP request. */
3910
+ if (cqr -> refers ) {
3911
+ spin_lock_bh (& block -> queue_lock );
3912
+ __dasd_process_erp (block -> base , cqr );
3913
+ spin_unlock_bh (& block -> queue_lock );
3914
+ /* restart list_for_xx loop since dasd_process_erp
3915
+ * might remove multiple elements
3916
+ */
3917
+ goto restart_cb ;
3930
3918
}
3931
-
3932
- /*
3933
- * _dasd_requeue_request already checked for a valid
3934
- * blockdevice, no need to check again
3935
- * all erp requests (cqr->refers) have a cqr->block
3936
- * pointer copy from the original cqr
3937
- */
3919
+ _dasd_requeue_request (cqr );
3938
3920
list_del_init (& cqr -> blocklist );
3939
3921
cqr -> block -> base -> discipline -> free_cp (
3940
3922
cqr , (struct request * ) cqr -> callback_data );
3941
3923
}
3942
-
3943
- /*
3944
- * if requests remain then they are internal request
3945
- * and go back to the device queue
3946
- */
3947
- if (!list_empty (& requeue_queue )) {
3948
- /* move freeze_queue to start of the ccw_queue */
3949
- spin_lock_irq (get_ccwdev_lock (device -> cdev ));
3950
- list_splice_tail (& requeue_queue , & device -> ccw_queue );
3951
- spin_unlock_irq (get_ccwdev_lock (device -> cdev ));
3952
- }
3953
3924
dasd_schedule_device_bh (device );
3954
3925
return rc ;
3955
3926
}
0 commit comments