ARM: configs: tizen_bcm2711_defconfig: Enable VIDEO_CODEC_BCM2835
[platform/kernel/linux-rpi.git] / block / elevator.c
index 440699c..1b5e57f 100644 (file)
@@ -336,6 +336,9 @@ enum elv_merge elv_merge(struct request_queue *q, struct request **req,
        __rq = elv_rqhash_find(q, bio->bi_iter.bi_sector);
        if (__rq && elv_bio_merge_ok(__rq, bio)) {
                *req = __rq;
+
+               if (blk_discard_mergable(__rq))
+                       return ELEVATOR_DISCARD_MERGE;
                return ELEVATOR_BACK_MERGE;
        }
 
@@ -350,9 +353,11 @@ enum elv_merge elv_merge(struct request_queue *q, struct request **req,
  * we can append 'rq' to an existing request, so we can throw 'rq' away
  * afterwards.
  *
- * Returns true if we merged, false otherwise
+ * Returns true if we merged, false otherwise. 'free' will contain all
+ * requests that need to be freed.
  */
-bool elv_attempt_insert_merge(struct request_queue *q, struct request *rq)
+bool elv_attempt_insert_merge(struct request_queue *q, struct request *rq,
+                             struct list_head *free)
 {
        struct request *__rq;
        bool ret;
@@ -363,8 +368,10 @@ bool elv_attempt_insert_merge(struct request_queue *q, struct request *rq)
        /*
         * First try one-hit cache.
         */
-       if (q->last_merge && blk_attempt_req_merge(q, q->last_merge, rq))
+       if (q->last_merge && blk_attempt_req_merge(q, q->last_merge, rq)) {
+               list_add(&rq->queuelist, free);
                return true;
+       }
 
        if (blk_queue_noxmerges(q))
                return false;
@@ -378,6 +385,7 @@ bool elv_attempt_insert_merge(struct request_queue *q, struct request *rq)
                if (!__rq || !blk_attempt_req_merge(q, __rq, rq))
                        break;
 
+               list_add(&rq->queuelist, free);
                /* The merged request could be merged with others, try again */
                ret = true;
                rq = __rq;
@@ -515,13 +523,15 @@ void elv_unregister_queue(struct request_queue *q)
                kobject_del(&e->kobj);
 
                e->registered = 0;
-               /* Re-enable throttling in case elevator disabled it */
-               wbt_enable_default(q);
        }
 }
 
 int elv_register(struct elevator_type *e)
 {
+       /* insert_requests and dispatch_request are mandatory */
+       if (WARN_ON_ONCE(!e->ops.insert_requests || !e->ops.dispatch_request))
+               return -EINVAL;
+
        /* create icq_cache if requested */
        if (e->icq_size) {
                if (WARN_ON(e->icq_size < sizeof(struct io_cq)) ||
@@ -621,6 +631,9 @@ static inline bool elv_support_iosched(struct request_queue *q)
  */
 static struct elevator_type *elevator_get_default(struct request_queue *q)
 {
+       if (q->tag_set && q->tag_set->flags & BLK_MQ_F_NO_SCHED_BY_DEFAULT)
+               return NULL;
+
        if (q->nr_hw_queues != 1 &&
                        !blk_mq_is_sbitmap_shared(q->tag_set->flags))
                return NULL;
@@ -679,12 +692,18 @@ void elevator_init_mq(struct request_queue *q)
        if (!e)
                return;
 
+       /*
+        * We are called before adding disk, when there isn't any FS I/O,
+        * so freezing queue plus canceling dispatch work is enough to
+        * drain any dispatch activities originated from passthrough
+        * requests, then no need to quiesce queue which may add long boot
+        * latency, especially when lots of disks are involved.
+        */
        blk_mq_freeze_queue(q);
-       blk_mq_quiesce_queue(q);
+       blk_mq_cancel_work_sync(q);
 
        err = blk_mq_init_sched(q, e);
 
-       blk_mq_unquiesce_queue(q);
        blk_mq_unfreeze_queue(q);
 
        if (err) {
@@ -694,7 +713,6 @@ void elevator_init_mq(struct request_queue *q)
        }
 }
 
-
 /*
  * switch to new_e io scheduler. be careful not to introduce deadlocks -
  * we don't free the old io scheduler, before we have allocated what we