Commit 17d5c8ca authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Jens Axboe

block: fix intermittent dm timeout based oops

Very rarely under stress testing of dm, oopses are occuring as
something tampers with an old stack frame.  This has been traced back
to blk_abort_queue() leaving a timeout_list pointing to the stack.
The reason is that sometimes blk_abort_request() won't delete the
timer (if the request is marked as complete but before the timer has
been removed, a small race window).  Fix this by splicing back from
the ususally empty list to the q->timeout_list.
Signed-off-by: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent f3c737de
...@@ -230,6 +230,13 @@ void blk_abort_queue(struct request_queue *q) ...@@ -230,6 +230,13 @@ void blk_abort_queue(struct request_queue *q)
list_for_each_entry_safe(rq, tmp, &list, timeout_list) list_for_each_entry_safe(rq, tmp, &list, timeout_list)
blk_abort_request(rq); blk_abort_request(rq);
/*
* Occasionally, blk_abort_request() will return without
* deleting the element from the list. Make sure we add those back
* instead of leaving them on the local stack list.
*/
list_splice(&list, &q->timeout_list);
spin_unlock_irqrestore(q->queue_lock, flags); spin_unlock_irqrestore(q->queue_lock, flags);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment