@@ -7998,11 +7998,19 @@ static int io_uring_show_cred(int id, void *p, void *data)
7998
7998
7999
7999
static void __io_uring_show_fdinfo (struct io_ring_ctx * ctx , struct seq_file * m )
8000
8000
{
8001
+ bool has_lock ;
8001
8002
int i ;
8002
8003
8003
- mutex_lock (& ctx -> uring_lock );
8004
+ /*
8005
+ * Avoid ABBA deadlock between the seq lock and the io_uring mutex,
8006
+ * since fdinfo case grabs it in the opposite direction of normal use
8007
+ * cases. If we fail to get the lock, we just don't iterate any
8008
+ * structures that could be going away outside the io_uring mutex.
8009
+ */
8010
+ has_lock = mutex_trylock (& ctx -> uring_lock );
8011
+
8004
8012
seq_printf (m , "UserFiles:\t%u\n" , ctx -> nr_user_files );
8005
- for (i = 0 ; i < ctx -> nr_user_files ; i ++ ) {
8013
+ for (i = 0 ; has_lock && i < ctx -> nr_user_files ; i ++ ) {
8006
8014
struct fixed_file_table * table ;
8007
8015
struct file * f ;
8008
8016
@@ -8014,13 +8022,13 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
8014
8022
seq_printf (m , "%5u: <none>\n" , i );
8015
8023
}
8016
8024
seq_printf (m , "UserBufs:\t%u\n" , ctx -> nr_user_bufs );
8017
- for (i = 0 ; i < ctx -> nr_user_bufs ; i ++ ) {
8025
+ for (i = 0 ; has_lock && i < ctx -> nr_user_bufs ; i ++ ) {
8018
8026
struct io_mapped_ubuf * buf = & ctx -> user_bufs [i ];
8019
8027
8020
8028
seq_printf (m , "%5u: 0x%llx/%u\n" , i , buf -> ubuf ,
8021
8029
(unsigned int ) buf -> len );
8022
8030
}
8023
- if (!idr_is_empty (& ctx -> personality_idr )) {
8031
+ if (has_lock && !idr_is_empty (& ctx -> personality_idr )) {
8024
8032
seq_printf (m , "Personalities:\n" );
8025
8033
idr_for_each (& ctx -> personality_idr , io_uring_show_cred , m );
8026
8034
}
@@ -8035,7 +8043,8 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
8035
8043
req -> task -> task_works != NULL );
8036
8044
}
8037
8045
spin_unlock_irq (& ctx -> completion_lock );
8038
- mutex_unlock (& ctx -> uring_lock );
8046
+ if (has_lock )
8047
+ mutex_unlock (& ctx -> uring_lock );
8039
8048
}
8040
8049
8041
8050
static void io_uring_show_fdinfo (struct seq_file * m , struct file * f )
0 commit comments