Message ID | 1641395025-7922-1-git-send-email-quic_charante@quicinc.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [v3] mm: shmem: implement POSIX_FADV_[WILL|DONT]NEED for shmem | expand |
Hi Charan, Thank you for the patch! Yet something to improve: [auto build test ERROR on hnaz-mm/master] url: https://github.com/0day-ci/linux/commits/Charan-Teja-Reddy/mm-shmem-implement-POSIX_FADV_-WILL-DONT-NEED-for-shmem/20220105-230604 base: https://github.com/hnaz/linux-mm master config: nds32-allnoconfig (https://download.01.org/0day-ci/archive/20220106/202201060232.K03lKwTH-lkp@intel.com/config) compiler: nds32le-linux-gcc (GCC) 11.2.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/6bdb2636187d2f6cb78d6cdc05f2b7e0b79c750a git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Charan-Teja-Reddy/mm-shmem-implement-POSIX_FADV_-WILL-DONT-NEED-for-shmem/20220105-230604 git checkout 6bdb2636187d2f6cb78d6cdc05f2b7e0b79c750a # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=nds32 SHELL=/bin/bash If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): >> mm/shmem.c:4000:27: error: 'shmem_fadvise' undeclared here (not in a function); did you mean 'shmem_file'? 4000 | .fadvise = shmem_fadvise, | ^~~~~~~~~~~~~ | shmem_file vim +4000 mm/shmem.c 3987 3988 static const struct file_operations shmem_file_operations = { 3989 .mmap = shmem_mmap, 3990 .get_unmapped_area = shmem_get_unmapped_area, 3991 #ifdef CONFIG_TMPFS 3992 .llseek = shmem_file_llseek, 3993 .read_iter = shmem_file_read_iter, 3994 .write_iter = generic_file_write_iter, 3995 .fsync = noop_fsync, 3996 .splice_read = generic_file_splice_read, 3997 .splice_write = iter_file_splice_write, 3998 .fallocate = shmem_fallocate, 3999 #endif > 4000 .fadvise = shmem_fadvise, 4001 }; 4002 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Charan, Thank you for the patch! Yet something to improve: [auto build test ERROR on hnaz-mm/master] url: https://github.com/0day-ci/linux/commits/Charan-Teja-Reddy/mm-shmem-implement-POSIX_FADV_-WILL-DONT-NEED-for-shmem/20220105-230604 base: https://github.com/hnaz/linux-mm master config: hexagon-randconfig-r013-20220105 (https://download.01.org/0day-ci/archive/20220106/202201061353.4vrJlOAk-lkp@intel.com/config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project d5b6e30ed3acad794dd0aec400e617daffc6cc3d) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/6bdb2636187d2f6cb78d6cdc05f2b7e0b79c750a git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Charan-Teja-Reddy/mm-shmem-implement-POSIX_FADV_-WILL-DONT-NEED-for-shmem/20220105-230604 git checkout 6bdb2636187d2f6cb78d6cdc05f2b7e0b79c750a # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): >> mm/shmem.c:4000:13: error: use of undeclared identifier 'shmem_fadvise'; did you mean 'shmem_file'? .fadvise = shmem_fadvise, ^~~~~~~~~~~~~ shmem_file include/linux/shmem_fs.h:118:20: note: 'shmem_file' declared here static inline bool shmem_file(struct file *file) ^ >> mm/shmem.c:4000:13: error: incompatible function pointer types initializing 'int (*)(struct file *, loff_t, loff_t, int)' (aka 'int (*)(struct file *, long long, long long, int)') with an expression of type 'bool (struct file *)' (aka '_Bool (struct file *)') [-Werror,-Wincompatible-function-pointer-types] .fadvise = shmem_fadvise, ^~~~~~~~~~~~~ 2 errors generated. vim +4000 mm/shmem.c 3987 3988 static const struct file_operations shmem_file_operations = { 3989 .mmap = shmem_mmap, 3990 .get_unmapped_area = shmem_get_unmapped_area, 3991 #ifdef CONFIG_TMPFS 3992 .llseek = shmem_file_llseek, 3993 .read_iter = shmem_file_read_iter, 3994 .write_iter = generic_file_write_iter, 3995 .fsync = noop_fsync, 3996 .splice_read = generic_file_splice_read, 3997 .splice_write = iter_file_splice_write, 3998 .fallocate = shmem_fallocate, 3999 #endif > 4000 .fadvise = shmem_fadvise, 4001 }; 4002 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/mm/shmem.c b/mm/shmem.c index 18f93c2..35c3161 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -39,6 +39,8 @@ #include <linux/frontswap.h> #include <linux/fs_parser.h> #include <linux/swapfile.h> +#include <linux/mm_inline.h> +#include <linux/fadvise.h> static struct vfsmount *shm_mnt; @@ -2791,6 +2793,175 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset, return error; } +static void shmem_isolate_pages_range(struct address_space *mapping, loff_t start, + loff_t end, struct list_head *list) +{ + XA_STATE(xas, &mapping->i_pages, start); + struct page *page; + + rcu_read_lock(); + xas_for_each(&xas, page, end) { + if (xas_retry(&xas, page)) + continue; + if (xa_is_value(page)) + continue; + if (!get_page_unless_zero(page)) + continue; + if (isolate_lru_page(page)) + continue; + + list_add(&page->lru, list); + __mod_node_page_state(page_pgdat(page), + NR_ISOLATED_ANON + page_is_file_lru(page), compound_nr(page)); + put_page(page); + if (need_resched()) { + xas_pause(&xas); + cond_resched_rcu(); + } + } + rcu_read_unlock(); +} + +static int shmem_fadvise_dontneed(struct address_space *mapping, loff_t start, + loff_t end) +{ + int ret; + struct page *page; + LIST_HEAD(list); + struct writeback_control wbc = { + .sync_mode = WB_SYNC_NONE, + .nr_to_write = LONG_MAX, + .range_start = 0, + .range_end = LLONG_MAX, + .for_reclaim = 1, + }; + + if (!shmem_mapping(mapping)) + return -EINVAL; + + if (!total_swap_pages) + return 0; + + lru_add_drain(); + shmem_isolate_pages_range(mapping, start, end, &list); + + while (!list_empty(&list)) { + page = lru_to_page(&list); + list_del(&page->lru); + if (page_mapped(page)) + goto keep; + if (!trylock_page(page)) + goto keep; + if (unlikely(PageTransHuge(page))) { + if (split_huge_page_to_list(page, &list)) + goto keep; + } + + clear_page_dirty_for_io(page); + SetPageReclaim(page); + ret = shmem_writepage(page, &wbc); + if (ret || PageWriteback(page)) { + if (ret) + unlock_page(page); + goto keep; + } + + if (!PageWriteback(page)) + ClearPageReclaim(page); + + /* + * shmem_writepage() place the page in the swapcache. + * Delete the page from the swapcache and release the + * page. + */ + __mod_node_page_state(page_pgdat(page), + NR_ISOLATED_ANON + page_is_file_lru(page), compound_nr(page)); + lock_page(page); + delete_from_swap_cache(page); + unlock_page(page); + put_page(page); + continue; +keep: + putback_lru_page(page); + __mod_node_page_state(page_pgdat(page), + NR_ISOLATED_ANON + page_is_file_lru(page), compound_nr(page)); + } + + return 0; +} + +static int shmem_fadvise_willneed(struct address_space *mapping, + pgoff_t start, pgoff_t long end) +{ + XA_STATE(xas, &mapping->i_pages, start); + struct page *page; + + rcu_read_lock(); + xas_for_each(&xas, page, end) { + if (!xa_is_value(page)) + continue; + xas_pause(&xas); + rcu_read_unlock(); + + page = shmem_read_mapping_page(mapping, xas.xa_index); + if (!IS_ERR(page)) + put_page(page); + + rcu_read_lock(); + if (need_resched()) { + xas_pause(&xas); + cond_resched_rcu(); + } + } + rcu_read_unlock(); + + return 0; +} + +static int shmem_fadvise(struct file *file, loff_t offset, loff_t len, int advice) +{ + loff_t endbyte; + pgoff_t start_index; + pgoff_t end_index; + struct address_space *mapping; + int ret = 0; + + mapping = file->f_mapping; + if (!mapping || len < 0) + return -EINVAL; + + endbyte = (u64)offset + (u64)len; + if (!len || endbyte < len) + endbyte = -1; + else + endbyte--; + + + start_index = offset >> PAGE_SHIFT; + end_index = endbyte >> PAGE_SHIFT; + switch (advice) { + case POSIX_FADV_DONTNEED: + ret = shmem_fadvise_dontneed(mapping, start_index, end_index); + break; + case POSIX_FADV_WILLNEED: + ret = shmem_fadvise_willneed(mapping, start_index, end_index); + break; + case POSIX_FADV_NORMAL: + case POSIX_FADV_RANDOM: + case POSIX_FADV_SEQUENTIAL: + case POSIX_FADV_NOREUSE: + /* + * No bad return value, but ignore advice. May have to + * implement in future. + */ + break; + default: + return -EINVAL; + } + + return ret; +} + static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf) { struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb); @@ -3777,6 +3948,7 @@ static const struct file_operations shmem_file_operations = { .splice_write = iter_file_splice_write, .fallocate = shmem_fallocate, #endif + .fadvise = shmem_fadvise, }; static const struct inode_operations shmem_inode_operations = {