@@ -25,6 +25,28 @@ struct io_msg {
25
25
u32 flags ;
26
26
};
27
27
28
+ static void io_double_unlock_ctx (struct io_ring_ctx * octx )
29
+ {
30
+ mutex_unlock (& octx -> uring_lock );
31
+ }
32
+
33
+ static int io_double_lock_ctx (struct io_ring_ctx * octx ,
34
+ unsigned int issue_flags )
35
+ {
36
+ /*
37
+ * To ensure proper ordering between the two ctxs, we can only
38
+ * attempt a trylock on the target. If that fails and we already have
39
+ * the source ctx lock, punt to io-wq.
40
+ */
41
+ if (!(issue_flags & IO_URING_F_UNLOCKED )) {
42
+ if (!mutex_trylock (& octx -> uring_lock ))
43
+ return - EAGAIN ;
44
+ return 0 ;
45
+ }
46
+ mutex_lock (& octx -> uring_lock );
47
+ return 0 ;
48
+ }
49
+
28
50
void io_msg_ring_cleanup (struct io_kiocb * req )
29
51
{
30
52
struct io_msg * msg = io_kiocb_to_cmd (req , struct io_msg );
@@ -36,68 +58,84 @@ void io_msg_ring_cleanup(struct io_kiocb *req)
36
58
msg -> src_file = NULL ;
37
59
}
38
60
61
+ static inline bool io_msg_need_remote (struct io_ring_ctx * target_ctx )
62
+ {
63
+ if (!target_ctx -> task_complete )
64
+ return false;
65
+ return current != target_ctx -> submitter_task ;
66
+ }
67
+
68
+ static int io_msg_exec_remote (struct io_kiocb * req , task_work_func_t func )
69
+ {
70
+ struct io_ring_ctx * ctx = req -> file -> private_data ;
71
+ struct io_msg * msg = io_kiocb_to_cmd (req , struct io_msg );
72
+ struct task_struct * task = READ_ONCE (ctx -> submitter_task );
73
+
74
+ if (unlikely (!task ))
75
+ return - EOWNERDEAD ;
76
+
77
+ init_task_work (& msg -> tw , func );
78
+ if (task_work_add (ctx -> submitter_task , & msg -> tw , TWA_SIGNAL ))
79
+ return - EOWNERDEAD ;
80
+
81
+ return IOU_ISSUE_SKIP_COMPLETE ;
82
+ }
83
+
39
84
static void io_msg_tw_complete (struct callback_head * head )
40
85
{
41
86
struct io_msg * msg = container_of (head , struct io_msg , tw );
42
87
struct io_kiocb * req = cmd_to_io_kiocb (msg );
43
88
struct io_ring_ctx * target_ctx = req -> file -> private_data ;
44
89
int ret = 0 ;
45
90
46
- if (current -> flags & PF_EXITING )
91
+ if (current -> flags & PF_EXITING ) {
47
92
ret = - EOWNERDEAD ;
48
- else if (!io_post_aux_cqe (target_ctx , msg -> user_data , msg -> len , 0 ))
49
- ret = - EOVERFLOW ;
93
+ } else {
94
+ /*
95
+ * If the target ring is using IOPOLL mode, then we need to be
96
+ * holding the uring_lock for posting completions. Other ring
97
+ * types rely on the regular completion locking, which is
98
+ * handled while posting.
99
+ */
100
+ if (target_ctx -> flags & IORING_SETUP_IOPOLL )
101
+ mutex_lock (& target_ctx -> uring_lock );
102
+ if (!io_post_aux_cqe (target_ctx , msg -> user_data , msg -> len , 0 ))
103
+ ret = - EOVERFLOW ;
104
+ if (target_ctx -> flags & IORING_SETUP_IOPOLL )
105
+ mutex_unlock (& target_ctx -> uring_lock );
106
+ }
50
107
51
108
if (ret < 0 )
52
109
req_set_fail (req );
53
110
io_req_queue_tw_complete (req , ret );
54
111
}
55
112
56
- static int io_msg_ring_data (struct io_kiocb * req )
113
+ static int io_msg_ring_data (struct io_kiocb * req , unsigned int issue_flags )
57
114
{
58
115
struct io_ring_ctx * target_ctx = req -> file -> private_data ;
59
116
struct io_msg * msg = io_kiocb_to_cmd (req , struct io_msg );
117
+ int ret ;
60
118
61
119
if (msg -> src_fd || msg -> dst_fd || msg -> flags )
62
120
return - EINVAL ;
121
+ if (target_ctx -> flags & IORING_SETUP_R_DISABLED )
122
+ return - EBADFD ;
63
123
64
- if (target_ctx -> task_complete && current != target_ctx -> submitter_task ) {
65
- init_task_work (& msg -> tw , io_msg_tw_complete );
66
- if (task_work_add (target_ctx -> submitter_task , & msg -> tw ,
67
- TWA_SIGNAL_NO_IPI ))
68
- return - EOWNERDEAD ;
69
-
70
- atomic_or (IORING_SQ_TASKRUN , & target_ctx -> rings -> sq_flags );
71
- return IOU_ISSUE_SKIP_COMPLETE ;
72
- }
73
-
74
- if (io_post_aux_cqe (target_ctx , msg -> user_data , msg -> len , 0 ))
75
- return 0 ;
124
+ if (io_msg_need_remote (target_ctx ))
125
+ return io_msg_exec_remote (req , io_msg_tw_complete );
76
126
77
- return - EOVERFLOW ;
78
- }
79
-
80
- static void io_double_unlock_ctx (struct io_ring_ctx * octx ,
81
- unsigned int issue_flags )
82
- {
83
- mutex_unlock (& octx -> uring_lock );
84
- }
85
-
86
- static int io_double_lock_ctx (struct io_ring_ctx * octx ,
87
- unsigned int issue_flags )
88
- {
89
- /*
90
- * To ensure proper ordering between the two ctxs, we can only
91
- * attempt a trylock on the target. If that fails and we already have
92
- * the source ctx lock, punt to io-wq.
93
- */
94
- if (!(issue_flags & IO_URING_F_UNLOCKED )) {
95
- if (!mutex_trylock (& octx -> uring_lock ))
127
+ ret = - EOVERFLOW ;
128
+ if (target_ctx -> flags & IORING_SETUP_IOPOLL ) {
129
+ if (unlikely (io_double_lock_ctx (target_ctx , issue_flags )))
96
130
return - EAGAIN ;
97
- return 0 ;
131
+ if (io_post_aux_cqe (target_ctx , msg -> user_data , msg -> len , 0 ))
132
+ ret = 0 ;
133
+ io_double_unlock_ctx (target_ctx );
134
+ } else {
135
+ if (io_post_aux_cqe (target_ctx , msg -> user_data , msg -> len , 0 ))
136
+ ret = 0 ;
98
137
}
99
- mutex_lock (& octx -> uring_lock );
100
- return 0 ;
138
+ return ret ;
101
139
}
102
140
103
141
static struct file * io_msg_grab_file (struct io_kiocb * req , unsigned int issue_flags )
@@ -148,7 +186,7 @@ static int io_msg_install_complete(struct io_kiocb *req, unsigned int issue_flag
148
186
if (!io_post_aux_cqe (target_ctx , msg -> user_data , msg -> len , 0 ))
149
187
ret = - EOVERFLOW ;
150
188
out_unlock :
151
- io_double_unlock_ctx (target_ctx , issue_flags );
189
+ io_double_unlock_ctx (target_ctx );
152
190
return ret ;
153
191
}
154
192
@@ -174,6 +212,8 @@ static int io_msg_send_fd(struct io_kiocb *req, unsigned int issue_flags)
174
212
175
213
if (target_ctx == ctx )
176
214
return - EINVAL ;
215
+ if (target_ctx -> flags & IORING_SETUP_R_DISABLED )
216
+ return - EBADFD ;
177
217
if (!src_file ) {
178
218
src_file = io_msg_grab_file (req , issue_flags );
179
219
if (!src_file )
@@ -182,14 +222,8 @@ static int io_msg_send_fd(struct io_kiocb *req, unsigned int issue_flags)
182
222
req -> flags |= REQ_F_NEED_CLEANUP ;
183
223
}
184
224
185
- if (target_ctx -> task_complete && current != target_ctx -> submitter_task ) {
186
- init_task_work (& msg -> tw , io_msg_tw_fd_complete );
187
- if (task_work_add (target_ctx -> submitter_task , & msg -> tw ,
188
- TWA_SIGNAL ))
189
- return - EOWNERDEAD ;
190
-
191
- return IOU_ISSUE_SKIP_COMPLETE ;
192
- }
225
+ if (io_msg_need_remote (target_ctx ))
226
+ return io_msg_exec_remote (req , io_msg_tw_fd_complete );
193
227
return io_msg_install_complete (req , issue_flags );
194
228
}
195
229
@@ -224,7 +258,7 @@ int io_msg_ring(struct io_kiocb *req, unsigned int issue_flags)
224
258
225
259
switch (msg -> cmd ) {
226
260
case IORING_MSG_DATA :
227
- ret = io_msg_ring_data (req );
261
+ ret = io_msg_ring_data (req , issue_flags );
228
262
break ;
229
263
case IORING_MSG_SEND_FD :
230
264
ret = io_msg_send_fd (req , issue_flags );
0 commit comments