File tree Expand file tree Collapse file tree 1 file changed +25
-8
lines changed Expand file tree Collapse file tree 1 file changed +25
-8
lines changed Original file line number Diff line number Diff line change @@ -475,18 +475,35 @@ int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags)
475475static inline int bio_queue_enter (struct bio * bio )
476476{
477477 struct request_queue * q = bio -> bi_bdev -> bd_disk -> queue ;
478- bool nowait = bio -> bi_opf & REQ_NOWAIT ;
479- int ret ;
480478
481- ret = blk_queue_enter (q , nowait ? BLK_MQ_REQ_NOWAIT : 0 );
482- if (unlikely (ret )) {
483- if (nowait && !blk_queue_dying (q ))
479+ while (!blk_try_enter_queue (q , false)) {
480+ if (bio -> bi_opf & REQ_NOWAIT ) {
481+ if (blk_queue_dying (q ))
482+ goto dead ;
484483 bio_wouldblock_error (bio );
485- else
486- bio_io_error (bio );
484+ return - EBUSY ;
485+ }
486+
487+ /*
488+ * read pair of barrier in blk_freeze_queue_start(), we need to
489+ * order reading __PERCPU_REF_DEAD flag of .q_usage_counter and
490+ * reading .mq_freeze_depth or queue dying flag, otherwise the
491+ * following wait may never return if the two reads are
492+ * reordered.
493+ */
494+ smp_rmb ();
495+ wait_event (q -> mq_freeze_wq ,
496+ (!q -> mq_freeze_depth &&
497+ blk_pm_resume_queue (false, q )) ||
498+ blk_queue_dying (q ));
499+ if (blk_queue_dying (q ))
500+ goto dead ;
487501 }
488502
489- return ret ;
503+ return 0 ;
504+ dead :
505+ bio_io_error (bio );
506+ return - ENODEV ;
490507}
491508
492509void blk_queue_exit (struct request_queue * q )
You can’t perform that action at this time.
0 commit comments