struct io_ring_ctx *ctx = container_of(work, struct io_ring_ctx, exit_work);
unsigned long timeout = jiffies + HZ * 60 * 5;
unsigned long interval = HZ / 20;
+ struct completion *exit_comp;
struct io_tctx_exit exit;
struct io_tctx_node *node;
int ret;
io_kworker_tw_end();
+ exit_comp = READ_ONCE(ctx->exit_comp);
+ if (exit_comp)
+ complete(exit_comp);
+
init_completion(&exit.completion);
init_task_work(&exit.task_work, io_tctx_exit_cb);
exit.ctx = ctx;
static int io_uring_release(struct inode *inode, struct file *file)
{
struct io_ring_ctx *ctx = file->private_data;
+ DECLARE_COMPLETION_ONSTACK(exit_comp);
file->private_data = NULL;
+ WRITE_ONCE(ctx->exit_comp, &exit_comp);
io_ring_ctx_wait_and_kill(ctx);
+
+ /*
+ * Wait for cancel to run before exiting task
+ */
+ do {
+ if (current->io_uring)
+ io_fallback_tw(current->io_uring, false);
+ } while (wait_for_completion_interruptible(&exit_comp));
+
return 0;
}