diff options
author | Christian Brauner <brauner@kernel.org> | 2025-01-10 11:59:08 +0100 |
---|---|---|
committer | Christian Brauner <brauner@kernel.org> | 2025-01-10 11:59:45 +0100 |
commit | 67cd2e23c0f353803f182ae790a7d5074d4c1a4d (patch) | |
tree | 21b4329a819a52e988be56b5faefd9a78255f896 /include/net | |
parent | Linux 6.13-rc1 (diff) | |
parent | poll: kill poll_does_not_wait() (diff) | |
download | linux-67cd2e23c0f353803f182ae790a7d5074d4c1a4d.tar.xz linux-67cd2e23c0f353803f182ae790a7d5074d4c1a4d.zip |
Merge patch series "poll_wait: add mb() to fix theoretical race between waitqueue_active() and .poll()"
Oleg Nesterov <oleg@redhat.com> says:
The waitqueue_active() helper can only be used if both waker and waiter
have memory barriers that pair with each other. But __pollwait() is
broken in this respect. Fix it.
* patches from https://lore.kernel.org/r/20250107162649.GA18886@redhat.com:
poll: kill poll_does_not_wait()
sock_poll_wait: kill the no longer necessary barrier after poll_wait()
io_uring_poll: kill the no longer necessary barrier after poll_wait()
poll_wait: kill the obsolete wait_address check
poll_wait: add mb() to fix theoretical race between waitqueue_active() and .poll()
Link: https://lore.kernel.org/r/20250107162649.GA18886@redhat.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/sock.h | 17 |
1 files changed, 7 insertions, 10 deletions
diff --git a/include/net/sock.h b/include/net/sock.h index 7464e9f9f47c..305f3ae5edc2 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2291,7 +2291,7 @@ static inline bool skwq_has_sleeper(struct socket_wq *wq) } /** - * sock_poll_wait - place memory barrier behind the poll_wait call. + * sock_poll_wait - wrapper for the poll_wait call. * @filp: file * @sock: socket to wait on * @p: poll_table @@ -2301,15 +2301,12 @@ static inline bool skwq_has_sleeper(struct socket_wq *wq) static inline void sock_poll_wait(struct file *filp, struct socket *sock, poll_table *p) { - if (!poll_does_not_wait(p)) { - poll_wait(filp, &sock->wq.wait, p); - /* We need to be sure we are in sync with the - * socket flags modification. - * - * This memory barrier is paired in the wq_has_sleeper. - */ - smp_mb(); - } + /* Provides a barrier we need to be sure we are in sync + * with the socket flags modification. + * + * This memory barrier is paired in the wq_has_sleeper. + */ + poll_wait(filp, &sock->wq.wait, p); } static inline void skb_set_hash_from_sk(struct sk_buff *skb, struct sock *sk) |