diff options
| author | Jens Axboe <axboe@kernel.dk> | 2025-02-27 07:18:01 -0700 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2025-02-27 07:18:01 -0700 |
| commit | c0d8c0362ba56dd68b45293271e5829ed8c95f5a (patch) | |
| tree | a0ba4791921a273cc9d360b71845bbe71f3e0a7c /io_uring/io-wq.c | |
| parent | 5d309914773370308eb98d1db664eb18f502c5a6 (diff) | |
| parent | 6ebf05189dfc6d0d597c99a6448a4d1064439a18 (diff) | |
Merge branch 'io_uring-6.14' into for-6.15/io_uring
Merge mainline fixes into 6.15 branch, as upcoming patches depend on
fixes that went into the 6.14 mainline branch.
* io_uring-6.14:
io_uring/net: save msg_control for compat
io_uring/rw: clean up mshot forced sync mode
io_uring/rw: move ki_complete init into prep
io_uring/rw: don't directly use ki_complete
io_uring/rw: forbid multishot async reads
io_uring/rsrc: remove unused constants
io_uring: fix spelling error in uapi io_uring.h
io_uring: prevent opcode speculation
io-wq: backoff when retrying worker creation
Diffstat (limited to 'io_uring/io-wq.c')
| -rw-r--r-- | io_uring/io-wq.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c index f7d328feb722..04a75d666195 100644 --- a/io_uring/io-wq.c +++ b/io_uring/io-wq.c @@ -63,7 +63,7 @@ struct io_worker { union { struct rcu_head rcu; - struct work_struct work; + struct delayed_work work; }; }; @@ -784,6 +784,18 @@ static inline bool io_should_retry_thread(struct io_worker *worker, long err) } } +static void queue_create_worker_retry(struct io_worker *worker) +{ + /* + * We only bother retrying because there's a chance that the + * failure to create a worker is due to some temporary condition + * in the forking task (e.g. outstanding signal); give the task + * some time to clear that condition. + */ + schedule_delayed_work(&worker->work, + msecs_to_jiffies(worker->init_retries * 5)); +} + static void create_worker_cont(struct callback_head *cb) { struct io_worker *worker; @@ -823,12 +835,13 @@ static void create_worker_cont(struct callback_head *cb) /* re-create attempts grab a new worker ref, drop the existing one */ io_worker_release(worker); - schedule_work(&worker->work); + queue_create_worker_retry(worker); } static void io_workqueue_create(struct work_struct *work) { - struct io_worker *worker = container_of(work, struct io_worker, work); + struct io_worker *worker = container_of(work, struct io_worker, + work.work); struct io_wq_acct *acct = io_wq_get_acct(worker); if (!io_queue_worker_create(worker, acct, create_worker_cont)) @@ -866,8 +879,8 @@ fail: kfree(worker); goto fail; } else { - INIT_WORK(&worker->work, io_workqueue_create); - schedule_work(&worker->work); + INIT_DELAYED_WORK(&worker->work, io_workqueue_create); + queue_create_worker_retry(worker); } return true; |
