Skip to content

Commit 1623bc2

Browse files
committed
Merge branch 'vfs-6.14.poll' into vfs.fixes
Bring in the fixes for __pollwait() and waitqueue_active() interactions. Signed-off-by: Christian Brauner <brauner@kernel.org>
2 parents 17a4fde + 67cd2e2 commit 1623bc2

File tree

3 files changed

+23
-29
lines changed

3 files changed

+23
-29
lines changed

include/linux/poll.h

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@
2525

2626
struct poll_table_struct;
2727

28-
/*
28+
/*
2929
* structures and helpers for f_op->poll implementations
3030
*/
3131
typedef void (*poll_queue_proc)(struct file *, wait_queue_head_t *, struct poll_table_struct *);
3232

3333
/*
34-
* Do not touch the structure directly, use the access functions
35-
* poll_does_not_wait() and poll_requested_events() instead.
34+
* Do not touch the structure directly, use the access function
35+
* poll_requested_events() instead.
3636
*/
3737
typedef struct poll_table_struct {
3838
poll_queue_proc _qproc;
@@ -41,18 +41,16 @@ typedef struct poll_table_struct {
4141

4242
static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
4343
{
44-
if (p && p->_qproc && wait_address)
44+
if (p && p->_qproc) {
4545
p->_qproc(filp, wait_address, p);
46-
}
47-
48-
/*
49-
* Return true if it is guaranteed that poll will not wait. This is the case
50-
* if the poll() of another file descriptor in the set got an event, so there
51-
* is no need for waiting.
52-
*/
53-
static inline bool poll_does_not_wait(const poll_table *p)
54-
{
55-
return p == NULL || p->_qproc == NULL;
46+
/*
47+
* This memory barrier is paired in the wq_has_sleeper().
48+
* See the comment above prepare_to_wait(), we need to
49+
* ensure that subsequent tests in this thread can't be
50+
* reordered with __add_wait_queue() in _qproc() paths.
51+
*/
52+
smp_mb();
53+
}
5654
}
5755

5856
/*

include/net/sock.h

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2297,7 +2297,7 @@ static inline bool skwq_has_sleeper(struct socket_wq *wq)
22972297
}
22982298

22992299
/**
2300-
* sock_poll_wait - place memory barrier behind the poll_wait call.
2300+
* sock_poll_wait - wrapper for the poll_wait call.
23012301
* @filp: file
23022302
* @sock: socket to wait on
23032303
* @p: poll_table
@@ -2307,15 +2307,12 @@ static inline bool skwq_has_sleeper(struct socket_wq *wq)
23072307
static inline void sock_poll_wait(struct file *filp, struct socket *sock,
23082308
poll_table *p)
23092309
{
2310-
if (!poll_does_not_wait(p)) {
2311-
poll_wait(filp, &sock->wq.wait, p);
2312-
/* We need to be sure we are in sync with the
2313-
* socket flags modification.
2314-
*
2315-
* This memory barrier is paired in the wq_has_sleeper.
2316-
*/
2317-
smp_mb();
2318-
}
2310+
/* Provides a barrier we need to be sure we are in sync
2311+
* with the socket flags modification.
2312+
*
2313+
* This memory barrier is paired in the wq_has_sleeper.
2314+
*/
2315+
poll_wait(filp, &sock->wq.wait, p);
23192316
}
23202317

23212318
static inline void skb_set_hash_from_sk(struct sk_buff *skb, struct sock *sk)

io_uring/io_uring.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2813,13 +2813,12 @@ static __poll_t io_uring_poll(struct file *file, poll_table *wait)
28132813

28142814
if (unlikely(!ctx->poll_activated))
28152815
io_activate_pollwq(ctx);
2816-
2817-
poll_wait(file, &ctx->poll_wq, wait);
28182816
/*
2819-
* synchronizes with barrier from wq_has_sleeper call in
2820-
* io_commit_cqring
2817+
* provides mb() which pairs with barrier from wq_has_sleeper
2818+
* call in io_commit_cqring
28212819
*/
2822-
smp_rmb();
2820+
poll_wait(file, &ctx->poll_wq, wait);
2821+
28232822
if (!io_sqring_full(ctx))
28242823
mask |= EPOLLOUT | EPOLLWRNORM;
28252824

0 commit comments

Comments
 (0)