kernel: make IO threads unfreezable by default
authorJens Axboe <axboe@kernel.dk>
Wed, 10 Mar 2021 02:49:02 +0000 (19:49 -0700)
committerJens Axboe <axboe@kernel.dk>
Wed, 10 Mar 2021 14:28:43 +0000 (07:28 -0700)
The io-wq threads were already marked as no-freeze, but the manager was
not. On resume, we perpetually have signal_pending() being true, and
hence the manager will loop and spin 100% of the time.

Just mark the tasks created by create_io_thread() as PF_NOFREEZE by
default, and remove any knowledge of it in io-wq and io_uring.

Reported-by: Kevin Locke <kevin@kevinlocke.name>
Tested-by: Kevin Locke <kevin@kevinlocke.name>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/io-wq.c
fs/io_uring.c
kernel/fork.c

index 3d7060b..0ae9eca 100644 (file)
@@ -591,7 +591,7 @@ static bool create_io_worker(struct io_wq *wq, struct io_wqe *wqe, int index)
        tsk->pf_io_worker = worker;
        worker->task = tsk;
        set_cpus_allowed_ptr(tsk, cpumask_of_node(wqe->node));
-       tsk->flags |= PF_NOFREEZE | PF_NO_SETAFFINITY;
+       tsk->flags |= PF_NO_SETAFFINITY;
 
        raw_spin_lock_irq(&wqe->lock);
        hlist_nulls_add_head_rcu(&worker->nulls_node, &wqe->free_list);
@@ -709,7 +709,6 @@ static int io_wq_manager(void *data)
                set_current_state(TASK_INTERRUPTIBLE);
                io_wq_check_workers(wq);
                schedule_timeout(HZ);
-               try_to_freeze();
                if (fatal_signal_pending(current))
                        set_bit(IO_WQ_BIT_EXIT, &wq->state);
        } while (!test_bit(IO_WQ_BIT_EXIT, &wq->state));
index 62f998b..14165e1 100644 (file)
@@ -6733,7 +6733,6 @@ static int io_sq_thread(void *data)
 
                        up_read(&sqd->rw_lock);
                        schedule();
-                       try_to_freeze();
                        down_read(&sqd->rw_lock);
                        list_for_each_entry(ctx, &sqd->ctx_list, sqd_list)
                                io_ring_clear_wakeup_flag(ctx);
index d3171e8..72e444c 100644 (file)
@@ -2436,6 +2436,7 @@ struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node)
        if (!IS_ERR(tsk)) {
                sigfillset(&tsk->blocked);
                sigdelsetmask(&tsk->blocked, sigmask(SIGKILL));
+               tsk->flags |= PF_NOFREEZE;
        }
        return tsk;
 }