@@ -191,7 +191,7 @@ struct fixed_file_ref_node {
191
191
struct list_head node ;
192
192
struct list_head file_list ;
193
193
struct fixed_file_data * file_data ;
194
- struct work_struct work ;
194
+ struct llist_node llist ;
195
195
};
196
196
197
197
struct fixed_file_data {
@@ -327,6 +327,9 @@ struct io_ring_ctx {
327
327
struct list_head inflight_list ;
328
328
} ____cacheline_aligned_in_smp ;
329
329
330
+ struct delayed_work file_put_work ;
331
+ struct llist_head file_put_llist ;
332
+
330
333
struct work_struct exit_work ;
331
334
};
332
335
@@ -879,6 +882,8 @@ struct sock *io_uring_get_socket(struct file *file)
879
882
}
880
883
EXPORT_SYMBOL (io_uring_get_socket );
881
884
885
+ static void io_file_put_work (struct work_struct * work );
886
+
882
887
static void io_ring_ctx_ref_free (struct percpu_ref * ref )
883
888
{
884
889
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)
934
939
init_waitqueue_head (& ctx -> inflight_wait );
935
940
spin_lock_init (& ctx -> inflight_lock );
936
941
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 );
937
944
return ctx ;
938
945
err :
939
946
if (ctx -> fallback_req )
@@ -6190,6 +6197,7 @@ static int io_sqe_files_unregister(struct io_ring_ctx *ctx)
6190
6197
percpu_ref_kill (& data -> refs );
6191
6198
6192
6199
/* wait for all refs nodes to complete */
6200
+ flush_delayed_work (& ctx -> file_put_work );
6193
6201
wait_for_completion (& data -> done );
6194
6202
6195
6203
__io_sqe_files_unregister (ctx );
@@ -6420,18 +6428,13 @@ struct io_file_put {
6420
6428
struct file * file ;
6421
6429
};
6422
6430
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 )
6424
6432
{
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 ;
6428
6435
struct io_file_put * pfile , * tmp ;
6429
6436
unsigned long flags ;
6430
6437
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
-
6435
6438
list_for_each_entry_safe (pfile , tmp , & ref_node -> file_list , list ) {
6436
6439
list_del_init (& pfile -> list );
6437
6440
io_ring_file_put (ctx , pfile -> file );
@@ -6447,13 +6450,42 @@ static void io_file_put_work(struct work_struct *work)
6447
6450
percpu_ref_put (& file_data -> refs );
6448
6451
}
6449
6452
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
+
6450
6471
static void io_file_data_ref_zero (struct percpu_ref * ref )
6451
6472
{
6452
6473
struct fixed_file_ref_node * ref_node ;
6474
+ struct io_ring_ctx * ctx ;
6475
+ bool first_add ;
6476
+ int delay = HZ ;
6453
6477
6454
6478
ref_node = container_of (ref , struct fixed_file_ref_node , refs );
6479
+ ctx = ref_node -> file_data -> ctx ;
6455
6480
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 );
6457
6489
}
6458
6490
6459
6491
static 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(
6472
6504
}
6473
6505
INIT_LIST_HEAD (& ref_node -> node );
6474
6506
INIT_LIST_HEAD (& ref_node -> file_list );
6475
- INIT_WORK (& ref_node -> work , io_file_put_work );
6476
6507
ref_node -> file_data = ctx -> file_data ;
6477
6508
return ref_node ;
6478
-
6479
6509
}
6480
6510
6481
6511
static void destroy_fixed_file_ref_node (struct fixed_file_ref_node * ref_node )
0 commit comments