From b4c141326236cf02276e32117e2490dc29a8d214 Mon Sep 17 00:00:00 2001 From: Qian Yingjin Date: Thu, 7 Nov 2024 11:40:38 +0800 Subject: [PATCH] LU-18430 llite: disable readahead on file with random fadvise If a file is advised with random access pattern via posix_fadvise with POSIX_FADV_RANDOM mode, the client should not trigger read-ahead on this file. Add posix_fadvise option 'i' for "multiop". Add "forceread_pages" stats into llite.*.read_ahead_stats to account the force read (random) pages. Add the test case sanity/test_853 to verify it. Signed-off-by: Qian Yingjin Change-Id: Ie02ace55985c92abffb871184f847400e9da03ad Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/56912 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Alexey Lyashkov Reviewed-by: Oleg Drokin Reviewed-by: Andreas Dilger --- lustre/llite/llite_internal.h | 1 + lustre/llite/lproc_llite.c | 6 ++++-- lustre/llite/rw.c | 7 +++++++ lustre/tests/multiop.c | 9 +++++++++ lustre/tests/sanity.sh | 29 +++++++++++++++++++++++++++++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 8455e2d..eae98ef 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -762,6 +762,7 @@ enum ra_stat { RA_STAT_FAILED_FAST_READ, RA_STAT_MMAP_RANGE_READ, RA_STAT_READAHEAD_PAGES, + RA_STAT_FORCEREAD_PAGES, _NR_RA_STAT, }; diff --git a/lustre/llite/lproc_llite.c b/lustre/llite/lproc_llite.c index 82da954..de36407 100644 --- a/lustre/llite/lproc_llite.c +++ b/lustre/llite/lproc_llite.c @@ -2602,7 +2602,8 @@ static const char *const ra_stat_string[] = { [RA_STAT_ASYNC] = "async_readahead", [RA_STAT_FAILED_FAST_READ] = "failed_to_fast_read", [RA_STAT_MMAP_RANGE_READ] = "mmap_range_read", - [RA_STAT_READAHEAD_PAGES] = "readahead_pages" + [RA_STAT_READAHEAD_PAGES] = "readahead_pages", + [RA_STAT_FORCEREAD_PAGES] = "forceread_pages" }; int ll_debugfs_register_super(struct super_block *sb, const char *name) @@ -2668,7 +2669,8 @@ int ll_debugfs_register_super(struct super_block *sb, const char *name) GOTO(out_stats, err = -ENOMEM); for (id = 0; id < ARRAY_SIZE(ra_stat_string); id++) { - if (id == RA_STAT_READAHEAD_PAGES) + if (id == RA_STAT_READAHEAD_PAGES || + id == RA_STAT_FORCEREAD_PAGES) lprocfs_counter_init(sbi->ll_ra_stats, id, LPROCFS_TYPE_PAGES | LPROCFS_CNTR_AVGMINMAX, diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index 62fdd11..9eb2461 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -951,6 +951,10 @@ static int ll_readpages(const struct lu_env *env, struct cl_io *io, count++; } + if (count) + ll_ra_stats_add(vvp_object_inode(io->ci_obj), + RA_STAT_FORCEREAD_PAGES, count); + RETURN(count > 0 ? count : ret); } @@ -1721,6 +1725,9 @@ int ll_io_read_page(const struct lu_env *env, struct cl_io *io, if (file) { lfd = file->private_data; ras = &lfd->fd_ras; + + if (file->f_mode & FMODE_RANDOM) + io->ci_rand_read = 1; } /* PagePrivate2 is set in ll_io_zero_page() to tell us the vmpage diff --git a/lustre/tests/multiop.c b/lustre/tests/multiop.c index 82b91be..4c5a7dc 100644 --- a/lustre/tests/multiop.c +++ b/lustre/tests/multiop.c @@ -83,6 +83,7 @@ char usage[] = " g gid put grouplock\n" " H[num] create HSM released file with num stripes\n" " I fiemap\n" +" i random fadvise\n" " K link path to filename\n" " L link\n" " l symlink filename to path\n" @@ -515,6 +516,14 @@ int main(int argc, char **argv) case 'I': do_fiemap(fd); break; + case 'i': + rc = posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM); + if (rc) { + save_errno = errno; + perror("fadvise"); + exit(save_errno); + } + break; case 'j': if (flock(fd, LOCK_EX) == -1) errx(-1, "flock()"); diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 3546d95..14c2ee1 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -33820,6 +33820,35 @@ test_852() { } run_test 852 "mkdir using intent lock for striped directory" +test_853() { + local file=$DIR/$tfile + local size=$((PAGE_SIZE * 2)) + + dd if=/dev/zero of=$file bs=1M count=100 || + error "failed to write $file" + cancel_lru_locks $OSC + $LCTL set_param llite.*.read_ahead_stats=clear + $MULTIOP $file or1048576c || error "failed to read $file" + $LCTL get_param llite.*.read_ahead_stats + + cancel_lru_locks $OSC + $LCTL set_param llite.*.read_ahead_stats=clear + $MULTIOP $file oir1048576z1048576r${size}c || + error "failed to read $file" + $LCTL get_param llite.*.read_ahead_stats + + local ranum=$($LCTL get_param -n llite.*.read_ahead_stats | + get_named_value 'readahead.pages' | calc_sum) + + (( ranum == 0 )) || error "should not trigger readahead" + + local rndnum=$($LCTL get_param -n llite.*.read_ahead_stats | + get_named_value 'forceread.pages' | calc_sum) + + (( rndnum == 2 )) || error "force random read: $rndnum, expected 2" +} +run_test 853 "Verify that random fadvise works as expected" + # # tests that do cleanup/setup should be run at the end # -- 1.8.3.1