From 851962832b12201ee0d4969e9a7c5d0ccdff70ff Mon Sep 17 00:00:00 2001 From: Yang Sheng Date: Sat, 18 Sep 2021 13:34:19 +0800 Subject: [PATCH] EX-3808 pcc: reset file mapping for pcc copy The inode mapping of PCC copy will be replaced since mmap(). Then we must check & reset it while io starting. Else system will crash on: CPU: 3 PID: 31556 Comm: dd Kdump: loaded Tainted: P Call Trace: [] ll_readpage+0x4f3/0x870 [lustre] [] generic_file_aio_read+0x3f0/0x790 [] ext4_file_read+0x43/0x130 [ext4] [] pcc_file_read_iter+0x323/0x390 [lustre] [] ll_file_aio_read+0x1f2/0x510 [lustre] [] ? mmap_region+0x20c/0x670 [] ll_file_read+0x100/0x1c0 [lustre] [] vfs_read+0x9f/0x170 [] SyS_read+0x7f/0xf0 [] ? system_call_after_swapgs+0xae/0x146 [] system_call_fastpath+0x25/0x2a [] ? system_call_after_swapgs+0xae/0x146 Signed-off-by: Yang Sheng Change-Id: I719e9fac7362fe76f0ece399dda693b9e965c5bc Reviewed-on: https://review.whamcloud.com/45052 Tested-by: jenkins Reviewed-by: Yingjin Qian Reviewed-by: Andreas Dilger Tested-by: Andreas Dilger --- lustre/llite/pcc.c | 59 +++++++++++++++++++--------------------------- lustre/tests/mmap_cat.c | 4 +++- lustre/tests/sanity-pcc.sh | 36 +++++++--------------------- 3 files changed, 36 insertions(+), 63 deletions(-) diff --git a/lustre/llite/pcc.c b/lustre/llite/pcc.c index 2482d15..44edbb3 100644 --- a/lustre/llite/pcc.c +++ b/lustre/llite/pcc.c @@ -1555,7 +1555,7 @@ static int pcc_try_dataset_attach(struct inode *inode, __u32 gen, bool *cached) { struct ll_inode_info *lli = ll_i2info(inode); - struct pcc_inode *pcci = lli->lli_pcc_inode; + struct pcc_inode *pcci = ll_i2pcci(inode); const struct cred *old_cred; struct dentry *pcc_dentry; struct path path; @@ -2019,19 +2019,6 @@ static inline bool pcc_may_auto_attach(struct inode *inode, RETURN(lli->lli_pcc_dsflags & PCC_DATASET_IO_ATTACH); } -static void __pcc_layout_invalidate(struct pcc_inode *pcci) -{ - pcci->pcci_type = LU_PCC_NONE; - pcc_layout_gen_set(pcci, CL_LAYOUT_GEN_NONE); - if (atomic_read(&pcci->pcci_active_ios) == 0) - return; - - CDEBUG(D_CACHE, "Waiting for IO completion: %d\n", - atomic_read(&pcci->pcci_active_ios)); - wait_event_idle(pcci->pcci_waitq, - atomic_read(&pcci->pcci_active_ios) == 0); -} - static inline void pcc_inode_mmap_get(struct inode *inode) { pcc_inode_lock(inode); @@ -2046,6 +2033,11 @@ static inline void pcc_inode_mapping_reset(struct inode *inode) struct address_space *mapping = inode->i_mapping; int rc; + CDEBUG(D_CACHE, "Waiting for IO completion: %d\n", + atomic_read(&pcci->pcci_active_ios)); + wait_event_idle(pcci->pcci_waitq, + atomic_read(&pcci->pcci_active_ios) == 0); + /* Did we mmap this file? */ if (pcc_inode->i_mapping == &pcc_inode->i_data) return; @@ -2100,7 +2092,10 @@ static inline void pcc_inode_mmap_put(struct inode *inode) /* Call with inode lock held. */ static inline void pcc_inode_detach(struct inode *inode) { - __pcc_layout_invalidate(ll_i2pcci(inode)); + struct pcc_inode *pcci = ll_i2pcci(inode); + + pcci->pcci_type = LU_PCC_NONE; + pcc_layout_gen_set(pcci, CL_LAYOUT_GEN_NONE); pcc_inode_mapping_reset(inode); ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_PCC_DETACH, 1); } @@ -2170,7 +2165,8 @@ pcc_file_mapping_reset(struct inode *inode, struct file *file) struct file *pcc_file = ll_file2pccf(file)->pccf_file; struct inode *pcc_inode = pcci->pcci_path.dentry->d_inode; - if (pcc_inode->i_mapping == &pcc_inode->i_data) + if (pcc_file && pcc_inode && + pcc_inode->i_mapping == &pcc_inode->i_data) pcc_file->f_mapping = pcc_inode->i_mapping; } } @@ -2190,7 +2186,6 @@ static void pcc_io_init(struct inode *inode, enum pcc_io_type iot, *cached = false; pcc_inode_detach_put(inode); } else { - atomic_inc(&pcci->pcci_active_ios); *cached = true; } } else { @@ -2199,15 +2194,13 @@ static void pcc_io_init(struct inode *inode, enum pcc_io_type iot, * Forbid to auto PCC attach if the file has still been * mapped in PCC. */ - if (pcc_may_auto_attach(inode, iot)) { + if (pcc_may_auto_attach(inode, iot)) (void) pcc_try_auto_attach(inode, cached, iot); - if (*cached) { - pcci = ll_i2pcci(inode); - pcc_file_mapping_reset(inode, file); - LASSERT(atomic_read(&pcci->pcci_refcount) > 0); - atomic_inc(&pcci->pcci_active_ios); - } - } + } + if (*cached) { + pcci = ll_i2pcci(inode); + pcc_file_mapping_reset(inode, file); + atomic_inc(&pcci->pcci_active_ios); } pcc_inode_unlock(inode); } @@ -2710,6 +2703,7 @@ static void pcc_mmap_io_init(struct inode *inode, enum pcc_io_type iot, LASSERT(atomic_read(&pcci->pcci_refcount) > 0); + *cached = true; if (pcci->pcci_type == LU_PCC_READONLY && iot == PIT_PAGE_MKWRITE) { pcc_inode_detach_put(inode); @@ -2728,21 +2722,17 @@ static void pcc_mmap_io_init(struct inode *inode, enum pcc_io_type iot, pcc_inode_detach_put(inode); pcc_vma_file_reset(inode, vma); *cached = false; - } else { - atomic_inc(&pcci->pcci_active_ios); - *cached = true; } } - } else { - atomic_inc(&pcci->pcci_active_ios); - *cached = true; } } else { *cached = false; pcc_vma_file_reset(inode, vma); } - if (!*cached && !pccf->pccf_fallback) + if (*cached) + atomic_inc(&pcci->pcci_active_ios); + else if (!pccf->pccf_fallback) pcc_file_fallback_set(lli, pccf); pcc_inode_unlock(inode); @@ -3630,8 +3620,7 @@ int pcc_readwrite_attach(struct file *file, struct inode *inode, OBD_FAIL_TIMEOUT(OBD_FAIL_LLITE_PCC_ATTACH_PAUSE, cfs_fail_val); pcc_inode_lock(inode); - pcci = ll_i2pcci(inode); - LASSERT(!pcci); + LASSERT(ll_i2pcci(inode) == NULL); OBD_SLAB_ALLOC_PTR_GFP(pcci, pcc_inode_slab, GFP_NOFS); if (pcci == NULL) GOTO(out_unlock, rc = -ENOMEM); @@ -3984,7 +3973,7 @@ int pcc_ioctl_detach(struct inode *inode, __u32 *flags) ENTRY; pcc_inode_lock(inode); - pcci = lli->lli_pcc_inode; + pcci = ll_i2pcci(inode); if (lli->lli_pcc_state & PCC_STATE_FL_ATTACHING) { *flags |= PCC_DETACH_FL_ATTACHING; GOTO(out_unlock, rc = 0); diff --git a/lustre/tests/mmap_cat.c b/lustre/tests/mmap_cat.c index c739670..d98c6f3 100644 --- a/lustre/tests/mmap_cat.c +++ b/lustre/tests/mmap_cat.c @@ -64,6 +64,7 @@ int main(int argc, char **argv) int fd; void *mmappedData; int rc; + char buf[100]; if (argc != 2) { fprintf(stderr, usage, argv[0]); @@ -89,6 +90,8 @@ int main(int argc, char **argv) exit(save_errno); } + rc = read(fd, buf, 50); + /* Write the mmapped data to stdout (= FD #1) */ rc = write(1, mmappedData, filesize); if (rc == -1) { @@ -96,7 +99,6 @@ int main(int argc, char **argv) perror("write"); exit(save_errno); } - rc = munmap(mmappedData, filesize); if (rc == -1) { save_errno = errno; diff --git a/lustre/tests/sanity-pcc.sh b/lustre/tests/sanity-pcc.sh index 5cab684..37ecbc8 100644 --- a/lustre/tests/sanity-pcc.sh +++ b/lustre/tests/sanity-pcc.sh @@ -3765,11 +3765,7 @@ test_98() { do_facet $SINGLEAGT $LCTL set_param llite.*.pcc_async_threshold=0 local rpid1 - local rpid2 - local rpid3 local mpid1 - local mpid2 - local mpid3 local lpid1 local lpid2 @@ -3779,35 +3775,23 @@ test_98() { ( while [ ! -e $DIR/sanity-pcc.98.lck ]; do do_facet $SINGLEAGT dd if=$file of=/dev/null bs=1M count=50 || - error "Read $file failed" - sleep 0.$((RANDON % 4 + 1)) - done - )& - rpid1=$! - - ( - while [ ! -e $DIR/sanity-pcc.98.lck ]; do + error "Read $file failed" & do_facet $SINGLEAGT dd if=$file of=/dev/null bs=1M count=50 || - error "Read $file failed" - sleep 0.$((RANDON % 4 + 1)) - done - )& - rpid2=$! - - ( - while [ ! -e $DIR/sanity-pcc.98.lck ]; do + error "Read $file failed" & do_facet $SINGLEAGT dd if=$file of=/dev/null bs=1M count=50 || error "Read $file failed" - sleep 0.$((RANDON % 4 + 1)) + sleep 0.2 done )& - rpid3=$! + rpid1=$! ( while [ ! -e $DIR/sanity-pcc.98.lck ]; do do_facet $SINGLEAGT $MMAP_CAT $file > /dev/null || + error "$MMAP_CAT $file failed" & + do_facet $SINGLEAGT $MMAP_CAT $file > /dev/null || error "$MMAP_CAT $file failed" - sleep 0.$((RANDOM % 2 + 1)) + sleep 0.2 done )& mpid1=$! @@ -3816,7 +3800,7 @@ test_98() { while [ ! -e $DIR/sanity-pcc.98.lck ]; do do_facet $SINGLEAGT $LCTL set_param -n ldlm.namespaces.*mdc*.lru_size=clear || error "cancel_lru_locks mdc failed" - sleep 0.1 + sleep 0.5 done )& lpid1=$! @@ -3825,7 +3809,7 @@ test_98() { while [ ! -e $DIR/sanity-pcc.98.lck ]; do do_facet $SINGLEAGT $LCTL set_param -n ldlm.namespaces.*osc*.lru_size=clear || error "cancel_lru_locks mdc failed" - sleep 0.1 + sleep 0.5 done )& lpid2=$! @@ -3833,8 +3817,6 @@ test_98() { sleep 60 touch $DIR/sanity-pcc.98.lck wait $rpid1 || error "$?: read failed" - wait $rpid2 || error "$?: read failed" - wait $rpid3 || error "$?: read failed" wait $mpid1 || error "$?: mmap failed" wait $lpid1 || error "$?: cancel locks failed" wait $lpid2 || error "$?: cancel locks failed" -- 1.8.3.1