@@ -191,7 +191,7 @@ struct fixed_file_ref_node {
191191 struct list_head node ;
192192 struct list_head file_list ;
193193 struct fixed_file_data * file_data ;
194- struct work_struct work ;
194+ struct llist_node llist ;
195195};
196196
197197struct fixed_file_data {
@@ -327,6 +327,9 @@ struct io_ring_ctx {
327327 struct list_head inflight_list ;
328328 } ____cacheline_aligned_in_smp ;
329329
330+ struct delayed_work file_put_work ;
331+ struct llist_head file_put_llist ;
332+
330333 struct work_struct exit_work ;
331334};
332335
@@ -879,6 +882,8 @@ struct sock *io_uring_get_socket(struct file *file)
879882}
880883EXPORT_SYMBOL (io_uring_get_socket );
881884
885+ static void io_file_put_work (struct work_struct * work );
886+
882887static void io_ring_ctx_ref_free (struct percpu_ref * ref )
883888{
884889 struct io_ring_ctx * ctx = container_of (ref , struct io_ring_ctx , refs );
@@ -934,6 +939,8 @@ static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
934939 init_waitqueue_head (& ctx -> inflight_wait );
935940 spin_lock_init (& ctx -> inflight_lock );
936941 INIT_LIST_HEAD (& ctx -> inflight_list );
942+ INIT_DELAYED_WORK (& ctx -> file_put_work , io_file_put_work );
943+ init_llist_head (& ctx -> file_put_llist );
937944 return ctx ;
938945err :
939946 if (ctx -> fallback_req )
@@ -6190,6 +6197,7 @@ static int io_sqe_files_unregister(struct io_ring_ctx *ctx)
61906197 percpu_ref_kill (& data -> refs );
61916198
61926199 /* wait for all refs nodes to complete */
6200+ flush_delayed_work (& ctx -> file_put_work );
61936201 wait_for_completion (& data -> done );
61946202
61956203 __io_sqe_files_unregister (ctx );
@@ -6420,18 +6428,13 @@ struct io_file_put {
64206428 struct file * file ;
64216429};
64226430
6423- static void io_file_put_work (struct work_struct * work )
6431+ static void __io_file_put_work (struct fixed_file_ref_node * ref_node )
64246432{
6425- struct fixed_file_ref_node * ref_node ;
6426- struct fixed_file_data * file_data ;
6427- struct io_ring_ctx * ctx ;
6433+ struct fixed_file_data * file_data = ref_node -> file_data ;
6434+ struct io_ring_ctx * ctx = file_data -> ctx ;
64286435 struct io_file_put * pfile , * tmp ;
64296436 unsigned long flags ;
64306437
6431- ref_node = container_of (work , struct fixed_file_ref_node , work );
6432- file_data = ref_node -> file_data ;
6433- ctx = file_data -> ctx ;
6434-
64356438 list_for_each_entry_safe (pfile , tmp , & ref_node -> file_list , list ) {
64366439 list_del_init (& pfile -> list );
64376440 io_ring_file_put (ctx , pfile -> file );
@@ -6447,13 +6450,42 @@ static void io_file_put_work(struct work_struct *work)
64476450 percpu_ref_put (& file_data -> refs );
64486451}
64496452
6453+ static void io_file_put_work (struct work_struct * work )
6454+ {
6455+ struct io_ring_ctx * ctx ;
6456+ struct llist_node * node ;
6457+
6458+ ctx = container_of (work , struct io_ring_ctx , file_put_work .work );
6459+ node = llist_del_all (& ctx -> file_put_llist );
6460+
6461+ while (node ) {
6462+ struct fixed_file_ref_node * ref_node ;
6463+ struct llist_node * next = node -> next ;
6464+
6465+ ref_node = llist_entry (node , struct fixed_file_ref_node , llist );
6466+ __io_file_put_work (ref_node );
6467+ node = next ;
6468+ }
6469+ }
6470+
64506471static void io_file_data_ref_zero (struct percpu_ref * ref )
64516472{
64526473 struct fixed_file_ref_node * ref_node ;
6474+ struct io_ring_ctx * ctx ;
6475+ bool first_add ;
6476+ int delay = HZ ;
64536477
64546478 ref_node = container_of (ref , struct fixed_file_ref_node , refs );
6479+ ctx = ref_node -> file_data -> ctx ;
64556480
6456- queue_work (system_wq , & ref_node -> work );
6481+ if (percpu_ref_is_dying (& ctx -> file_data -> refs ))
6482+ delay = 0 ;
6483+
6484+ first_add = llist_add (& ref_node -> llist , & ctx -> file_put_llist );
6485+ if (!delay )
6486+ mod_delayed_work (system_wq , & ctx -> file_put_work , 0 );
6487+ else if (first_add )
6488+ queue_delayed_work (system_wq , & ctx -> file_put_work , delay );
64576489}
64586490
64596491static struct fixed_file_ref_node * alloc_fixed_file_ref_node (
@@ -6472,10 +6504,8 @@ static struct fixed_file_ref_node *alloc_fixed_file_ref_node(
64726504 }
64736505 INIT_LIST_HEAD (& ref_node -> node );
64746506 INIT_LIST_HEAD (& ref_node -> file_list );
6475- INIT_WORK (& ref_node -> work , io_file_put_work );
64766507 ref_node -> file_data = ctx -> file_data ;
64776508 return ref_node ;
6478-
64796509}
64806510
64816511static void destroy_fixed_file_ref_node (struct fixed_file_ref_node * ref_node )
0 commit comments