From 5dc37c619b4a250dfd12f8ff4d58a72e07f0ec3c Mon Sep 17 00:00:00 2001 From: wangdi <wangdi> Date: Thu, 30 Oct 2008 21:46:32 +0000 Subject: [PATCH] Branch: HEAD Once the unmatched stride IO mode is detected, shrink the stride-ahead window to 0. if it does hit cache miss, and read-pattern is still stride-io mode, does not reset the stride window, but also does not increase the stride window length in this case. b=17197 i=Nikita i=Andreas --- lustre/ChangeLog | 8 +++ lustre/llite/rw.c | 121 ++++++++++++++++++++++------------------------ 2 files changed, 66 insertions(+), 63 deletions(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 9cc3e32919..8cc4fcb23a 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -1743,6 +1743,14 @@ Details : Checks validity of on-disk block bitmap. Also it does better checking of number of applied preallocations. When corruption is found, it turns filesystem readonly to prevent further corruptions. +Severity : normal +Bugzilla : 17197 +Description: (rw.c:1323:ll_read_ahead_pages()) ASSERTION(page_idx > ria->ria_stoff) failed +Details : Once the unmatched stride IO mode is detected, shrink the stride-ahead + window to 0. If it does hit cache miss, and read-pattern is still + stride-io mode, does not reset the stride window, but also does not + increase the stride window length in this case. + -------------------------------------------------------------------------------- 2007-08-10 Cluster File Systems, Inc. <info@clusterfs.com> diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index f6813408a9..6a2be0ad01 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -1697,6 +1697,8 @@ static void ras_reset(struct ll_readahead_state *ras, unsigned long index) static void ras_stride_reset(struct ll_readahead_state *ras) { ras->ras_consecutive_stride_requests = 0; + ras->ras_stride_length = 0; + ras->ras_stride_pages = 0; RAS_CDEBUG(ras); } @@ -1708,46 +1710,39 @@ void ll_readahead_init(struct inode *inode, struct ll_readahead_state *ras) INIT_LIST_HEAD(&ras->ras_read_beads); } -/* Check whether the read request is in the stride window. +/* + * Check whether the read request is in the stride window. * If it is in the stride window, return 1, otherwise return 0. - * and also update stride_gap and stride_pages. */ static int index_in_stride_window(unsigned long index, struct ll_readahead_state *ras, struct inode *inode) { - int stride_gap = index - ras->ras_last_readpage - 1; + unsigned long stride_gap = index - ras->ras_last_readpage - 1; + + if (ras->ras_stride_length == 0 || ras->ras_stride_pages == 0) + return 0; - LASSERT(stride_gap != 0); + /* If it is contiguous read */ + if (stride_gap == 0) + return ras->ras_consecutive_pages + 1 <= ras->ras_stride_pages; - if (ras->ras_consecutive_pages == 0) - return 0; + /* Otherwise check the stride by itself */ + return (ras->ras_stride_length - ras->ras_stride_pages) == stride_gap && + ras->ras_consecutive_pages == ras->ras_stride_pages; +} - /*Otherwise check the stride by itself */ - if ((ras->ras_stride_length - ras->ras_stride_pages) == stride_gap && - ras->ras_consecutive_pages == ras->ras_stride_pages) - return 1; +static void ras_update_stride_detector(struct ll_readahead_state *ras, + unsigned long index) +{ + unsigned long stride_gap = index - ras->ras_last_readpage - 1; - if (stride_gap >= 0) { - /* - * only set stride_pages, stride_length if - * it is forward reading ( stride_gap > 0) - */ + if (!stride_io_mode(ras) && (stride_gap != 0 || + ras->ras_consecutive_stride_requests == 0)) { ras->ras_stride_pages = ras->ras_consecutive_pages; - ras->ras_stride_length = stride_gap + ras->ras_consecutive_pages; - } else { - /* - * If stride_gap < 0,(back_forward reading), - * reset the stride_pages/length. - * FIXME:back_ward stride I/O read. - * - */ - ras->ras_stride_pages = 0; - ras->ras_stride_length = 0; + ras->ras_stride_length = stride_gap +ras->ras_consecutive_pages; } RAS_CDEBUG(ras); - - return 0; } static unsigned long @@ -1819,7 +1814,7 @@ static void ras_update(struct ll_sb_info *sbi, struct inode *inode, unsigned hit) { struct ll_ra_info *ra = &sbi->ll_ra_info; - int zero = 0, stride_zero = 0, stride_detect = 0, ra_miss = 0; + int zero = 0, stride_detect = 0, ra_miss = 0; ENTRY; spin_lock(&ras->ras_lock); @@ -1834,20 +1829,11 @@ static void ras_update(struct ll_sb_info *sbi, struct inode *inode, if (!index_in_window(index, ras->ras_last_readpage, 8, 8)) { zero = 1; ll_ra_stats_inc_sbi(sbi, RA_STAT_DISTANT_READPAGE); - /* check whether it is in stride I/O mode*/ - if (!index_in_stride_window(index, ras, inode)) - stride_zero = 1; } else if (!hit && ras->ras_window_len && index < ras->ras_next_readahead && index_in_window(index, ras->ras_window_start, 0, ras->ras_window_len)) { - zero = 1; ra_miss = 1; - /* If it hits read-ahead miss and the stride I/O is still - * not detected, reset stride stuff to re-detect the whole - * stride I/O mode to avoid complication */ - if (!stride_io_mode(ras)) - stride_zero = 1; ll_ra_stats_inc_sbi(sbi, RA_STAT_MISS_IN_WINDOW); } @@ -1876,42 +1862,51 @@ static void ras_update(struct ll_sb_info *sbi, struct inode *inode, GOTO(out_unlock, 0); } } - if (zero) { - /* If it is discontinuous read, check - * whether it is stride I/O mode*/ - if (stride_zero) { + /* check whether it is in stride I/O mode*/ + if (!index_in_stride_window(index, ras, inode)) { ras_reset(ras, index); ras->ras_consecutive_pages++; ras_stride_reset(ras); - RAS_CDEBUG(ras); GOTO(out_unlock, 0); } else { - /* The read is still in stride window or - * it hits read-ahead miss */ - - /* If ra-window miss is hitted, which probably means VM - * pressure, and some read-ahead pages were reclaimed.So - * the length of ra-window will not increased, but also - * not reset to avoid redetecting the stride I/O mode.*/ - ras->ras_consecutive_requests = 0; - if (!ra_miss) { - ras->ras_consecutive_pages = 0; - if (++ras->ras_consecutive_stride_requests > 1) - stride_detect = 1; - } + ras->ras_consecutive_requests = 0; + if (++ras->ras_consecutive_stride_requests > 1) + stride_detect = 1; RAS_CDEBUG(ras); } - } else if (ras->ras_consecutive_stride_requests > 1) { - /* If this is contiguous read but in stride I/O mode - * currently, check whether stride step still is valid, - * if invalid, it will reset the stride ra window*/ - if (ras->ras_consecutive_pages + 1 > ras->ras_stride_pages) - ras_stride_reset(ras); + } else { + if (ra_miss) { + if (index_in_stride_window(index, ras, inode) && + stride_io_mode(ras)) { + /*If stride-RA hit cache miss, the stride dector + *will not be reset to avoid the overhead of + *redetecting read-ahead mode */ + if (index != ras->ras_last_readpage + 1) + ras->ras_consecutive_pages = 0; + RAS_CDEBUG(ras); + } else { + /* Reset both stride window and normal RA window */ + ras_reset(ras, index); + ras->ras_consecutive_pages++; + ras_stride_reset(ras); + GOTO(out_unlock, 0); + } + } else if (stride_io_mode(ras)) { + /* If this is contiguous read but in stride I/O mode + * currently, check whether stride step still is valid, + * if invalid, it will reset the stride ra window*/ + if (!index_in_stride_window(index, ras, inode)) { + /* Shrink stride read-ahead window to be zero */ + ras_stride_reset(ras); + ras->ras_window_len = 0; + ras->ras_next_readahead = index; + } + } } - - ras->ras_last_readpage = index; ras->ras_consecutive_pages++; + ras_update_stride_detector(ras, index); + ras->ras_last_readpage = index; ras_set_start(ras, index); ras->ras_next_readahead = max(ras->ras_window_start, ras->ras_next_readahead); -- GitLab