Patchwork [3.5.yuz,extended,stable] Patch "block: lift the initial queue bypass mode on" has been added to staging queue

mail settings
Submitter Herton Ronaldo Krzesinski
Date Nov. 15, 2012, 5:47 a.m.
Message ID <>
Download mbox | patch
Permalink /patch/199147/
State New
Headers show


Herton Ronaldo Krzesinski - Nov. 15, 2012, 5:47 a.m.
This is a note to let you know that I have just added a patch titled

    block: lift the initial queue bypass mode on

to the linux-3.5.y-queue branch of the 3.5.yuz extended stable tree 
which can be found at:;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.yuz tree, see



From 2a8340ff66cd0cf8c04f23a23646a96acfca5d48 Mon Sep 17 00:00:00 2001
From: Tejun Heo <>
Date: Thu, 20 Sep 2012 14:08:52 -0700
Subject: [PATCH] block: lift the initial queue bypass mode on
 blk_register_queue() instead of blk_init_allocated_queue()

commit 749fefe6778e98dfefe3b8bb72a93875196ec554 upstream.

b82d4b197c ("blkcg: make request_queue bypassing on allocation") made
request_queues bypassed on allocation to avoid switching on and off
bypass mode on a queue being initialized.  Some drivers allocate and
then destroy a lot of queues without fully initializing them and
incurring bypass latency overhead on each of them could add upto
significant overhead.

Unfortunately, blk_init_allocated_queue() is never used by queues of
bio-based drivers, which means that all bio-based driver queues are in
bypass mode even after initialization and registration complete

Due to the limited way request_queues are used by bio drivers, this
problem is hidden pretty well but it shows up when blk-throttle is
used in combination with a bio-based driver.  Trying to configure
(echoing to cgroupfs file) blk-throttle for a bio-based driver hangs
indefinitely in blkg_conf_prep() waiting for bypass mode to end.

This patch moves the initial blk_queue_bypass_end() call from
blk_init_allocated_queue() to blk_register_queue() which is called for
any userland-visible queues regardless of its type.

I believe this is correct because I don't think there is any block
driver which needs or wants working elevator and blk-cgroup on a queue
which isn't visible to userland.  If there are such users, we need a
different solution.

Signed-off-by: Tejun Heo <>
Reported-by: Joseph Glanville <>
Acked-by: Vivek Goyal <>
Signed-off-by: Jens Axboe <>
Signed-off-by: Herton Ronaldo Krzesinski <>
 block/blk-core.c  |    7 ++-----
 block/blk-sysfs.c |    6 ++++++
 2 files changed, 8 insertions(+), 5 deletions(-)



diff --git a/block/blk-core.c b/block/blk-core.c
index ad39394..96335a7 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -598,8 +598,8 @@  struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
 	 * A queue starts its life with bypass turned on to avoid
 	 * unnecessary bypass on/off overhead and nasty surprises during
-	 * init.  The initial bypass will be finished at the end of
-	 * blk_init_allocated_queue().
+	 * init.  The initial bypass will be finished when the queue is
+	 * registered by blk_register_queue().
 	q->bypass_depth = 1;
 	__set_bit(QUEUE_FLAG_BYPASS, &q->queue_flags);
@@ -702,9 +702,6 @@  blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn,
 	/* init elevator */
 	if (elevator_init(q, NULL))
 		return NULL;
-	/* all done, end the initial bypass */
-	blk_queue_bypass_end(q);
 	return q;
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index aa41b47..be7edfc 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -523,6 +523,12 @@  int blk_register_queue(struct gendisk *disk)
 	if (WARN_ON(!q))
 		return -ENXIO;

+	/*
+	 * Initialization must be complete by now.  Finish the initial
+	 * bypass from queue allocation.
+	 */
+	blk_queue_bypass_end(q);
 	ret = blk_trace_init_sysfs(dev);
 	if (ret)
 		return ret;