block: Don't access request after it might be freed
PATCH 1/1 block: Don't access request after it might be freed
From: Roland Dreier <[email protected]>
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.
--- block/blk-exec.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
block/blk-exec.c +7 -1
@@ -52,11 +52,17 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, rq_end_io_fn *done) {int where = at_head ?ELEVATOR_INSERT_FRONT :ELEVATOR_INSERT_BACK ; +bool is_pm_resume;WARN_ON (irqs_disabled ()); rq->rq_disk = bd_disk; rq->end_io = done; +/* +* 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 ;spin_lock_irq (q->queue_lock);
@@ -71,7 +77,7 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,__elv_add_request (q, rq, where);__blk_run_queue (q);/* the queue is stopped so it won't be run */ -if (rq->cmd_type ==REQ_TYPE_PM_RESUME ) +if (is_pm_resume) q->request_fn (q);spin_unlock_irq (q->queue_lock); }
Signature · 1 line
1.7.10.4
Jens Axboe
maintainerQuoted 8 lines · Roland Dreier
From: Roland Dreier <[email protected]>
After we've done
__elv_add_request()and__blk_run_queue()inblk_execute_rq_nowait(), the request might finish and be freed immediately. Therefore checking if the type isREQ_TYPE_PM_RESUMEisn't safe afterwards, because if it isn't, rq might be gone. Instead, check beforehand and stash the result in a temporary.
Quoted 4 lines
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.
Thanks Roland, that's obviously a bug, not safe to touch the request even after insertion, let alone running the queue. Applied.
Signature · 1 line
Jens Axboe