Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+23 -29
+12 -14
include/linux/poll.h
··· 25 25 26 26 struct poll_table_struct; 27 27 28 - /* 28 + /* 29 29 * structures and helpers for f_op->poll implementations 30 30 */ 31 31 typedef 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 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. 36 36 */ 37 37 typedef struct poll_table_struct { 38 38 poll_queue_proc _qproc; ··· 41 41 42 42 static 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 45 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 + } 56 54 } 57 55 58 56 /*
+7 -10
include/net/sock.h
··· 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 2301 * @filp: file 2302 2302 * @sock: socket to wait on 2303 2303 * @p: poll_table ··· 2307 2307 static inline void sock_poll_wait(struct file *filp, struct socket *sock, 2308 2308 poll_table *p) 2309 2309 { 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); 2319 2316 } 2320 2317 2321 2318 static inline void skb_set_hash_from_sk(struct sk_buff *skb, struct sock *sk)
+4 -5
io_uring/io_uring.c
··· 2813 2813 2814 2814 if (unlikely(!ctx->poll_activated)) 2815 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 in 2820 - * io_commit_cqring 2817 + * provides mb() which pairs with barrier from wq_has_sleeper 2818 + * call in io_commit_cqring 2821 2819 */ 2822 - smp_rmb(); 2820 + poll_wait(file, &ctx->poll_wq, wait); 2821 + 2823 2822 if (!io_sqring_full(ctx)) 2824 2823 mask |= EPOLLOUT | EPOLLWRNORM; 2825 2824