Patchwork [3.5.y.z,extended,stable] Patch "block: Don't access request after it might be freed" has been added to staging queue

mail settings
Submitter Herton Ronaldo Krzesinski
Date Dec. 10, 2012, 2:20 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/204921/
State New
Headers show


Herton Ronaldo Krzesinski - Dec. 10, 2012, 2:20 p.m.
This is a note to let you know that I have just added a patch titled

    block: Don't access request after it might be freed

to the linux-3.5.y-queue branch of the 3.5.y.z 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.y.z tree, see



From ee5cf30456f95be755b0e6502132c535903aa89f Mon Sep 17 00:00:00 2001
From: Roland Dreier <>
Date: Thu, 22 Nov 2012 02:00:11 -0800
Subject: [PATCH] block: Don't access request after it might be freed

commit 893d290f1d7496db97c9471bc352ad4a11dc8a25 upstream.

After we've done __elv_add_request() and __blk_run_queue() in
blk_execute_rq_nowait(), the request might finish and be freed
immediately.  Therefore checking if the type is REQ_TYPE_PM_RESUME
isn't safe afterwards, because if it isn't, rq might be gone.
Instead, check beforehand and stash the result in a temporary.

This fixes crashes in blk_execute_rq_nowait() I get occasionally when
running with lots of memory debugging options enabled -- I think this
race is usually harmless because the window for rq to be reallocated
is so small.

Signed-off-by: Roland Dreier <>
Signed-off-by: Jens Axboe <>
[ herton: adjust context ]
Signed-off-by: Herton Ronaldo Krzesinski <>
 block/blk-exec.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)



diff --git a/block/blk-exec.c b/block/blk-exec.c
index fb2cbd5..9925fbe 100644
--- a/block/blk-exec.c
+++ b/block/blk-exec.c
@@ -49,8 +49,16 @@  void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
 			   rq_end_io_fn *done)
+	bool is_pm_resume;

+	/*
+	 * need to check this before __blk_run_queue(), because rq can
+	 * be freed before that returns.
+	 */
+	is_pm_resume = rq->cmd_type == REQ_TYPE_PM_RESUME;

 	if (unlikely(blk_queue_dead(q))) {
@@ -66,7 +74,7 @@  void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
 	__elv_add_request(q, rq, where);
 	/* the queue is stopped so it won't be run */
-	if (rq->cmd_type == REQ_TYPE_PM_RESUME)
+	if (is_pm_resume)