Skip to content

Commit

Permalink
io_uring: remove the need for relying on an io-wq fallback worker
Browse files Browse the repository at this point in the history
We hit this case when the task is exiting, and we need somewhere to
do background cleanup of requests. Instead of relying on the io-wq
task manager to do this work for us, just stuff it somewhere where
we can safely run it ourselves directly.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
Jens Axboe committed Feb 22, 2021
1 parent 2713154 commit 7c25c0d
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 17 deletions.
12 changes: 0 additions & 12 deletions fs/io-wq.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include <linux/kthread.h>
#include <linux/rculist_nulls.h>
#include <linux/fs_struct.h>
#include <linux/task_work.h>
#include <linux/blk-cgroup.h>
#include <linux/audit.h>
#include <linux/cpu.h>
Expand Down Expand Up @@ -775,9 +774,6 @@ static int io_wq_manager(void *data)
complete(&wq->done);

while (!kthread_should_stop()) {
if (current->task_works)
task_work_run();

for_each_node(node) {
struct io_wqe *wqe = wq->wqes[node];
bool fork_worker[2] = { false, false };
Expand All @@ -800,9 +796,6 @@ static int io_wq_manager(void *data)
schedule_timeout(HZ);
}

if (current->task_works)
task_work_run();

out:
if (refcount_dec_and_test(&wq->refs)) {
complete(&wq->done);
Expand Down Expand Up @@ -1160,11 +1153,6 @@ void io_wq_destroy(struct io_wq *wq)
__io_wq_destroy(wq);
}

struct task_struct *io_wq_get_task(struct io_wq *wq)
{
return wq->manager;
}

static bool io_wq_worker_affinity(struct io_worker *worker, void *data)
{
struct task_struct *task = worker->task;
Expand Down
2 changes: 0 additions & 2 deletions fs/io-wq.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ typedef bool (work_cancel_fn)(struct io_wq_work *, void *);
enum io_wq_cancel io_wq_cancel_cb(struct io_wq *wq, work_cancel_fn *cancel,
void *data, bool cancel_all);

struct task_struct *io_wq_get_task(struct io_wq *wq);

#if defined(CONFIG_IO_WQ)
extern void io_wq_worker_sleeping(struct task_struct *);
extern void io_wq_worker_running(struct task_struct *);
Expand Down
37 changes: 34 additions & 3 deletions fs/io_uring.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,9 @@ struct io_ring_ctx {

struct io_restriction restrictions;

/* exit task_work */
struct callback_head *exit_task_work;

/* Keep this last, we don't need it for the fast path */
struct work_struct exit_work;
};
Expand Down Expand Up @@ -2328,11 +2331,14 @@ static int io_req_task_work_add(struct io_kiocb *req)
static void io_req_task_work_add_fallback(struct io_kiocb *req,
task_work_func_t cb)
{
struct task_struct *tsk = io_wq_get_task(req->ctx->io_wq);
struct io_ring_ctx *ctx = req->ctx;
struct callback_head *head;

init_task_work(&req->task_work, cb);
task_work_add(tsk, &req->task_work, TWA_NONE);
wake_up_process(tsk);
do {
head = READ_ONCE(ctx->exit_task_work);
req->task_work.next = head;
} while (cmpxchg(&ctx->exit_task_work, head, &req->task_work) != head);
}

static void __io_req_task_cancel(struct io_kiocb *req, int error)
Expand Down Expand Up @@ -8835,6 +8841,28 @@ static int io_remove_personalities(int id, void *p, void *data)
return 0;
}

static void io_run_ctx_fallback(struct io_ring_ctx *ctx)
{
struct callback_head *work, *head, *next;

do {
do {
head = NULL;
work = READ_ONCE(ctx->exit_task_work);
} while (cmpxchg(&ctx->exit_task_work, work, head) != work);

if (!work)
break;

do {
next = work->next;
work->func(work);
work = next;
cond_resched();
} while (work);
} while (1);
}

static void io_ring_exit_work(struct work_struct *work)
{
struct io_ring_ctx *ctx = container_of(work, struct io_ring_ctx,
Expand All @@ -8848,6 +8876,7 @@ static void io_ring_exit_work(struct work_struct *work)
*/
do {
io_uring_try_cancel_requests(ctx, NULL, NULL);
io_run_ctx_fallback(ctx);
} while (!wait_for_completion_timeout(&ctx->ref_comp, HZ/20));
io_ring_ctx_free(ctx);
}
Expand Down Expand Up @@ -9243,6 +9272,8 @@ static int io_uring_flush(struct file *file, void *data)
io_req_caches_free(ctx, current);
}

io_run_ctx_fallback(ctx);

if (!tctx)
return 0;

Expand Down

0 comments on commit 7c25c0d

Please sign in to comment.