diff options
author | Jens Axboe <axboe@fb.com> | 2014-12-15 10:30:26 -0500 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-12-15 10:30:26 -0500 |
commit | 35d37c66356eed46700e0d5db87211844d43a241 (patch) | |
tree | 6bfdbddaf04501ac9edcf6c526e1e54dd00444b8 | |
parent | 67e2c3883828b39548cee2091b36656787775d95 (diff) |
Revert "blk-mq: Micro-optimize bt_get()"
This reverts commit 52f7eb945f2ba62b324bb9ae16d945326a961dcf.
The optimization is only really safe for a single queue, otherwise
'bs' and 'bt' can indeed change, and if we don't do a finish_wait()
for each loop, we'll potentially change the wait structure and
corrupt task wait list.
Reported-by: Jan Kara <jack@suse.cz>
-rw-r--r-- | block/blk-mq-tag.c | 4 |
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); |