Skip to content

Commit c213de6

Browse files
committed
Merge tag 'io_uring-6.4-2023-06-21' of git://git.kernel.dk/linux
Pull io_uring fixes from Jens Axboe: "A fix for a race condition with poll removal and linked timeouts, and then a few followup fixes/tweaks for the msg_control patch from last week. Not super important, particularly the sparse fixup, as it was broken before that recent commit. But let's get it sorted for real for this release, rather than just have it broken a bit differently" * tag 'io_uring-6.4-2023-06-21' of git://git.kernel.dk/linux: io_uring/net: use the correct msghdr union member in io_sendmsg_copy_hdr io_uring/net: disable partial retries for recvmsg with cmsg io_uring/net: clear msg_controllen on partial sendmsg retry io_uring/poll: serialize poll linked timer start with poll removal
2 parents 5950a00 + 26fed83 commit c213de6

File tree

2 files changed

+15
-11
lines changed

2 files changed

+15
-11
lines changed

io_uring/net.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ static int io_sendmsg_copy_hdr(struct io_kiocb *req,
203203
ret = sendmsg_copy_msghdr(&iomsg->msg, sr->umsg, sr->msg_flags,
204204
&iomsg->free_iov);
205205
/* save msg_control as sys_sendmsg() overwrites it */
206-
sr->msg_control = iomsg->msg.msg_control;
206+
sr->msg_control = iomsg->msg.msg_control_user;
207207
return ret;
208208
}
209209

@@ -302,7 +302,7 @@ int io_sendmsg(struct io_kiocb *req, unsigned int issue_flags)
302302

303303
if (req_has_async_data(req)) {
304304
kmsg = req->async_data;
305-
kmsg->msg.msg_control = sr->msg_control;
305+
kmsg->msg.msg_control_user = sr->msg_control;
306306
} else {
307307
ret = io_sendmsg_copy_hdr(req, &iomsg);
308308
if (ret)
@@ -326,6 +326,8 @@ int io_sendmsg(struct io_kiocb *req, unsigned int issue_flags)
326326
if (ret == -EAGAIN && (issue_flags & IO_URING_F_NONBLOCK))
327327
return io_setup_async_msg(req, kmsg, issue_flags);
328328
if (ret > 0 && io_net_retry(sock, flags)) {
329+
kmsg->msg.msg_controllen = 0;
330+
kmsg->msg.msg_control = NULL;
329331
sr->done_io += ret;
330332
req->flags |= REQ_F_PARTIAL_IO;
331333
return io_setup_async_msg(req, kmsg, issue_flags);
@@ -787,16 +789,19 @@ int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags)
787789
flags = sr->msg_flags;
788790
if (force_nonblock)
789791
flags |= MSG_DONTWAIT;
790-
if (flags & MSG_WAITALL)
791-
min_ret = iov_iter_count(&kmsg->msg.msg_iter);
792792

793793
kmsg->msg.msg_get_inq = 1;
794-
if (req->flags & REQ_F_APOLL_MULTISHOT)
794+
if (req->flags & REQ_F_APOLL_MULTISHOT) {
795795
ret = io_recvmsg_multishot(sock, sr, kmsg, flags,
796796
&mshot_finished);
797-
else
797+
} else {
798+
/* disable partial retry for recvmsg with cmsg attached */
799+
if (flags & MSG_WAITALL && !kmsg->msg.msg_controllen)
800+
min_ret = iov_iter_count(&kmsg->msg.msg_iter);
801+
798802
ret = __sys_recvmsg_sock(sock, &kmsg->msg, sr->umsg,
799803
kmsg->uaddr, flags);
804+
}
800805

801806
if (ret < min_ret) {
802807
if (ret == -EAGAIN && force_nonblock) {

io_uring/poll.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -977,8 +977,9 @@ int io_poll_remove(struct io_kiocb *req, unsigned int issue_flags)
977977
struct io_hash_bucket *bucket;
978978
struct io_kiocb *preq;
979979
int ret2, ret = 0;
980-
struct io_tw_state ts = {};
980+
struct io_tw_state ts = { .locked = true };
981981

982+
io_ring_submit_lock(ctx, issue_flags);
982983
preq = io_poll_find(ctx, true, &cd, &ctx->cancel_table, &bucket);
983984
ret2 = io_poll_disarm(preq);
984985
if (bucket)
@@ -990,12 +991,10 @@ int io_poll_remove(struct io_kiocb *req, unsigned int issue_flags)
990991
goto out;
991992
}
992993

993-
io_ring_submit_lock(ctx, issue_flags);
994994
preq = io_poll_find(ctx, true, &cd, &ctx->cancel_table_locked, &bucket);
995995
ret2 = io_poll_disarm(preq);
996996
if (bucket)
997997
spin_unlock(&bucket->lock);
998-
io_ring_submit_unlock(ctx, issue_flags);
999998
if (ret2) {
1000999
ret = ret2;
10011000
goto out;
@@ -1019,17 +1018,17 @@ int io_poll_remove(struct io_kiocb *req, unsigned int issue_flags)
10191018
if (poll_update->update_user_data)
10201019
preq->cqe.user_data = poll_update->new_user_data;
10211020

1022-
ret2 = io_poll_add(preq, issue_flags);
1021+
ret2 = io_poll_add(preq, issue_flags & ~IO_URING_F_UNLOCKED);
10231022
/* successfully updated, don't complete poll request */
10241023
if (!ret2 || ret2 == -EIOCBQUEUED)
10251024
goto out;
10261025
}
10271026

10281027
req_set_fail(preq);
10291028
io_req_set_res(preq, -ECANCELED, 0);
1030-
ts.locked = !(issue_flags & IO_URING_F_UNLOCKED);
10311029
io_req_task_complete(preq, &ts);
10321030
out:
1031+
io_ring_submit_unlock(ctx, issue_flags);
10331032
if (ret < 0) {
10341033
req_set_fail(req);
10351034
return ret;

0 commit comments

Comments
 (0)