aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-15 20:25:20 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-15 20:25:20 -0500
commit9b8ec916df67ba31614796037caf606b763e2e79 (patch)
tree686e3d85b8c5af57d54265354ffab61f4803856e
parent27cb8823e26cecd03c00d82dfb501f6c144b3445 (diff)
parent35d37c66356eed46700e0d5db87211844d43a241 (diff)
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Pull core block fix from Jens Axboe: "Jan reported a problem this morning with a crash in blk-mq, and after looking over the recent changes, it's obvious that the blk-mq-tag waitqueue handling change is buggy. We could end up _not_ doing finish_wait() before switching to a new waitqueue, thus corrupting the wait task list" * 'for-linus' of git://git.kernel.dk/linux-block: Revert "blk-mq: Micro-optimize bt_get()"
-rw-r--r--block/blk-mq-tag.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
index e3d4e4043b49..32e8dbb9ad1c 100644
--- a/block/blk-mq-tag.c
+++ b/block/blk-mq-tag.c
@@ -248,8 +248,8 @@ static int bt_get(struct blk_mq_alloc_data *data,
248 if (!(data->gfp & __GFP_WAIT)) 248 if (!(data->gfp & __GFP_WAIT))
249 return -1; 249 return -1;
250 250
251 bs = bt_wait_ptr(bt, hctx);
251 do { 252 do {
252 bs = bt_wait_ptr(bt, hctx);
253 prepare_to_wait(&bs->wait, &wait, TASK_UNINTERRUPTIBLE); 253 prepare_to_wait(&bs->wait, &wait, TASK_UNINTERRUPTIBLE);
254 254
255 tag = __bt_get(hctx, bt, last_tag); 255 tag = __bt_get(hctx, bt, last_tag);
@@ -285,6 +285,8 @@ static int bt_get(struct blk_mq_alloc_data *data,
285 hctx = data->hctx; 285 hctx = data->hctx;
286 bt = &hctx->tags->bitmap_tags; 286 bt = &hctx->tags->bitmap_tags;
287 } 287 }
288 finish_wait(&bs->wait, &wait);
289 bs = bt_wait_ptr(bt, hctx);
288 } while (1); 290 } while (1);
289 291
290 finish_wait(&bs->wait, &wait); 292 finish_wait(&bs->wait, &wait);