| From: Kuniyuki Iwashima <kuniyu@amazon.co.jp> |
| Subject: pipe: make poll_usage boolean and annotate its access |
| |
| Patch series "Fix data-races around epoll reported by KCSAN." |
| |
| This series suppresses a false positive KCSAN's message and fixes a real |
| data-race. |
| |
| |
| This patch (of 2): |
| |
| pipe_poll() runs locklessly and assigns 1 to poll_usage. Once poll_usage |
| is set to 1, it never changes in other places. However, concurrent writes |
| of a value trigger KCSAN, so let's make KCSAN happy. |
| |
| BUG: KCSAN: data-race in pipe_poll / pipe_poll |
| |
| write to 0xffff8880042f6678 of 4 bytes by task 174 on cpu 3: |
| pipe_poll (fs/pipe.c:656) |
| ep_item_poll.isra.0 (./include/linux/poll.h:88 fs/eventpoll.c:853) |
| do_epoll_wait (fs/eventpoll.c:1692 fs/eventpoll.c:1806 fs/eventpoll.c:2234) |
| __x64_sys_epoll_wait (fs/eventpoll.c:2246 fs/eventpoll.c:2241 fs/eventpoll.c:2241) |
| do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80) |
| entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:113) |
| |
| write to 0xffff8880042f6678 of 4 bytes by task 177 on cpu 1: |
| pipe_poll (fs/pipe.c:656) |
| ep_item_poll.isra.0 (./include/linux/poll.h:88 fs/eventpoll.c:853) |
| do_epoll_wait (fs/eventpoll.c:1692 fs/eventpoll.c:1806 fs/eventpoll.c:2234) |
| __x64_sys_epoll_wait (fs/eventpoll.c:2246 fs/eventpoll.c:2241 fs/eventpoll.c:2241) |
| do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80) |
| entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:113) |
| |
| Reported by Kernel Concurrency Sanitizer on: |
| CPU: 1 PID: 177 Comm: epoll_race Not tainted 5.17.0-58927-gf443e374ae13 #6 |
| Hardware name: Red Hat KVM, BIOS 1.11.0-2.amzn2 04/01/2014 |
| |
| Link: https://lkml.kernel.org/r/20220322002653.33865-1-kuniyu@amazon.co.jp |
| Link: https://lkml.kernel.org/r/20220322002653.33865-2-kuniyu@amazon.co.jp |
| Fixes: 3b844826b6c6 ("pipe: avoid unnecessary EPOLLET wakeups under normal loads") |
| Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.co.jp> |
| Cc: Alexander Duyck <alexander.h.duyck@intel.com> |
| Cc: Al Viro <viro@zeniv.linux.org.uk> |
| Cc: Davidlohr Bueso <dave@stgolabs.net> |
| Cc: Kuniyuki Iwashima <kuni1840@gmail.com> |
| Cc: "Soheil Hassas Yeganeh" <soheil@google.com> |
| Cc: "Sridhar Samudrala" <sridhar.samudrala@intel.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| fs/pipe.c | 2 +- |
| include/linux/pipe_fs_i.h | 2 +- |
| 2 files changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/fs/pipe.c~pipe-make-poll_usage-boolean-and-annotate-its-access |
| +++ a/fs/pipe.c |
| @@ -653,7 +653,7 @@ pipe_poll(struct file *filp, poll_table |
| unsigned int head, tail; |
| |
| /* Epoll has some historical nasty semantics, this enables them */ |
| - pipe->poll_usage = 1; |
| + WRITE_ONCE(pipe->poll_usage, true); |
| |
| /* |
| * Reading pipe state only -- no need for acquiring the semaphore. |
| --- a/include/linux/pipe_fs_i.h~pipe-make-poll_usage-boolean-and-annotate-its-access |
| +++ a/include/linux/pipe_fs_i.h |
| @@ -71,7 +71,7 @@ struct pipe_inode_info { |
| unsigned int files; |
| unsigned int r_counter; |
| unsigned int w_counter; |
| - unsigned int poll_usage; |
| + bool poll_usage; |
| struct page *tmp_page; |
| struct fasync_struct *fasync_readers; |
| struct fasync_struct *fasync_writers; |
| _ |