Merge branch 'for-linus' of git://git.kernel.dk/linux-block
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 16 Dec 2014 01:25:20 +0000 (17:25 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 16 Dec 2014 01:25:20 +0000 (17:25 -0800)
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()"

block/blk-mq-tag.c

index e3d4e40..32e8dbb 100644 (file)
@@ -248,8 +248,8 @@ static int bt_get(struct blk_mq_alloc_data *data,
        if (!(data->gfp & __GFP_WAIT))
                return -1;
 
+       bs = bt_wait_ptr(bt, hctx);
        do {
-               bs = bt_wait_ptr(bt, hctx);
                prepare_to_wait(&bs->wait, &wait, TASK_UNINTERRUPTIBLE);
 
                tag = __bt_get(hctx, bt, last_tag);
@@ -285,6 +285,8 @@ static int bt_get(struct blk_mq_alloc_data *data,
                        hctx = data->hctx;
                        bt = &hctx->tags->bitmap_tags;
                }
+               finish_wait(&bs->wait, &wait);
+               bs = bt_wait_ptr(bt, hctx);
        } while (1);
 
        finish_wait(&bs->wait, &wait);