[RFC PATCH] blk-mq: set the default elevator type to none if nr_hw_queues > 1

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Xiubo Li <xiubli@xxxxxxxxxx>

For the nbd device, firstly it will be initialized as single hardware
queue, and then in add_disk() the elevator will set to mq-deadline.

But if there more than one socket connections, then the hardware
queus will be increased and will equal to the socket connection
numners. In this case shouldn't we set it back to none as default ?

If the user space daemon has changed the elevator type or the drivers
has specified the elevator feature, we will set it back anyway.

Signed-off-by: Xiubo Li <xiubli@xxxxxxxxxx>
---
 block/blk-mq.c         | 19 +++++++++++++++++--
 block/blk.h            |  1 +
 block/elevator.c       |  6 ++++--
 include/linux/blkdev.h |  2 ++
 4 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 8cdc747d5c4d..1be9e416bfd8 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -3242,7 +3242,7 @@ static void blk_mq_elv_switch_back(struct list_head *head,
 		struct request_queue *q)
 {
 	struct blk_mq_qe_pair *qe;
-	struct elevator_type *t = NULL;
+	struct elevator_type *t = NULL, *e;
 
 	list_for_each_entry(qe, head, node)
 		if (qe->q == q) {
@@ -3257,7 +3257,22 @@ static void blk_mq_elv_switch_back(struct list_head *head,
 	kfree(qe);
 
 	mutex_lock(&q->sysfs_lock);
-	elevator_switch_mq(q, t);
+	/*
+	 * If the elevator type has been touched by user space daemon
+	 * we will switch it back to the previous one anyway.
+	 *
+	 * Or will set it as default depending on the new hw queue number,
+	 * if will keep the elv type to none then we need to put the moudle.
+	 */
+	if (q->elv_user_touched || q->required_elevator_features) {
+		elevator_switch_mq(q, t);
+	} else {
+		e = elevator_get_default(q);
+		if (e)
+			elevator_switch_mq(q, e);
+		else
+			module_put(t->elevator_owner);
+	}
 	mutex_unlock(&q->sysfs_lock);
 }
 
diff --git a/block/blk.h b/block/blk.h
index ed347f7a97b1..43021b87b953 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -190,6 +190,7 @@ int elevator_switch_mq(struct request_queue *q,
 void __elevator_exit(struct request_queue *, struct elevator_queue *);
 int elv_register_queue(struct request_queue *q, bool uevent);
 void elv_unregister_queue(struct request_queue *q);
+struct elevator_type *elevator_get_default(struct request_queue *q);
 
 static inline void elevator_exit(struct request_queue *q,
 		struct elevator_queue *e)
diff --git a/block/elevator.c b/block/elevator.c
index bba10e83478a..14bfcb1b19b3 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -654,7 +654,7 @@ static inline bool elv_support_iosched(struct request_queue *q)
  * 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)
+struct elevator_type *elevator_get_default(struct request_queue *q)
 {
 	if (q->nr_hw_queues != 1)
 		return NULL;
@@ -796,8 +796,10 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name,
 		return count;
 
 	ret = __elevator_change(q, name);
-	if (!ret)
+	if (!ret) {
+		q->elv_user_touched = true;
 		return count;
+	}
 
 	return ret;
 }
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index b196124e3240..a03b8ea5916d 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -587,6 +587,8 @@ struct request_queue {
 
 #define BLK_MAX_WRITE_HINTS	5
 	u64			write_hints[BLK_MAX_WRITE_HINTS];
+
+	bool			elv_user_touched;
 };
 
 #define QUEUE_FLAG_STOPPED	0	/* queue is stopped */
-- 
2.21.0




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux