From f42073eeb92fd4d680c249c2186b6c18d961ae7b Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Mon, 16 Sep 2019 17:20:46 +0800 Subject: [PATCH] rq-qos: fix missed wake-ups in rq_qos_throttle mainline inclusion from mainline-5.3-rc2 commit 545fbd0775bafcefc8f7bc844291bd13c44b7fdc category: bugfix bugzilla: 21211 CVE: NA --------------------------- We saw a hang in production with WBT where there was only one waiter in the throttle path and no outstanding IO. This is because of the has_sleepers optimization that is used to make sure we don't steal an inflight counter for new submitters when there are people already on the list. We can race with our check to see if the waitqueue has any waiters (this is done locklessly) and the time we actually add ourselves to the waitqueue. If this happens we'll go to sleep and never be woken up because nobody is doing IO to wake us up. Fix this by checking if the waitqueue has a single sleeper on the list after we add ourselves, that way we have an uptodate view of the list. Reviewed-by: Oleg Nesterov Signed-off-by: Josef Bacik Signed-off-by: Jens Axboe Conflicts: block/blk-rq-qos.c [yan: __wbt_wait() has not been turned into rq_qos_wait() yet.] Signed-off-by: Jason Yan Reviewed-by: Yufen Yu Signed-off-by: Yang Yingliang --- block/blk-wbt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/blk-wbt.c b/block/blk-wbt.c index 0c62bf4eca75..4a279d27e1c1 100644 --- a/block/blk-wbt.c +++ b/block/blk-wbt.c @@ -543,6 +543,7 @@ static void __wbt_wait(struct rq_wb *rwb, enum wbt_flags wb_acct, return; prepare_to_wait_exclusive(&rqw->wait, &data.wq, TASK_UNINTERRUPTIBLE); + has_sleeper = !wq_has_single_sleeper(&rqw->wait); do { if (data.got_token) break; -- GitLab