summaryrefslogtreecommitdiff
path: root/fs/io-wq.c
diff options
context:
space:
mode:
authorBeld Zhang <beldzhang@gmail.com>2021-11-02 21:32:08 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-11-18 21:17:05 +0300
commitcd63d080b9e88e9903f4466f79def4ddec072d2e (patch)
treee69289c0026ca7419253297b46e19b8136d31dae /fs/io-wq.c
parente99270d7f2731f532831923b9dd35b7be79158fe (diff)
downloadlinux-cd63d080b9e88e9903f4466f79def4ddec072d2e.tar.xz
io-wq: fix max-workers not correctly set on multi-node system
[ Upstream commit 71c9ce27bb57c59d8d7f5298e730c8096eef3d1f ] In io-wq.c:io_wq_max_workers(), new_count[] was changed right after each node's value was set. This caused the following node getting the setting of the previous one. Returned values are copied from node 0. Fixes: 2e480058ddc2 ("io-wq: provide a way to limit max number of workers") Signed-off-by: Beld Zhang <beldzhang@gmail.com> [axboe: minor fixups] Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'fs/io-wq.c')
-rw-r--r--fs/io-wq.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/io-wq.c b/fs/io-wq.c
index 5d189b24a8d4..8c6131565754 100644
--- a/fs/io-wq.c
+++ b/fs/io-wq.c
@@ -1318,7 +1318,9 @@ int io_wq_cpu_affinity(struct io_wq *wq, cpumask_var_t mask)
*/
int io_wq_max_workers(struct io_wq *wq, int *new_count)
{
- int i, node, prev = 0;
+ int prev[IO_WQ_ACCT_NR];
+ bool first_node = true;
+ int i, node;
BUILD_BUG_ON((int) IO_WQ_ACCT_BOUND != (int) IO_WQ_BOUND);
BUILD_BUG_ON((int) IO_WQ_ACCT_UNBOUND != (int) IO_WQ_UNBOUND);
@@ -1329,6 +1331,9 @@ int io_wq_max_workers(struct io_wq *wq, int *new_count)
new_count[i] = task_rlimit(current, RLIMIT_NPROC);
}
+ for (i = 0; i < IO_WQ_ACCT_NR; i++)
+ prev[i] = 0;
+
rcu_read_lock();
for_each_node(node) {
struct io_wqe *wqe = wq->wqes[node];
@@ -1337,14 +1342,19 @@ int io_wq_max_workers(struct io_wq *wq, int *new_count)
raw_spin_lock(&wqe->lock);
for (i = 0; i < IO_WQ_ACCT_NR; i++) {
acct = &wqe->acct[i];
- prev = max_t(int, acct->max_workers, prev);
+ if (first_node)
+ prev[i] = max_t(int, acct->max_workers, prev[i]);
if (new_count[i])
acct->max_workers = new_count[i];
- new_count[i] = prev;
}
raw_spin_unlock(&wqe->lock);
+ first_node = false;
}
rcu_read_unlock();
+
+ for (i = 0; i < IO_WQ_ACCT_NR; i++)
+ new_count[i] = prev[i];
+
return 0;
}