@@ -992,6 +992,10 @@ enum io_mem_account {
992
992
ACCT_PINNED ,
993
993
};
994
994
995
+ static void destroy_fixed_file_ref_node (struct fixed_file_ref_node * ref_node );
996
+ static struct fixed_file_ref_node * alloc_fixed_file_ref_node (
997
+ struct io_ring_ctx * ctx );
998
+
995
999
static void __io_complete_rw (struct io_kiocb * req , long res , long res2 ,
996
1000
struct io_comp_state * cs );
997
1001
static void io_cqring_fill_event (struct io_kiocb * req , long res );
@@ -1501,6 +1505,13 @@ static bool io_grab_identity(struct io_kiocb *req)
1501
1505
spin_unlock_irq (& ctx -> inflight_lock );
1502
1506
req -> work .flags |= IO_WQ_WORK_FILES ;
1503
1507
}
1508
+ if (!(req -> work .flags & IO_WQ_WORK_MM ) &&
1509
+ (def -> work_flags & IO_WQ_WORK_MM )) {
1510
+ if (id -> mm != current -> mm )
1511
+ return false;
1512
+ mmgrab (id -> mm );
1513
+ req -> work .flags |= IO_WQ_WORK_MM ;
1514
+ }
1504
1515
1505
1516
return true;
1506
1517
}
@@ -1525,13 +1536,6 @@ static void io_prep_async_work(struct io_kiocb *req)
1525
1536
req -> work .flags |= IO_WQ_WORK_UNBOUND ;
1526
1537
}
1527
1538
1528
- /* ->mm can never change on us */
1529
- if (!(req -> work .flags & IO_WQ_WORK_MM ) &&
1530
- (def -> work_flags & IO_WQ_WORK_MM )) {
1531
- mmgrab (id -> mm );
1532
- req -> work .flags |= IO_WQ_WORK_MM ;
1533
- }
1534
-
1535
1539
/* if we fail grabbing identity, we must COW, regrab, and retry */
1536
1540
if (io_grab_identity (req ))
1537
1541
return ;
@@ -7231,14 +7235,28 @@ static void io_file_ref_kill(struct percpu_ref *ref)
7231
7235
complete (& data -> done );
7232
7236
}
7233
7237
7238
+ static void io_sqe_files_set_node (struct fixed_file_data * file_data ,
7239
+ struct fixed_file_ref_node * ref_node )
7240
+ {
7241
+ spin_lock_bh (& file_data -> lock );
7242
+ file_data -> node = ref_node ;
7243
+ list_add_tail (& ref_node -> node , & file_data -> ref_list );
7244
+ spin_unlock_bh (& file_data -> lock );
7245
+ percpu_ref_get (& file_data -> refs );
7246
+ }
7247
+
7234
7248
static int io_sqe_files_unregister (struct io_ring_ctx * ctx )
7235
7249
{
7236
7250
struct fixed_file_data * data = ctx -> file_data ;
7237
- struct fixed_file_ref_node * ref_node = NULL ;
7251
+ struct fixed_file_ref_node * backup_node , * ref_node = NULL ;
7238
7252
unsigned nr_tables , i ;
7253
+ int ret ;
7239
7254
7240
7255
if (!data )
7241
7256
return - ENXIO ;
7257
+ backup_node = alloc_fixed_file_ref_node (ctx );
7258
+ if (!backup_node )
7259
+ return - ENOMEM ;
7242
7260
7243
7261
spin_lock_bh (& data -> lock );
7244
7262
ref_node = data -> node ;
@@ -7250,7 +7268,18 @@ static int io_sqe_files_unregister(struct io_ring_ctx *ctx)
7250
7268
7251
7269
/* wait for all refs nodes to complete */
7252
7270
flush_delayed_work (& ctx -> file_put_work );
7253
- wait_for_completion (& data -> done );
7271
+ do {
7272
+ ret = wait_for_completion_interruptible (& data -> done );
7273
+ if (!ret )
7274
+ break ;
7275
+ ret = io_run_task_work_sig ();
7276
+ if (ret < 0 ) {
7277
+ percpu_ref_resurrect (& data -> refs );
7278
+ reinit_completion (& data -> done );
7279
+ io_sqe_files_set_node (data , backup_node );
7280
+ return ret ;
7281
+ }
7282
+ } while (1 );
7254
7283
7255
7284
__io_sqe_files_unregister (ctx );
7256
7285
nr_tables = DIV_ROUND_UP (ctx -> nr_user_files , IORING_MAX_FILES_TABLE );
@@ -7261,6 +7290,7 @@ static int io_sqe_files_unregister(struct io_ring_ctx *ctx)
7261
7290
kfree (data );
7262
7291
ctx -> file_data = NULL ;
7263
7292
ctx -> nr_user_files = 0 ;
7293
+ destroy_fixed_file_ref_node (backup_node );
7264
7294
return 0 ;
7265
7295
}
7266
7296
@@ -7758,11 +7788,7 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg,
7758
7788
return PTR_ERR (ref_node );
7759
7789
}
7760
7790
7761
- file_data -> node = ref_node ;
7762
- spin_lock_bh (& file_data -> lock );
7763
- list_add_tail (& ref_node -> node , & file_data -> ref_list );
7764
- spin_unlock_bh (& file_data -> lock );
7765
- percpu_ref_get (& file_data -> refs );
7791
+ io_sqe_files_set_node (file_data , ref_node );
7766
7792
return ret ;
7767
7793
out_fput :
7768
7794
for (i = 0 ; i < ctx -> nr_user_files ; i ++ ) {
@@ -7918,11 +7944,7 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx,
7918
7944
7919
7945
if (needs_switch ) {
7920
7946
percpu_ref_kill (& data -> node -> refs );
7921
- spin_lock_bh (& data -> lock );
7922
- list_add_tail (& ref_node -> node , & data -> ref_list );
7923
- data -> node = ref_node ;
7924
- spin_unlock_bh (& data -> lock );
7925
- percpu_ref_get (& ctx -> file_data -> refs );
7947
+ io_sqe_files_set_node (data , ref_node );
7926
7948
} else
7927
7949
destroy_fixed_file_ref_node (ref_node );
7928
7950
0 commit comments