Skip to content

Commit 01e68ce

Browse files
committed
io_uring/io-wq: stop setting PF_NO_SETAFFINITY on io-wq workers
Every now and then reports come in that are puzzled on why changing affinity on the io-wq workers fails with EINVAL. This happens because they set PF_NO_SETAFFINITY as part of their creation, as io-wq organizes workers into groups based on what CPU they are running on. However, this is purely an optimization and not a functional requirement. We can allow setting affinity, and just lazily update our worker to wqe mappings. If a given io-wq thread times out, it normally exits if there's no more work to do. The exception is if it's the last worker available. For the timeout case, check the affinity of the worker against group mask and exit even if it's the last worker. New workers should be created with the right mask and in the right location. Reported-by:Daniel Dao <[email protected]> Link: https://lore.kernel.org/io-uring/CA+wXwBQwgxB3_UphSny-yAP5b26meeOu1W4TwYVcD_+5gOhvPw@mail.gmail.com/ Signed-off-by: Jens Axboe <[email protected]>
1 parent fe15c26 commit 01e68ce

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

io_uring/io-wq.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ static int io_wqe_worker(void *data)
616616
struct io_wqe_acct *acct = io_wqe_get_acct(worker);
617617
struct io_wqe *wqe = worker->wqe;
618618
struct io_wq *wq = wqe->wq;
619-
bool last_timeout = false;
619+
bool exit_mask = false, last_timeout = false;
620620
char buf[TASK_COMM_LEN];
621621

622622
worker->flags |= (IO_WORKER_F_UP | IO_WORKER_F_RUNNING);
@@ -632,8 +632,11 @@ static int io_wqe_worker(void *data)
632632
io_worker_handle_work(worker);
633633

634634
raw_spin_lock(&wqe->lock);
635-
/* timed out, exit unless we're the last worker */
636-
if (last_timeout && acct->nr_workers > 1) {
635+
/*
636+
* Last sleep timed out. Exit if we're not the last worker,
637+
* or if someone modified our affinity.
638+
*/
639+
if (last_timeout && (exit_mask || acct->nr_workers > 1)) {
637640
acct->nr_workers--;
638641
raw_spin_unlock(&wqe->lock);
639642
__set_current_state(TASK_RUNNING);
@@ -652,7 +655,11 @@ static int io_wqe_worker(void *data)
652655
continue;
653656
break;
654657
}
655-
last_timeout = !ret;
658+
if (!ret) {
659+
last_timeout = true;
660+
exit_mask = !cpumask_test_cpu(raw_smp_processor_id(),
661+
wqe->cpu_mask);
662+
}
656663
}
657664

658665
if (test_bit(IO_WQ_BIT_EXIT, &wq->state))
@@ -704,7 +711,6 @@ static void io_init_new_worker(struct io_wqe *wqe, struct io_worker *worker,
704711
tsk->worker_private = worker;
705712
worker->task = tsk;
706713
set_cpus_allowed_ptr(tsk, wqe->cpu_mask);
707-
tsk->flags |= PF_NO_SETAFFINITY;
708714

709715
raw_spin_lock(&wqe->lock);
710716
hlist_nulls_add_head_rcu(&worker->nulls_node, &wqe->free_list);

0 commit comments

Comments
 (0)