On 10/25/21 06:38, Xiaoguang Wang wrote:
In current implementation, if there are not available events,
io_poll_rewait() just gets completion_lock, and unlocks it in
io_poll_task_func() or io_async_task_func(), which isn't necessary.
Change this logic to let io_poll_task_func() or io_async_task_func()
get the completion_lock lock.
Signed-off-by: Xiaoguang Wang <xiaoguang.wang@xxxxxxxxxxxxxxxxx>
---
fs/io_uring.c | 58 ++++++++++++++++++++++++++--------------------------------
1 file changed, 26 insertions(+), 32 deletions(-)
diff --git a/fs/io_uring.c b/fs/io_uring.c
index e4c779dac953..41ff8fdafe55 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -5248,10 +5248,7 @@ static inline int __io_async_wake(struct io_kiocb *req, struct io_poll_iocb *pol
}
static bool io_poll_rewait(struct io_kiocb *req, struct io_poll_iocb *poll)
- __acquires(&req->ctx->completion_lock)
{
- struct io_ring_ctx *ctx = req->ctx;
-
/* req->task == current here, checking PF_EXITING is safe */
if (unlikely(req->task->flags & PF_EXITING))
WRITE_ONCE(poll->canceled, true);
@@ -5262,7 +5259,6 @@ static bool io_poll_rewait(struct io_kiocb *req, struct io_poll_iocb *poll)
req->result = vfs_poll(req->file, &pt) & poll->events;
}
- spin_lock(&ctx->completion_lock);
Don't remember poll sync too well but this was synchronising with the
final section of __io_arm_poll_handler(), and I'm afraid it may go
completely loose with races.
if (!req->result && !READ_ONCE(poll->canceled)) {
if (req->opcode == IORING_OP_POLL_ADD)
WRITE_ONCE(poll->active, true);
--
Pavel Begunkov