block: Make writeback throttling defaults consistent for SQ devices
authorJan Kara <jack@suse.cz>
Wed, 19 Apr 2017 09:33:27 +0000 (11:33 +0200)
committerJens Axboe <axboe@fb.com>
Wed, 19 Apr 2017 14:49:03 +0000 (08:49 -0600)
When CFQ is used as an elevator, it disables writeback throttling
because they don't play well together. Later when a different elevator
is chosen for the device, writeback throttling doesn't get enabled
again as it should. Make sure CFQ enables writeback throttling (if it
should be enabled by default) when we switch from it to another IO
scheduler.

Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jens Axboe <axboe@fb.com>
block/blk-sysfs.c
block/blk-wbt.c
block/blk-wbt.h
block/elevator.c

index fc20489f0d2b49528fcc2dad9366a8b0ae3ab829..f85723332288d497e624ab66eac9211d8147cba4 100644 (file)
@@ -844,23 +844,6 @@ struct kobj_type blk_queue_ktype = {
        .release        = blk_release_queue,
 };
 
-static void blk_wb_init(struct request_queue *q)
-{
-#ifndef CONFIG_BLK_WBT_MQ
-       if (q->mq_ops)
-               return;
-#endif
-#ifndef CONFIG_BLK_WBT_SQ
-       if (q->request_fn)
-               return;
-#endif
-
-       /*
-        * If this fails, we don't get throttling
-        */
-       wbt_init(q);
-}
-
 int blk_register_queue(struct gendisk *disk)
 {
        int ret;
@@ -908,7 +891,7 @@ int blk_register_queue(struct gendisk *disk)
 
        kobject_uevent(&q->kobj, KOBJ_ADD);
 
-       blk_wb_init(q);
+       wbt_enable_default(q);
 
        blk_throtl_register_queue(q);
 
index b3b79149d3a0c61529983bb5e28e62f8c25d78a9..26e1bb617877f24be53b25415403b0bfaf275ffb 100644 (file)
@@ -665,6 +665,25 @@ void wbt_disable_default(struct request_queue *q)
 }
 EXPORT_SYMBOL_GPL(wbt_disable_default);
 
+/*
+ * Enable wbt if defaults are configured that way
+ */
+void wbt_enable_default(struct request_queue *q)
+{
+       /* Throttling already enabled? */
+       if (q->rq_wb)
+               return;
+
+       /* Queue not registered? Maybe shutting down... */
+       if (!test_bit(QUEUE_FLAG_REGISTERED, &q->queue_flags))
+               return;
+
+       if ((q->mq_ops && IS_ENABLED(CONFIG_BLK_WBT_MQ)) ||
+           (q->request_fn && IS_ENABLED(CONFIG_BLK_WBT_SQ)))
+               wbt_init(q);
+}
+EXPORT_SYMBOL_GPL(wbt_enable_default);
+
 u64 wbt_default_latency_nsec(struct request_queue *q)
 {
        /*
index ad6c78507c3a7fdda23cbcfd7e5885405d61ac39..df6de50c5d594847b16aabb9d88e16c5ca2312d0 100644 (file)
@@ -117,6 +117,7 @@ void wbt_update_limits(struct rq_wb *);
 void wbt_requeue(struct rq_wb *, struct blk_issue_stat *);
 void wbt_issue(struct rq_wb *, struct blk_issue_stat *);
 void wbt_disable_default(struct request_queue *);
+void wbt_enable_default(struct request_queue *);
 
 void wbt_set_queue_depth(struct rq_wb *, unsigned int);
 void wbt_set_write_cache(struct rq_wb *, bool);
@@ -155,6 +156,9 @@ static inline void wbt_issue(struct rq_wb *rwb, struct blk_issue_stat *stat)
 static inline void wbt_disable_default(struct request_queue *q)
 {
 }
+static inline void wbt_enable_default(struct request_queue *q)
+{
+}
 static inline void wbt_set_queue_depth(struct rq_wb *rwb, unsigned int depth)
 {
 }
index dbeecf7be719eaada4457ed3c7ac799fd0bbacec..fb50416b5aaed8727df8c27c2f5a8214f2a46c5a 100644 (file)
@@ -41,6 +41,7 @@
 
 #include "blk.h"
 #include "blk-mq-sched.h"
+#include "blk-wbt.h"
 
 static DEFINE_SPINLOCK(elv_list_lock);
 static LIST_HEAD(elv_list);
@@ -877,6 +878,8 @@ void elv_unregister_queue(struct request_queue *q)
                kobject_uevent(&e->kobj, KOBJ_REMOVE);
                kobject_del(&e->kobj);
                e->registered = 0;
+               /* Re-enable throttling in case elevator disabled it */
+               wbt_enable_default(q);
        }
 }
 EXPORT_SYMBOL(elv_unregister_queue);