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)
475
475
static inline int bio_queue_enter (struct bio * bio )
476
476
{
477
477
struct request_queue * q = bio -> bi_bdev -> bd_disk -> queue ;
478
- bool nowait = bio -> bi_opf & REQ_NOWAIT ;
479
- int ret ;
480
478
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 ;
484
483
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 ;
487
501
}
488
502
489
- return ret ;
503
+ return 0 ;
504
+ dead :
505
+ bio_io_error (bio );
506
+ return - ENODEV ;
490
507
}
491
508
492
509
void blk_queue_exit (struct request_queue * q )
You can’t perform that action at this time.
0 commit comments