io-wq: make worker creation resilient against signals
authorJens Axboe <axboe@kernel.dk>
Wed, 1 Sep 2021 17:20:10 +0000 (11:20 -0600)
committerJens Axboe <axboe@kernel.dk>
Thu, 2 Sep 2021 17:12:19 +0000 (11:12 -0600)
commit3146cba99aa284b1d4a10fbd923df953f1d18035
tree87b77c785c2a51a1247bc72bf0ecd5a884524244
parent05c5f4ee4da7086cceacc78bf3a080e314c241fa
io-wq: make worker creation resilient against signals

If a task is queueing async work and also handling signals, then we can
run into the case where create_io_thread() is interrupted and returns
failure because of that. If this happens for creating the first worker
in a group, then that worker will never get created and we can hang the
ring.

If we do get a fork failure, retry from task_work. With signals we have
to be a bit careful as we cannot simply queue as task_work, as we'll
still have signals pending at that point. Punt over a normal workqueue
first and then create from task_work after that.

Lastly, ensure that we handle fatal worker creations. Worker creation
failures are normally not fatal, only if we fail to create one in an empty
worker group can we not make progress. Right now that is ignored, ensure
that we handle that and run cancel on the work item.

There are two paths that create new workers - one is the "existing worker
going to sleep", and the other is "no workers found for this work, create
one". The former is never fatal, as workers do exist in the group. Only
the latter needs to be carefully handled.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/io-wq.c