pipe_lock() and pipe_unlock() inspect pipe->files without inode->i_lock, while opening or closing a pipe changes the count under that lock. KCSAN reports these checks racing with put_pipe_info(). Only the zero/nonzero distinction matters here: a caller's file reference keeps the count nonzero for a regular pipe or FIFO, and an internal splice pipe has no files. Use data_race(READ_ONCE()) to document that distinction and take a single snapshot without changing the file-count writers. Fixes: 6447a3cf19da ("get rid of pipe->inode") Signed-off-by: Zhu Jun --- fs/pipe.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/pipe.c b/fs/pipe.c index 4fa69192e6fb..cdca0df67f90 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -87,14 +87,16 @@ static int pipe_lock_cmp_fn(const struct lockdep_map *a, void pipe_lock(struct pipe_inode_info *pipe) { - if (pipe->files) + /* A file reference keeps this nonzero; internal splice pipes stay zero. */ + if (data_race(READ_ONCE(pipe->files))) mutex_lock(&pipe->mutex); } EXPORT_SYMBOL(pipe_lock); void pipe_unlock(struct pipe_inode_info *pipe) { - if (pipe->files) + /* As in pipe_lock(), only the stable zero/nonzero distinction matters. */ + if (data_race(READ_ONCE(pipe->files))) mutex_unlock(&pipe->mutex); } EXPORT_SYMBOL(pipe_unlock); -- 2.51.0