diff options
author | Alexander Gordeev <agordeev@redhat.com> | 2014-06-17 16:37:23 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-06-18 01:13:08 -0400 |
commit | 86fb5c56cfa26de5e91c9a50e2767a695dff366e (patch) | |
tree | da76443281fb15c54d56400b25ff9279e0b9e33e | |
parent | 2971c35f35886b87af54675313a2afef937c1b0c (diff) |
blk-mq: bitmap tag: fix races in bt_get() function
This update fixes few issues in bt_get() function:
- list_empty(&wait.task_list) check is not protected;
- was_empty check is always true which results in *every* thread
entering the loop resets bt_wait_state::wait_cnt counter rather
than every bt->wake_cnt'th thread;
- 'bt_wait_state::wait_cnt' counter update is redundant, since
it also gets reset in bt_clear_tag() function;
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Ming Lei <tom.leiming@gmail.com>
Cc: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r-- | block/blk-mq-tag.c | 13 |
1 files changed, 5 insertions, 8 deletions
diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c index 08fc6716d362..c1b92426c95e 100644 --- a/block/blk-mq-tag.c +++ b/block/blk-mq-tag.c | |||
@@ -248,18 +248,12 @@ static int bt_get(struct blk_mq_alloc_data *data, | |||
248 | 248 | ||
249 | bs = bt_wait_ptr(bt, hctx); | 249 | bs = bt_wait_ptr(bt, hctx); |
250 | do { | 250 | do { |
251 | bool was_empty; | ||
252 | |||
253 | was_empty = list_empty(&wait.task_list); | ||
254 | prepare_to_wait(&bs->wait, &wait, TASK_UNINTERRUPTIBLE); | 251 | prepare_to_wait(&bs->wait, &wait, TASK_UNINTERRUPTIBLE); |
255 | 252 | ||
256 | tag = __bt_get(hctx, bt, last_tag); | 253 | tag = __bt_get(hctx, bt, last_tag); |
257 | if (tag != -1) | 254 | if (tag != -1) |
258 | break; | 255 | break; |
259 | 256 | ||
260 | if (was_empty) | ||
261 | atomic_set(&bs->wait_cnt, bt->wake_cnt); | ||
262 | |||
263 | blk_mq_put_ctx(data->ctx); | 257 | blk_mq_put_ctx(data->ctx); |
264 | 258 | ||
265 | io_schedule(); | 259 | io_schedule(); |
@@ -519,10 +513,13 @@ static int bt_alloc(struct blk_mq_bitmap_tags *bt, unsigned int depth, | |||
519 | return -ENOMEM; | 513 | return -ENOMEM; |
520 | } | 514 | } |
521 | 515 | ||
522 | for (i = 0; i < BT_WAIT_QUEUES; i++) | 516 | bt_update_count(bt, depth); |
517 | |||
518 | for (i = 0; i < BT_WAIT_QUEUES; i++) { | ||
523 | init_waitqueue_head(&bt->bs[i].wait); | 519 | init_waitqueue_head(&bt->bs[i].wait); |
520 | atomic_set(&bt->bs[i].wait_cnt, bt->wake_cnt); | ||
521 | } | ||
524 | 522 | ||
525 | bt_update_count(bt, depth); | ||
526 | return 0; | 523 | return 0; |
527 | } | 524 | } |
528 | 525 | ||