]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - block/blk-core.c
blk-mq: introduce blk_mq_hw_queue_first_cpu() to figure out first cpu
[mirror_ubuntu-bionic-kernel.git] / block / blk-core.c
index b8881750a3acd705789050c845c942673da999a8..fc0666354af39226ec616b09d5d5d2c278690b05 100644 (file)
@@ -562,6 +562,13 @@ static void __blk_drain_queue(struct request_queue *q, bool drain_all)
        }
 }
 
+void blk_drain_queue(struct request_queue *q)
+{
+       spin_lock_irq(q->queue_lock);
+       __blk_drain_queue(q, true);
+       spin_unlock_irq(q->queue_lock);
+}
+
 /**
  * blk_queue_bypass_start - enter queue bypass mode
  * @q: queue of interest
@@ -689,11 +696,18 @@ void blk_cleanup_queue(struct request_queue *q)
         */
        blk_freeze_queue(q);
        spin_lock_irq(lock);
-       if (!q->mq_ops)
-               __blk_drain_queue(q, true);
        queue_flag_set(QUEUE_FLAG_DEAD, q);
        spin_unlock_irq(lock);
 
+       /*
+        * make sure all in-progress dispatch are completed because
+        * blk_freeze_queue() can only complete all requests, and
+        * dispatch may still be in-progress since we dispatch requests
+        * from more than one contexts
+        */
+       if (q->mq_ops)
+               blk_mq_quiesce_queue(q);
+
        /* for synchronous bio-based driver finish in-flight integrity i/o */
        blk_flush_integrity();
 
@@ -809,7 +823,7 @@ int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags)
                bool success = false;
                int ret;
 
-               rcu_read_lock_sched();
+               rcu_read_lock();
                if (percpu_ref_tryget_live(&q->q_usage_counter)) {
                        /*
                         * The code that sets the PREEMPT_ONLY flag is
@@ -822,7 +836,7 @@ int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags)
                                percpu_ref_put(&q->q_usage_counter);
                        }
                }
-               rcu_read_unlock_sched();
+               rcu_read_unlock();
 
                if (success)
                        return 0;
@@ -2387,7 +2401,7 @@ blk_qc_t submit_bio(struct bio *bio)
                unsigned int count;
 
                if (unlikely(bio_op(bio) == REQ_OP_WRITE_SAME))
-                       count = queue_logical_block_size(bio->bi_disk->queue);
+                       count = queue_logical_block_size(bio->bi_disk->queue) >> 9;
                else
                        count = bio_sectors(bio);
 
@@ -3246,6 +3260,8 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
 {
        if (bio_has_data(bio))
                rq->nr_phys_segments = bio_phys_segments(q, bio);
+       else if (bio_op(bio) == REQ_OP_DISCARD)
+               rq->nr_phys_segments = 1;
 
        rq->__data_len = bio->bi_iter.bi_size;
        rq->bio = rq->biotail = bio;