| From 976570b4ecd30d3ec6e1b0910da8e5edc591f2b6 Mon Sep 17 00:00:00 2001 |
| From: Gabriel Krisman Bertazi <krisman@suse.de> |
| Date: Tue, 15 Nov 2022 17:45:51 -0500 |
| Subject: sbitmap: Advance the queue index before waking up a queue |
| |
| From: Gabriel Krisman Bertazi <krisman@suse.de> |
| |
| commit 976570b4ecd30d3ec6e1b0910da8e5edc591f2b6 upstream. |
| |
| When a queue is awaken, the wake_index written by sbq_wake_ptr currently |
| keeps pointing to the same queue. On the next wake up, it will thus |
| retry the same queue, which is unfair to other queues, and can lead to |
| starvation. This patch, moves the index update to happen before the |
| queue is returned, such that it will now try a different queue first on |
| the next wake up, improving fairness. |
| |
| Fixes: 4f8126bb2308 ("sbitmap: Use single per-bitmap counting to wake up queued tags") |
| Reported-by: Jan Kara <jack@suse.cz> |
| Reviewed-by: Jan Kara <jack@suse.cz> |
| Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de> |
| Link: https://lore.kernel.org/r/20221115224553.23594-2-krisman@suse.de |
| Signed-off-by: Jens Axboe <axboe@kernel.dk> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| lib/sbitmap.c | 10 ++++++++-- |
| 1 file changed, 8 insertions(+), 2 deletions(-) |
| |
| --- a/lib/sbitmap.c |
| +++ b/lib/sbitmap.c |
| @@ -566,13 +566,19 @@ static struct sbq_wait_state *sbq_wake_p |
| for (i = 0; i < SBQ_WAIT_QUEUES; i++) { |
| struct sbq_wait_state *ws = &sbq->ws[wake_index]; |
| |
| + /* |
| + * Advance the index before checking the current queue. |
| + * It improves fairness, by ensuring the queue doesn't |
| + * need to be fully emptied before trying to wake up |
| + * from the next one. |
| + */ |
| + wake_index = sbq_index_inc(wake_index); |
| + |
| if (waitqueue_active(&ws->wait)) { |
| if (wake_index != atomic_read(&sbq->wake_index)) |
| atomic_set(&sbq->wake_index, wake_index); |
| return ws; |
| } |
| - |
| - wake_index = sbq_index_inc(wake_index); |
| } |
| |
| return NULL; |