diff mbox series

[v2,4/7] block: Improve default elevator selection

Message ID 20190828022947.23364-5-damien.lemoal@wdc.com (mailing list archive)
State Superseded
Headers show
Series Elevator cleanups and improvements | expand

Commit Message

Damien Le Moal Aug. 28, 2019, 2:29 a.m. UTC
For block devices that do not specify required features, preserve the
current default elevator selection (mq-deadline for single queue
devices, none for multi-queue devices). However, for devices specifying
required features (e.g. zoned block devices ELEVATOR_F_ZBD_SEQ_WRITE
feature), select the first available elevator providing the required
features.

In all cases, default to "none" if no elevator is available or if the
initialization of the default elevator fails.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---
 block/elevator.c | 48 ++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 44 insertions(+), 4 deletions(-)

Comments

Christoph Hellwig Sept. 3, 2019, 8:57 a.m. UTC | #1
On Wed, Aug 28, 2019 at 11:29:44AM +0900, Damien Le Moal wrote:
> For block devices that do not specify required features, preserve the
> current default elevator selection (mq-deadline for single queue
> devices, none for multi-queue devices). However, for devices specifying
> required features (e.g. zoned block devices ELEVATOR_F_ZBD_SEQ_WRITE
> feature), select the first available elevator providing the required
> features.
> 
> In all cases, default to "none" if no elevator is available or if the
> initialization of the default elevator fails.
> 
> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>
Damien Le Moal Sept. 4, 2019, 8:42 a.m. UTC | #2
On Tue, 2019-09-03 at 01:57 -0700, Christoph Hellwig wrote:
> On Wed, Aug 28, 2019 at 11:29:44AM +0900, Damien Le Moal wrote:
> > For block devices that do not specify required features, preserve the
> > current default elevator selection (mq-deadline for single queue
> > devices, none for multi-queue devices). However, for devices specifying
> > required features (e.g. zoned block devices ELEVATOR_F_ZBD_SEQ_WRITE
> > feature), select the first available elevator providing the required
> > features.
> > 
> > In all cases, default to "none" if no elevator is available or if the
> > initialization of the default elevator fails.
> > 
> > Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
> 
> Looks good,
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>

Thanks, but I need to fix this patch too.
The "if (q->nr_hw_queues != 1)" at the beginning of elevator_init_mq()
must be removed.

I am sending a v3 with this fix and a modified patch 5 to call
elevator_init_mq() earlier in device_add_disk().
diff mbox series

Patch

diff --git a/block/elevator.c b/block/elevator.c
index 2235dfe6755b..81d0877dbc34 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -665,9 +665,46 @@  static inline bool elv_support_iosched(struct request_queue *q)
 }
 
 /*
- * For blk-mq devices supporting IO scheduling, we default to using mq-deadline,
- * if available, for single queue devices. If deadline isn't available OR
- * deadline initialization fails OR we have multiple queues, default to "none".
+ * For single queue devices, default to using mq-deadline. If we have multiple
+ * queues or mq-deadline is not available, default to "none".
+ */
+static struct elevator_type *elevator_get_default(struct request_queue *q)
+{
+	if (q->nr_hw_queues != 1)
+		return NULL;
+
+	return elevator_get(q, "mq-deadline", false);
+}
+
+/*
+ * Get the first elevator providing the features required by the request queue.
+ * Default to "none" if no matching elevator is found.
+ */
+static struct elevator_type *elevator_get_by_features(struct request_queue *q)
+{
+	struct elevator_type *e;
+
+	spin_lock(&elv_list_lock);
+
+	list_for_each_entry(e, &elv_list, list) {
+		if (elv_support_features(e->elevator_features,
+					 q->required_elevator_features))
+			break;
+	}
+
+	if (e && !try_module_get(e->elevator_owner))
+		e = NULL;
+
+	spin_unlock(&elv_list_lock);
+
+	return e;
+}
+
+/*
+ * For a device queue that has no required features, use the default elevator
+ * settings. Otherwise, use the first elevator available matching the required
+ * features. If no suitable elevator is find or if the chosen elevator
+ * initialization fails, fall back to the "none" elevator (no elevator).
  */
 void elevator_init_mq(struct request_queue *q)
 {
@@ -685,7 +722,10 @@  void elevator_init_mq(struct request_queue *q)
 	if (unlikely(q->elevator))
 		return;
 
-	e = elevator_get(q, "mq-deadline", false);
+	if (!q->required_elevator_features)
+		e = elevator_get_default(q);
+	else
+		e = elevator_get_by_features(q);
 	if (!e)
 		return;