23d72c6
If there are too many pending per work I/O, too many
23d72c6
high priority work thread can be generated so that
23d72c6
system performance can be effected.
23d72c6
23d72c6
This patch limits the max pending per work I/O as 16,
23d72c6
and will fackback to single queue mode when the max
23d72c6
number is reached.
23d72c6
23d72c6
This patch fixes Fedora 22 live booting performance
23d72c6
regression when it is booted from squashfs over dm
23d72c6
based on loop, and looks the following reasons are
23d72c6
related with the problem:
23d72c6
23d72c6
- not like other filesyststems(such as ext4), squashfs
23d72c6
is a bit special, and I observed that increasing I/O jobs
23d72c6
to access file in squashfs only improve I/O performance a
23d72c6
little, but it can make big difference for ext4
23d72c6
23d72c6
- nested loop: both squashfs.img and ext3fs.img are mounted
23d72c6
as loop block, and ext3fs.img is inside the squashfs
23d72c6
23d72c6
- during booting, lots of tasks may run concurrently
23d72c6
23d72c6
Fixes: b5dd2f6047ca108001328aac0e8588edd15f1778
23d72c6
Cc: stable@vger.kernel.org (v4.0)
23d72c6
Reported-by: Justin M. Forbes <jforbes@fedoraproject.org>
23d72c6
Tested-by: Justin M. Forbes <jforbes@fedoraproject.org>
23d72c6
Signed-off-by: Ming Lei <ming.lei@canonical.com>
23d72c6
---
23d72c6
 drivers/block/loop.c | 19 +++++++++++++++++--
23d72c6
 drivers/block/loop.h |  2 ++
23d72c6
 2 files changed, 19 insertions(+), 2 deletions(-)
23d72c6
23d72c6
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
64752e5
index ae3fcb4..5a728c6 100644
23d72c6
--- a/drivers/block/loop.c
23d72c6
+++ b/drivers/block/loop.c
23d72c6
@@ -1425,13 +1425,24 @@ static int loop_queue_rq(struct blk_mq_hw_ctx *hctx,
23d72c6
 		const struct blk_mq_queue_data *bd)
23d72c6
 {
23d72c6
 	struct loop_cmd *cmd = blk_mq_rq_to_pdu(bd->rq);
23d72c6
+	struct loop_device *lo = cmd->rq->q->queuedata;
23d72c6
+	bool single_queue = !!(cmd->rq->cmd_flags & REQ_WRITE);
23d72c6
+
23d72c6
+	/*
23d72c6
+	 * Fallback to single queue mode if the pending per work
64752e5
+	 * I/O number reaches 16, otherwise too many high priority
23d72c6
+	 * worker thread may effect system performance as reported
23d72c6
+	 * in fedora live booting from squashfs over loop.
23d72c6
+	 */
64752e5
+	if (atomic_read(&lo->pending_per_work_io) >= 16)
23d72c6
+		single_queue = true;
23d72c6
 
23d72c6
 	blk_mq_start_request(bd->rq);
23d72c6
 
23d72c6
-	if (cmd->rq->cmd_flags & REQ_WRITE) {
23d72c6
-		struct loop_device *lo = cmd->rq->q->queuedata;
23d72c6
+	if (single_queue) {
23d72c6
 		bool need_sched = true;
23d72c6
 
23d72c6
+		cmd->per_work_io = false;
23d72c6
 		spin_lock_irq(&lo->lo_lock);
23d72c6
 		if (lo->write_started)
23d72c6
 			need_sched = false;
23d72c6
@@ -1443,6 +1454,8 @@ static int loop_queue_rq(struct blk_mq_hw_ctx *hctx,
23d72c6
 		if (need_sched)
23d72c6
 			queue_work(loop_wq, &lo->write_work);
23d72c6
 	} else {
23d72c6
+		atomic_inc(&lo->pending_per_work_io);
64752e5
+		cmd->per_work_io = true;
23d72c6
 		queue_work(loop_wq, &cmd->read_work);
23d72c6
 	}
23d72c6
 
23d72c6
@@ -1467,6 +1480,8 @@ static void loop_handle_cmd(struct loop_cmd *cmd)
23d72c6
 	if (ret)
23d72c6
 		cmd->rq->errors = -EIO;
23d72c6
 	blk_mq_complete_request(cmd->rq);
23d72c6
+	if (cmd->per_work_io)
23d72c6
+		atomic_dec(&lo->pending_per_work_io);
23d72c6
 }
23d72c6
 
23d72c6
 static void loop_queue_write_work(struct work_struct *work)
23d72c6
diff --git a/drivers/block/loop.h b/drivers/block/loop.h
23d72c6
index 301c27f..eb855f5 100644
23d72c6
--- a/drivers/block/loop.h
23d72c6
+++ b/drivers/block/loop.h
23d72c6
@@ -57,6 +57,7 @@ struct loop_device {
23d72c6
 	struct list_head	write_cmd_head;
23d72c6
 	struct work_struct	write_work;
23d72c6
 	bool			write_started;
23d72c6
+	atomic_t		pending_per_work_io;
23d72c6
 	int			lo_state;
23d72c6
 	struct mutex		lo_ctl_mutex;
23d72c6
 
23d72c6
@@ -68,6 +69,7 @@ struct loop_device {
23d72c6
 struct loop_cmd {
23d72c6
 	struct work_struct read_work;
23d72c6
 	struct request *rq;
23d72c6
+	bool per_work_io;
23d72c6
 	struct list_head list;
23d72c6
 };
23d72c6
 
23d72c6
-- 
23d72c6
1.9.1