From 3a701bf587a66774a3138f4f8701a2d516c8cd3e Mon Sep 17 00:00:00 2001 From: Patrick Farrell Date: Tue, 17 Oct 2023 10:54:13 -0400 Subject: [PATCH] EX-8421 llite: disable kernel readahead for pcc mmap Set ra_pages to 0 for PCC files when mmaped, because otherwise this setting carries through to Lustre and will cause crashes and possible inconsistencies. This happens because the PCC file and Lustre file share a mapping, which is a weird trick required to have mmap work on PCC. Add a set of asserts which confirm kernel readahead is disabled and wasn't used for mmap. Signed-off-by: Patrick Farrell Change-Id: I117042d68fac25158e8141c243acba698cf1930f Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/52732 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Qian Yingjin Reviewed-by: Andreas Dilger --- lustre/llite/pcc.c | 8 ++++++++ lustre/llite/rw.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/lustre/llite/pcc.c b/lustre/llite/pcc.c index 7997c09..0f8562c 100644 --- a/lustre/llite/pcc.c +++ b/lustre/llite/pcc.c @@ -3194,6 +3194,14 @@ int pcc_file_mmap(struct file *file, struct vm_area_struct *vma, if (!pcc_file || !file_inode(pcc_file)->i_fop->mmap) RETURN(0); + /* with PCC, the files are created in an unusual way, then we do some + * special magic with mmap to allow Lustre and PCC to share the mmap, + * so we must manually set the ra_pages or we can get kernel readahead + * occurring (which Lustre does not support) + */ + pcc_file->f_ra.ra_pages = 0; + file->f_ra.ra_pages = 0; + pcc_inode_lock(inode); pcci = ll_i2pcci(inode); if (pcci && pcc_inode_has_layout(pcci)) { diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index 44d2ef6..f628905 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -1885,10 +1885,12 @@ int ll_readpage(struct file *file, struct page *vmpage) struct inode *inode = file_inode(file); struct cl_object *clob = ll_i2info(inode)->lli_clob; struct ll_sb_info *sbi = ll_i2sbi(inode); + struct super_block *sb = inode->i_sb; const struct lu_env *env = NULL; struct cl_read_ahead ra = { 0 }; struct ll_cl_context *lcc; struct cl_io *io = NULL; + bool ra_assert = false; struct cl_page *page; int result; ENTRY; @@ -2033,6 +2035,32 @@ int ll_readpage(struct file *file, struct page *vmpage) } } + /* this is a sequence of checks verifying that kernel readahead is + * truly disabled + */ + if (lcc && lcc->lcc_type == LCC_MMAP) { + if (io->u.ci_fault.ft_index != vmpage->index) { + CERROR("ft_index %lu, vmpage index %lu\n", + io->u.ci_fault.ft_index, vmpage->index); + ra_assert = true; + } + } + + if (ra_assert || sb->s_bdi->ra_pages != 0 || file->f_ra.ra_pages != 0) { + CERROR("sbi ra pages %lu, file ra pages %d\n", + sb->s_bdi->ra_pages, file->f_ra.ra_pages); + ra_assert = true; + } + + +#ifdef HAVE_BDI_IO_PAGES + if (ra_assert || sb->s_bdi->io_pages != 0) { + CERROR("bdi io_pages %lu\n", sb->s_bdi->io_pages); + ra_assert = true; + } +#endif + if (ra_assert) + LBUG(); /** * Direct read can fall back to buffered read, but DIO is done * with lockless i/o, and buffered requires LDLM locking, so in -- 1.8.3.1