Skip to content

Commit e861857

Browse files
committedMar 25, 2019
blk-mq: fix sbitmap ws_active for shared tags
We now wrap sbitmap waitqueues in an active counter, so we can avoid iterating wakeups unless we have waiters there. This works as long as everyone that's manipulating the waitqueues use the proper helpers. For the tag wait case for shared tags, however, we add ourselves to the waitqueue without incrementing/decrementing the ->ws_active count. This means that wakeups can take a long time to happen. Fix this by manually doing the inc/dec as needed for the wait queue handling. Reported-by: Michael Leun <kbug@newton.leun.net> Tested-by: Michael Leun <kbug@newton.leun.net> Cc: stable@vger.kernel.org Reviewed-by: Omar Sandoval <osandov@fb.com> Fixes: 5d2ee71 ("sbitmap: optimize wakeup check") Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 9e75ad5 commit e861857

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed
 

‎block/blk-mq.c

+11-2
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,13 @@ static int blk_mq_dispatch_wake(wait_queue_entry_t *wait, unsigned mode,
10721072
hctx = container_of(wait, struct blk_mq_hw_ctx, dispatch_wait);
10731073

10741074
spin_lock(&hctx->dispatch_wait_lock);
1075-
list_del_init(&wait->entry);
1075+
if (!list_empty(&wait->entry)) {
1076+
struct sbitmap_queue *sbq;
1077+
1078+
list_del_init(&wait->entry);
1079+
sbq = &hctx->tags->bitmap_tags;
1080+
atomic_dec(&sbq->ws_active);
1081+
}
10761082
spin_unlock(&hctx->dispatch_wait_lock);
10771083

10781084
blk_mq_run_hw_queue(hctx, true);
@@ -1088,6 +1094,7 @@ static int blk_mq_dispatch_wake(wait_queue_entry_t *wait, unsigned mode,
10881094
static bool blk_mq_mark_tag_wait(struct blk_mq_hw_ctx *hctx,
10891095
struct request *rq)
10901096
{
1097+
struct sbitmap_queue *sbq = &hctx->tags->bitmap_tags;
10911098
struct wait_queue_head *wq;
10921099
wait_queue_entry_t *wait;
10931100
bool ret;
@@ -1110,7 +1117,7 @@ static bool blk_mq_mark_tag_wait(struct blk_mq_hw_ctx *hctx,
11101117
if (!list_empty_careful(&wait->entry))
11111118
return false;
11121119

1113-
wq = &bt_wait_ptr(&hctx->tags->bitmap_tags, hctx)->wait;
1120+
wq = &bt_wait_ptr(sbq, hctx)->wait;
11141121

11151122
spin_lock_irq(&wq->lock);
11161123
spin_lock(&hctx->dispatch_wait_lock);
@@ -1120,6 +1127,7 @@ static bool blk_mq_mark_tag_wait(struct blk_mq_hw_ctx *hctx,
11201127
return false;
11211128
}
11221129

1130+
atomic_inc(&sbq->ws_active);
11231131
wait->flags &= ~WQ_FLAG_EXCLUSIVE;
11241132
__add_wait_queue(wq, wait);
11251133

@@ -1140,6 +1148,7 @@ static bool blk_mq_mark_tag_wait(struct blk_mq_hw_ctx *hctx,
11401148
* someone else gets the wakeup.
11411149
*/
11421150
list_del_init(&wait->entry);
1151+
atomic_dec(&sbq->ws_active);
11431152
spin_unlock(&hctx->dispatch_wait_lock);
11441153
spin_unlock_irq(&wq->lock);
11451154

0 commit comments

Comments
 (0)
Please sign in to comment.