@@ -987,6 +987,7 @@ static const struct io_op_def io_op_defs[] = {
987
987
[IORING_OP_UNLINKAT ] = {},
988
988
};
989
989
990
+ static void io_uring_del_task_file (unsigned long index );
990
991
static void io_uring_try_cancel_requests (struct io_ring_ctx * ctx ,
991
992
struct task_struct * task ,
992
993
struct files_struct * files );
@@ -8536,10 +8537,33 @@ static bool io_run_ctx_fallback(struct io_ring_ctx *ctx)
8536
8537
return executed ;
8537
8538
}
8538
8539
8540
+ struct io_tctx_exit {
8541
+ struct callback_head task_work ;
8542
+ struct completion completion ;
8543
+ unsigned long index ;
8544
+ };
8545
+
8546
+ static void io_tctx_exit_cb (struct callback_head * cb )
8547
+ {
8548
+ struct io_uring_task * tctx = current -> io_uring ;
8549
+ struct io_tctx_exit * work ;
8550
+
8551
+ work = container_of (cb , struct io_tctx_exit , task_work );
8552
+ /*
8553
+ * When @in_idle, we're in cancellation and it's racy to remove the
8554
+ * node. It'll be removed by the end of cancellation, just ignore it.
8555
+ */
8556
+ if (!atomic_read (& tctx -> in_idle ))
8557
+ io_uring_del_task_file (work -> index );
8558
+ complete (& work -> completion );
8559
+ }
8560
+
8539
8561
static void io_ring_exit_work (struct work_struct * work )
8540
8562
{
8541
- struct io_ring_ctx * ctx = container_of (work , struct io_ring_ctx ,
8542
- exit_work );
8563
+ struct io_ring_ctx * ctx = container_of (work , struct io_ring_ctx , exit_work );
8564
+ struct io_tctx_exit exit ;
8565
+ struct io_tctx_node * node ;
8566
+ int ret ;
8543
8567
8544
8568
/*
8545
8569
* If we're doing polled IO and end up having requests being
@@ -8550,6 +8574,26 @@ static void io_ring_exit_work(struct work_struct *work)
8550
8574
do {
8551
8575
io_uring_try_cancel_requests (ctx , NULL , NULL );
8552
8576
} while (!wait_for_completion_timeout (& ctx -> ref_comp , HZ /20 ));
8577
+
8578
+ mutex_lock (& ctx -> uring_lock );
8579
+ while (!list_empty (& ctx -> tctx_list )) {
8580
+ node = list_first_entry (& ctx -> tctx_list , struct io_tctx_node ,
8581
+ ctx_node );
8582
+ exit .index = (unsigned long )node -> file ;
8583
+ init_completion (& exit .completion );
8584
+ init_task_work (& exit .task_work , io_tctx_exit_cb );
8585
+ ret = task_work_add (node -> task , & exit .task_work , TWA_SIGNAL );
8586
+ if (WARN_ON_ONCE (ret ))
8587
+ continue ;
8588
+ wake_up_process (node -> task );
8589
+
8590
+ mutex_unlock (& ctx -> uring_lock );
8591
+ wait_for_completion (& exit .completion );
8592
+ cond_resched ();
8593
+ mutex_lock (& ctx -> uring_lock );
8594
+ }
8595
+ mutex_unlock (& ctx -> uring_lock );
8596
+
8553
8597
io_ring_ctx_free (ctx );
8554
8598
}
8555
8599
0 commit comments