Skip to content

Commit 9c38747

Browse files
committed
Merge tag 'io_uring-6.2-2023-01-20' of git://git.kernel.dk/linux
Pull io_uring fixes from Jens Axboe: "Fixes for the MSG_RING opcode. Nothing really major: - Fix an overflow missing serialization around posting CQEs to the target ring (me) - Disable MSG_RING on a ring that isn't enabled yet. There's nothing really wrong with allowing it, but 1) it's somewhat odd as nobody can receive them yet, and 2) it means that using the right delivery mechanism might change. As nobody should be sending CQEs to a ring that isn't enabled yet, let's just disable it (Pavel) - Tweak to when we decide to post remotely or not for MSG_RING (Pavel)" * tag 'io_uring-6.2-2023-01-20' of git://git.kernel.dk/linux: io_uring/msg_ring: fix remote queue to disabled ring io_uring/msg_ring: fix flagging remote execution io_uring/msg_ring: fix missing lock on overflow for IOPOLL io_uring/msg_ring: move double lock/unlock helpers higher up
2 parents 26e5750 + 8579538 commit 9c38747

File tree

2 files changed

+84
-50
lines changed

2 files changed

+84
-50
lines changed

io_uring/io_uring.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3674,7 +3674,7 @@ static __cold int io_uring_create(unsigned entries, struct io_uring_params *p,
36743674

36753675
if (ctx->flags & IORING_SETUP_SINGLE_ISSUER
36763676
&& !(ctx->flags & IORING_SETUP_R_DISABLED))
3677-
ctx->submitter_task = get_task_struct(current);
3677+
WRITE_ONCE(ctx->submitter_task, get_task_struct(current));
36783678

36793679
file = io_uring_get_file(ctx);
36803680
if (IS_ERR(file)) {
@@ -3868,7 +3868,7 @@ static int io_register_enable_rings(struct io_ring_ctx *ctx)
38683868
return -EBADFD;
38693869

38703870
if (ctx->flags & IORING_SETUP_SINGLE_ISSUER && !ctx->submitter_task)
3871-
ctx->submitter_task = get_task_struct(current);
3871+
WRITE_ONCE(ctx->submitter_task, get_task_struct(current));
38723872

38733873
if (ctx->restrictions.registered)
38743874
ctx->restricted = 1;

io_uring/msg_ring.c

Lines changed: 82 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,28 @@ struct io_msg {
2525
u32 flags;
2626
};
2727

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+
2850
void io_msg_ring_cleanup(struct io_kiocb *req)
2951
{
3052
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)
3658
msg->src_file = NULL;
3759
}
3860

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+
3984
static void io_msg_tw_complete(struct callback_head *head)
4085
{
4186
struct io_msg *msg = container_of(head, struct io_msg, tw);
4287
struct io_kiocb *req = cmd_to_io_kiocb(msg);
4388
struct io_ring_ctx *target_ctx = req->file->private_data;
4489
int ret = 0;
4590

46-
if (current->flags & PF_EXITING)
91+
if (current->flags & PF_EXITING) {
4792
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+
}
50107

51108
if (ret < 0)
52109
req_set_fail(req);
53110
io_req_queue_tw_complete(req, ret);
54111
}
55112

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)
57114
{
58115
struct io_ring_ctx *target_ctx = req->file->private_data;
59116
struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg);
117+
int ret;
60118

61119
if (msg->src_fd || msg->dst_fd || msg->flags)
62120
return -EINVAL;
121+
if (target_ctx->flags & IORING_SETUP_R_DISABLED)
122+
return -EBADFD;
63123

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);
76126

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)))
96130
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;
98137
}
99-
mutex_lock(&octx->uring_lock);
100-
return 0;
138+
return ret;
101139
}
102140

103141
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
148186
if (!io_post_aux_cqe(target_ctx, msg->user_data, msg->len, 0))
149187
ret = -EOVERFLOW;
150188
out_unlock:
151-
io_double_unlock_ctx(target_ctx, issue_flags);
189+
io_double_unlock_ctx(target_ctx);
152190
return ret;
153191
}
154192

@@ -174,6 +212,8 @@ static int io_msg_send_fd(struct io_kiocb *req, unsigned int issue_flags)
174212

175213
if (target_ctx == ctx)
176214
return -EINVAL;
215+
if (target_ctx->flags & IORING_SETUP_R_DISABLED)
216+
return -EBADFD;
177217
if (!src_file) {
178218
src_file = io_msg_grab_file(req, issue_flags);
179219
if (!src_file)
@@ -182,14 +222,8 @@ static int io_msg_send_fd(struct io_kiocb *req, unsigned int issue_flags)
182222
req->flags |= REQ_F_NEED_CLEANUP;
183223
}
184224

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);
193227
return io_msg_install_complete(req, issue_flags);
194228
}
195229

@@ -224,7 +258,7 @@ int io_msg_ring(struct io_kiocb *req, unsigned int issue_flags)
224258

225259
switch (msg->cmd) {
226260
case IORING_MSG_DATA:
227-
ret = io_msg_ring_data(req);
261+
ret = io_msg_ring_data(req, issue_flags);
228262
break;
229263
case IORING_MSG_SEND_FD:
230264
ret = io_msg_send_fd(req, issue_flags);

0 commit comments

Comments
 (0)