在 2021/9/27 下午8:35, Hao Xu 写道:
There may be concurrent poll interruptions:
async_wake()
->del wait entry
->add to tw list
async_wake()
->del wait entry
->add to tw list
This mess up the tw list, let's avoid it by adding a if check before
delete wait entry:
async_wake()
->if empty(wait entry)
return
->del wait entry
->add to tw list
async_wake()
->if empty(wait entry)
return <------------will return here
->del wait entry
->add to tw list
I now think the issue may not exist, since async_wake() is protected by
poll->head->lock, so the wait entry has already been deleted when the
second time event happens and try to visit the wait list to wakeup it.
Fixes: 88e41cf928a6 ("io_uring: add multishot mode for IORING_OP_POLL_ADD")
Signed-off-by: Hao Xu <haoxu@xxxxxxxxxxxxxxxxx>
---
fs/io_uring.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 8317c360f7a4..d0b358b9b589 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -5245,6 +5245,8 @@ static int __io_async_wake(struct io_kiocb *req, struct io_poll_iocb *poll,
trace_io_uring_task_add(req->ctx, req->opcode, req->user_data, mask);
+ if (list_empty(&poll->wait.entry))
+ return 0;
list_del_init(&poll->wait.entry);
req->result = mask;