History

Merge branch 'vfs-6.14.poll' into vfs.fixes

Bring in the fixes for __pollwait() and waitqueue_active() interactions.

Christian Brauner committed 1 year ago

Commit 1623bc22 parents 17a4fde 67cd2e23 files · +23 −29Browse files

Unified · Split

3 files
  1. include/linux/poll.h +12 −14
  2. include/net/sock.h +7 −10
  3. io_uring/io_uring.c +4 −5
include/linux/poll.h+12−14
@@ -25,14 +25,14 @@ · 24 unmodified lines
25 25
26struct poll_table_struct;26struct poll_table_struct;
27 27
28/* 28/*
29 * structures and helpers for f_op->poll implementations29 * structures and helpers for f_op->poll implementations
30 */30 */
31typedef void (*poll_queue_proc)(struct file *, wait_queue_head_t *, struct poll_table_struct *);31typedef void (*poll_queue_proc)(struct file *, wait_queue_head_t *, struct poll_table_struct *);
32 32
33/*33/*
34 * Do not touch the structure directly, use the access functions34 * Do not touch the structure directly, use the access function
35 * poll_does_not_wait() and poll_requested_events() instead.35 * poll_requested_events() instead.
36 */36 */
37typedef struct poll_table_struct {37typedef struct poll_table_struct {
38 poll_queue_proc _qproc;38 poll_queue_proc _qproc;
@@ -41,18 +41,16 @@ typedef struct poll_table_struct { · 2 unmodified lines
41 41
42static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)42static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
43{43{
44 if (p && p->_qproc && wait_address)44 if (p && p->_qproc) {
45 p->_qproc(filp, wait_address, p);45 p->_qproc(filp, wait_address, p);
46}46 /*
47 47 * This memory barrier is paired in the wq_has_sleeper().
48/*48 * See the comment above prepare_to_wait(), we need to
49 * Return true if it is guaranteed that poll will not wait. This is the case49 * ensure that subsequent tests in this thread can't be
50 * if the poll() of another file descriptor in the set got an event, so there50 * reordered with __add_wait_queue() in _qproc() paths.
51 * is no need for waiting.51 */
52 */52 smp_mb();
53static inline bool poll_does_not_wait(const poll_table *p)53 }
54{
55 return p == NULL || p->_qproc == NULL;
56}54}
57 55
58/*56/*
include/net/sock.h+7−10
@@ -2297,7 +2297,7 @@ static inline bool skwq_has_sleeper(struct socket_wq *wq) · 2296 unmodified lines
2297}2297}
2298 2298
2299/**2299/**
2300 * sock_poll_wait - place memory barrier behind the poll_wait call.2300 * sock_poll_wait - wrapper for the poll_wait call.
2301 * @filp: file2301 * @filp: file
2302 * @sock: socket to wait on2302 * @sock: socket to wait on
2303 * @p: poll_table2303 * @p: poll_table
@@ -2307,15 +2307,12 @@ static inline bool skwq_has_sleeper(struct socket_wq *wq) · 3 unmodified lines
2307static inline void sock_poll_wait(struct file *filp, struct socket *sock,2307static inline void sock_poll_wait(struct file *filp, struct socket *sock,
2308 poll_table *p)2308 poll_table *p)
2309{2309{
2310 if (!poll_does_not_wait(p)) {2310 /* Provides a barrier we need to be sure we are in sync
2311 poll_wait(filp, &sock->wq.wait, p);2311 * with the socket flags modification.
2312 /* We need to be sure we are in sync with the2312 *
2313 * socket flags modification.2313 * This memory barrier is paired in the wq_has_sleeper.
2314 *2314 */
2315 * This memory barrier is paired in the wq_has_sleeper.2315 poll_wait(filp, &sock->wq.wait, p);
2316 */
2317 smp_mb();
2318 }
2319}2316}
2320 2317
2321static inline void skb_set_hash_from_sk(struct sk_buff *skb, struct sock *sk)2318static inline void skb_set_hash_from_sk(struct sk_buff *skb, struct sock *sk)
io_uring/io_uring.c+4−5
@@ -2813,13 +2813,12 @@ static __poll_t io_uring_poll(struct file *file, poll_table *wait) · 2812 unmodified lines
2813 2813
2814 if (unlikely(!ctx->poll_activated))2814 if (unlikely(!ctx->poll_activated))
2815 io_activate_pollwq(ctx);2815 io_activate_pollwq(ctx);
2816
2817 poll_wait(file, &ctx->poll_wq, wait);
2818 /*2816 /*
2819 * synchronizes with barrier from wq_has_sleeper call in2817 * provides mb() which pairs with barrier from wq_has_sleeper
2820 * io_commit_cqring2818 * call in io_commit_cqring
2821 */2819 */
2822 smp_rmb();2820 poll_wait(file, &ctx->poll_wq, wait);
2821
2823 if (!io_sqring_full(ctx))2822 if (!io_sqring_full(ctx))
2824 mask |= EPOLLOUT | EPOLLWRNORM;2823 mask |= EPOLLOUT | EPOLLWRNORM;
2825 2824