--- x/io_uring/poll.c +++ y/io_uring/poll.c @@ -143,6 +143,8 @@ static inline void io_poll_remove_entry( struct wait_queue_head *head = smp_load_acquire(&poll->head); if (head) { + if (list_empty(&poll->wait.entry)) + return; spin_lock_irq(&head->lock); list_del_init(&poll->wait.entry); poll->head = NULL; @@ -416,7 +418,7 @@ static int io_poll_wake(struct wait_queu /* optional, saves extra locking for removal in tw handler */ if (mask && poll->events & EPOLLONESHOT) { list_del_init(&poll->wait.entry); - poll->head = NULL; + smp_store_release(&poll->head, NULL); if (wqe_is_double(wait)) req->flags &= ~REQ_F_DOUBLE_POLL; else