public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Vivek Goyal <vgoyal@redhat.com>
To: linux-kernel@vger.kernel.org, jaxboe@fusionio.com
Cc: vgoyal@redhat.com, neilb@suse.de
Subject: [PATCH 3/3] block: Move blk_throtl_exit() call to blk_cleanup_queue()
Date: Mon, 28 Feb 2011 14:25:30 -0500	[thread overview]
Message-ID: <1298921130-17533-4-git-send-email-vgoyal@redhat.com> (raw)
In-Reply-To: <1298921130-17533-1-git-send-email-vgoyal@redhat.com>

o Move blk_throtl_exit() in blk_cleanup_queue() as blk_throtl_exit() is
  written in such a way that it needs queue lock. In blk_release_queue()
  there is no gurantee that ->queue_lock is still around.

o Initially blk_throtl_exit() was in blk_cleanup_queue() but Ingo reported
  one problem.

  https://lkml.org/lkml/2010/10/23/86

  And a quick fix moved blk_throtl_exit() to blk_release_queue().

        commit 7ad58c028652753814054f4e3ac58f925e7343f4
        Author: Jens Axboe <jaxboe@fusionio.com>
        Date:   Sat Oct 23 20:40:26 2010 +0200

        block: fix use-after-free bug in blk throttle code

o This patch reverts above change and does not try to shutdown the
  throtl work in blk_sync_queue(). By avoiding call to
  throtl_shutdown_timer_wq() from blk_sync_queue(), we should also avoid
  the problem reported by Ingo.

o blk_sync_queue() seems to be used only by md driver and it seems to be
  using it to make sure q->unplug_fn is not called as md registers its
  own unplug functions and it is about to free up the data structures
  used by unplug_fn(). Block throttle does not call back into unplug_fn()
  or into md. So there is no need to cancel blk throttle work.

  In fact I think cancelling block throttle work is bad because it might
  happen that some bios are throttled and scheduled to be dispatched later
  with the help of pending work and if work is cancelled, these bios might
  never be dispatched.

  Block layer also uses blk_sync_queue() during blk_cleanup_queue() and
  blk_release_queue() time. That should be safe as we are also calling
  blk_throtl_exit() which should make sure all the throttling related
  data structures are cleaned up.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
---
 block/blk-core.c       |    7 ++++++-
 block/blk-sysfs.c      |    2 --
 block/blk-throttle.c   |    6 +++---
 include/linux/blkdev.h |    2 --
 4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index bc2b7c5..accff29 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -380,13 +380,16 @@ EXPORT_SYMBOL(blk_stop_queue);
  *     that its ->make_request_fn will not re-add plugging prior to calling
  *     this function.
  *
+ *     This function does not cancel any asynchronous activity arising
+ *     out of elevator or throttling code. That would require elevaotor_exit()
+ *     and blk_throtl_exit() to be called with queue lock initialized.
+ *
  */
 void blk_sync_queue(struct request_queue *q)
 {
 	del_timer_sync(&q->unplug_timer);
 	del_timer_sync(&q->timeout);
 	cancel_work_sync(&q->unplug_work);
-	throtl_shutdown_timer_wq(q);
 }
 EXPORT_SYMBOL(blk_sync_queue);
 
@@ -469,6 +472,8 @@ void blk_cleanup_queue(struct request_queue *q)
 	if (q->elevator)
 		elevator_exit(q->elevator);
 
+	blk_throtl_exit(q);
+
 	blk_put_queue(q);
 }
 EXPORT_SYMBOL(blk_cleanup_queue);
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 41fb691..261c75c 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -471,8 +471,6 @@ static void blk_release_queue(struct kobject *kobj)
 
 	blk_sync_queue(q);
 
-	blk_throtl_exit(q);
-
 	if (rl->rq_pool)
 		mempool_destroy(rl->rq_pool);
 
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index a89043a..c0f6237 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -965,7 +965,7 @@ static void throtl_update_blkio_group_write_iops(void *key,
 	throtl_schedule_delayed_work(td->queue, 0);
 }
 
-void throtl_shutdown_timer_wq(struct request_queue *q)
+static void throtl_shutdown_wq(struct request_queue *q)
 {
 	struct throtl_data *td = q->td;
 
@@ -1099,7 +1099,7 @@ void blk_throtl_exit(struct request_queue *q)
 
 	BUG_ON(!td);
 
-	throtl_shutdown_timer_wq(q);
+	throtl_shutdown_wq(q);
 
 	spin_lock_irq(q->queue_lock);
 	throtl_release_tgs(td);
@@ -1129,7 +1129,7 @@ void blk_throtl_exit(struct request_queue *q)
 	 * update limits through cgroup and another work got queued, cancel
 	 * it.
 	 */
-	throtl_shutdown_timer_wq(q);
+	throtl_shutdown_wq(q);
 	throtl_td_free(td);
 }
 
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index e3ee74f..23fb925 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1144,7 +1144,6 @@ extern int blk_throtl_init(struct request_queue *q);
 extern void blk_throtl_exit(struct request_queue *q);
 extern int blk_throtl_bio(struct request_queue *q, struct bio **bio);
 extern void throtl_schedule_delayed_work(struct request_queue *q, unsigned long delay);
-extern void throtl_shutdown_timer_wq(struct request_queue *q);
 #else /* CONFIG_BLK_DEV_THROTTLING */
 static inline int blk_throtl_bio(struct request_queue *q, struct bio **bio)
 {
@@ -1154,7 +1153,6 @@ static inline int blk_throtl_bio(struct request_queue *q, struct bio **bio)
 static inline int blk_throtl_init(struct request_queue *q) { return 0; }
 static inline int blk_throtl_exit(struct request_queue *q) { return 0; }
 static inline void throtl_schedule_delayed_work(struct request_queue *q, unsigned long delay) {}
-static inline void throtl_shutdown_timer_wq(struct request_queue *q) {}
 #endif /* CONFIG_BLK_DEV_THROTTLING */
 
 #define MODULE_ALIAS_BLOCKDEV(major,minor) \
-- 
1.7.2.3


  parent reply	other threads:[~2011-02-28 19:25 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-28 19:25 [PATCH 0/3] block: Few fixes for throttle and blk_cleanup_queue() Vivek Goyal
2011-02-28 19:25 ` [PATCH 1/3] block: Initialize ->queue_lock to internal lock at queue allocation time Vivek Goyal
2011-02-28 19:25 ` [PATCH 2/3] loop: No need to initialize ->queue_lock explicitly before calling blk_cleanup_queue() Vivek Goyal
2011-02-28 19:25 ` Vivek Goyal [this message]
2011-03-02 23:57 ` [PATCH 0/3] block: Few fixes for throttle and blk_cleanup_queue() Jens Axboe
2011-03-03  0:09   ` Vivek Goyal
2011-03-03  0:11     ` Jens Axboe
  -- strict thread matches above, loose matches on Subject: below --
2011-02-22  3:53 [PATCH 0/3] [RFC] block: Enforce that ->queue_lock is initialized during call to blk_cleanup_queue() Vivek Goyal
2011-02-22  3:53 ` [PATCH 3/3] block: Move blk_throtl_exit() " Vivek Goyal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1298921130-17533-4-git-send-email-vgoyal@redhat.com \
    --to=vgoyal@redhat.com \
    --cc=jaxboe@fusionio.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=neilb@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox