io_uring-6.1-2022-11-18
-----BEGIN PGP SIGNATURE----- iQJEBAABCAAuFiEEwPw5LcreJtl1+l5K99NY+ylx4KYFAmN4ClYQHGF4Ym9lQGtl cm5lbC5kawAKCRD301j7KXHgpgUND/4sDj30Ga1speiQ4ePkmyWSXJbKacROWM5A OFD0+UAcTPieQ4oEnzQuQjldlPKw7pVDsvS/XJzmXYSF3wZyWQKK3IKNEPQdEovF HvIEMjDA3XJCdn4xJfcBMlOUwzi8/08O+b6QsWbZuZQGuhmJP1nzlNKjETBnct1n 3yWcc7ZrZwKYP3rXsdKx/5gI6jY37tHuo2Xg/eF81QnWpiM8x0KKCDUSTxkbHphl efs+rQ85RGAUMocUEzRn2Ij9gMCzabeF+ZtRLBpTTj6dTjVMcBfn55NjPTBndlXN frBtZ/GNIbkLmi7Dho+ffi93mYhkrNciFrRedQOxYg0PVi6hEe4HZT/DsEb2YbHb +k6y1bh0OJnOp8GNTi9Mu0ZC6cHdiO4ZnE6mh+kU72uTlQcLrn4d3/qyJdL2DzQA VZlEM+xFUbY4MJ21q7bE4hc7WN5fERlSIg+7QEpcDJjukjehUUw8W0h7QudQqHSd uGLwfXDDXuqz6yd+UBs53G3NezsMOtJSXyGG4cd8YpF37YK/pZOl+tgX5bPL6eyM XG5vY6XPHJZ+EQqgpm43vnOiXd2YdzHZbzI6Tu5zbdFKWLgXmO+d1QpFEsyo5Sah FYsZQx6/cAiIA1LEJcxCTQQanULduAg+bdVj/QjxH+paw2ScNmsSrA5ZY/3hTtWj FjGfwSsFRA== =s84S -----END PGP SIGNATURE----- Merge tag 'io_uring-6.1-2022-11-18' of git://git.kernel.dk/linux Pull io_uring fixes from Jens Axboe: "This is mostly fixing issues around the poll rework, but also two tweaks for the multishot handling for accept and receive. All stable material" * tag 'io_uring-6.1-2022-11-18' of git://git.kernel.dk/linux: io_uring: disallow self-propelled ring polling io_uring: fix multishot recv request leaks io_uring: fix multishot accept request leaks io_uring: fix tw losing poll events io_uring: update res mask in io_poll_check_events
This commit is contained in:
commit
a66e4cbf7a
|
@ -16,6 +16,9 @@ enum io_uring_cmd_flags {
|
|||
IO_URING_F_SQE128 = 4,
|
||||
IO_URING_F_CQE32 = 8,
|
||||
IO_URING_F_IOPOLL = 16,
|
||||
|
||||
/* the request is executed from poll, it should not be freed */
|
||||
IO_URING_F_MULTISHOT = 32,
|
||||
};
|
||||
|
||||
struct io_uring_cmd {
|
||||
|
|
|
@ -1768,7 +1768,7 @@ int io_poll_issue(struct io_kiocb *req, bool *locked)
|
|||
io_tw_lock(req->ctx, locked);
|
||||
if (unlikely(req->task->flags & PF_EXITING))
|
||||
return -EFAULT;
|
||||
return io_issue_sqe(req, IO_URING_F_NONBLOCK);
|
||||
return io_issue_sqe(req, IO_URING_F_NONBLOCK|IO_URING_F_MULTISHOT);
|
||||
}
|
||||
|
||||
struct io_wq_work *io_wq_free_work(struct io_wq_work *work)
|
||||
|
|
|
@ -17,8 +17,8 @@ enum {
|
|||
IOU_ISSUE_SKIP_COMPLETE = -EIOCBQUEUED,
|
||||
|
||||
/*
|
||||
* Intended only when both REQ_F_POLLED and REQ_F_APOLL_MULTISHOT
|
||||
* are set to indicate to the poll runner that multishot should be
|
||||
* Intended only when both IO_URING_F_MULTISHOT is passed
|
||||
* to indicate to the poll runner that multishot should be
|
||||
* removed and the result is set on req->cqe.res.
|
||||
*/
|
||||
IOU_STOP_MULTISHOT = -ECANCELED,
|
||||
|
|
|
@ -67,8 +67,6 @@ struct io_sr_msg {
|
|||
struct io_kiocb *notif;
|
||||
};
|
||||
|
||||
#define IO_APOLL_MULTI_POLLED (REQ_F_APOLL_MULTISHOT | REQ_F_POLLED)
|
||||
|
||||
int io_shutdown_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
||||
{
|
||||
struct io_shutdown *shutdown = io_kiocb_to_cmd(req, struct io_shutdown);
|
||||
|
@ -591,7 +589,8 @@ static inline void io_recv_prep_retry(struct io_kiocb *req)
|
|||
* again (for multishot).
|
||||
*/
|
||||
static inline bool io_recv_finish(struct io_kiocb *req, int *ret,
|
||||
unsigned int cflags, bool mshot_finished)
|
||||
unsigned int cflags, bool mshot_finished,
|
||||
unsigned issue_flags)
|
||||
{
|
||||
if (!(req->flags & REQ_F_APOLL_MULTISHOT)) {
|
||||
io_req_set_res(req, *ret, cflags);
|
||||
|
@ -614,7 +613,7 @@ static inline bool io_recv_finish(struct io_kiocb *req, int *ret,
|
|||
|
||||
io_req_set_res(req, *ret, cflags);
|
||||
|
||||
if (req->flags & REQ_F_POLLED)
|
||||
if (issue_flags & IO_URING_F_MULTISHOT)
|
||||
*ret = IOU_STOP_MULTISHOT;
|
||||
else
|
||||
*ret = IOU_OK;
|
||||
|
@ -773,8 +772,7 @@ retry_multishot:
|
|||
if (ret < min_ret) {
|
||||
if (ret == -EAGAIN && force_nonblock) {
|
||||
ret = io_setup_async_msg(req, kmsg, issue_flags);
|
||||
if (ret == -EAGAIN && (req->flags & IO_APOLL_MULTI_POLLED) ==
|
||||
IO_APOLL_MULTI_POLLED) {
|
||||
if (ret == -EAGAIN && (issue_flags & IO_URING_F_MULTISHOT)) {
|
||||
io_kbuf_recycle(req, issue_flags);
|
||||
return IOU_ISSUE_SKIP_COMPLETE;
|
||||
}
|
||||
|
@ -803,7 +801,7 @@ retry_multishot:
|
|||
if (kmsg->msg.msg_inq)
|
||||
cflags |= IORING_CQE_F_SOCK_NONEMPTY;
|
||||
|
||||
if (!io_recv_finish(req, &ret, cflags, mshot_finished))
|
||||
if (!io_recv_finish(req, &ret, cflags, mshot_finished, issue_flags))
|
||||
goto retry_multishot;
|
||||
|
||||
if (mshot_finished) {
|
||||
|
@ -869,7 +867,7 @@ retry_multishot:
|
|||
ret = sock_recvmsg(sock, &msg, flags);
|
||||
if (ret < min_ret) {
|
||||
if (ret == -EAGAIN && force_nonblock) {
|
||||
if ((req->flags & IO_APOLL_MULTI_POLLED) == IO_APOLL_MULTI_POLLED) {
|
||||
if (issue_flags & IO_URING_F_MULTISHOT) {
|
||||
io_kbuf_recycle(req, issue_flags);
|
||||
return IOU_ISSUE_SKIP_COMPLETE;
|
||||
}
|
||||
|
@ -902,7 +900,7 @@ out_free:
|
|||
if (msg.msg_inq)
|
||||
cflags |= IORING_CQE_F_SOCK_NONEMPTY;
|
||||
|
||||
if (!io_recv_finish(req, &ret, cflags, ret <= 0))
|
||||
if (!io_recv_finish(req, &ret, cflags, ret <= 0, issue_flags))
|
||||
goto retry_multishot;
|
||||
|
||||
return ret;
|
||||
|
@ -1289,8 +1287,7 @@ retry:
|
|||
* return EAGAIN to arm the poll infra since it
|
||||
* has already been done
|
||||
*/
|
||||
if ((req->flags & IO_APOLL_MULTI_POLLED) ==
|
||||
IO_APOLL_MULTI_POLLED)
|
||||
if (issue_flags & IO_URING_F_MULTISHOT)
|
||||
ret = IOU_ISSUE_SKIP_COMPLETE;
|
||||
return ret;
|
||||
}
|
||||
|
@ -1315,9 +1312,7 @@ retry:
|
|||
goto retry;
|
||||
|
||||
io_req_set_res(req, ret, 0);
|
||||
if (req->flags & REQ_F_POLLED)
|
||||
return IOU_STOP_MULTISHOT;
|
||||
return IOU_OK;
|
||||
return (issue_flags & IO_URING_F_MULTISHOT) ? IOU_STOP_MULTISHOT : IOU_OK;
|
||||
}
|
||||
|
||||
int io_socket_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
||||
|
|
|
@ -228,6 +228,13 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
|
|||
return IOU_POLL_DONE;
|
||||
if (v & IO_POLL_CANCEL_FLAG)
|
||||
return -ECANCELED;
|
||||
/*
|
||||
* cqe.res contains only events of the first wake up
|
||||
* and all others are be lost. Redo vfs_poll() to get
|
||||
* up to date state.
|
||||
*/
|
||||
if ((v & IO_POLL_REF_MASK) != 1)
|
||||
req->cqe.res = 0;
|
||||
|
||||
/* the mask was stashed in __io_poll_execute */
|
||||
if (!req->cqe.res) {
|
||||
|
@ -239,6 +246,8 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
|
|||
continue;
|
||||
if (req->apoll_events & EPOLLONESHOT)
|
||||
return IOU_POLL_DONE;
|
||||
if (io_is_uring_fops(req->file))
|
||||
return IOU_POLL_DONE;
|
||||
|
||||
/* multishot, just fill a CQE and proceed */
|
||||
if (!(req->flags & REQ_F_APOLL_MULTISHOT)) {
|
||||
|
@ -258,6 +267,9 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* force the next iteration to vfs_poll() */
|
||||
req->cqe.res = 0;
|
||||
|
||||
/*
|
||||
* Release all references, retry if someone tried to restart
|
||||
* task_work while we were executing it.
|
||||
|
|
Loading…
Reference in New Issue