Re: [PATCH] mm/vmscan: add sysctl knobs for protecting the specified

From: kernel test robot
Date: Mon Apr 05 2021 - 21:17:10 EST


Hi Alexey,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linux/master]
[also build test WARNING on linus/master v5.12-rc6 next-20210401]
[cannot apply to hnaz-linux-mm/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Alexey-Avramov/mm-vmscan-add-sysctl-knobs-for-protecting-the-specified/20210406-061034
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 5e46d1b78a03d52306f21f77a4e4a144b6d31486
config: s390-randconfig-r006-20210405 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project a46f59a747a7273cc439efaf3b4f98d8b63d2f20)
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
# install s390 cross compiling tool for clang build
# apt-get install binutils-s390x-linux-gnu
# https://github.com/0day-ci/linux/commit/a5eeb8d197a8e10c333422e9cc0f2c7d976a3426
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Alexey-Avramov/mm-vmscan-add-sysctl-knobs-for-protecting-the-specified/20210406-061034
git checkout a5eeb8d197a8e10c333422e9cc0f2c7d976a3426
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=s390

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@xxxxxxxxx>

All warnings (new ones prefixed by >>):

In file included from mm/vmscan.c:20:
In file included from include/linux/swap.h:9:
In file included from include/linux/memcontrol.h:22:
In file included from include/linux/writeback.h:14:
In file included from include/linux/blk-cgroup.h:23:
In file included from include/linux/blkdev.h:26:
In file included from include/linux/scatterlist.h:9:
In file included from arch/s390/include/asm/io.h:80:
include/asm-generic/io.h:464:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
val = __raw_readb(PCI_IOBASE + addr);
~~~~~~~~~~ ^
include/asm-generic/io.h:477:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
~~~~~~~~~~ ^
include/uapi/linux/byteorder/big_endian.h:36:59: note: expanded from macro '__le16_to_cpu'
#define __le16_to_cpu(x) __swab16((__force __u16)(__le16)(x))
^
include/uapi/linux/swab.h:102:54: note: expanded from macro '__swab16'
#define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
^
In file included from mm/vmscan.c:20:
In file included from include/linux/swap.h:9:
In file included from include/linux/memcontrol.h:22:
In file included from include/linux/writeback.h:14:
In file included from include/linux/blk-cgroup.h:23:
In file included from include/linux/blkdev.h:26:
In file included from include/linux/scatterlist.h:9:
In file included from arch/s390/include/asm/io.h:80:
include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
~~~~~~~~~~ ^
include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
#define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
^
include/uapi/linux/swab.h:115:54: note: expanded from macro '__swab32'
#define __swab32(x) (__u32)__builtin_bswap32((__u32)(x))
^
In file included from mm/vmscan.c:20:
In file included from include/linux/swap.h:9:
In file included from include/linux/memcontrol.h:22:
In file included from include/linux/writeback.h:14:
In file included from include/linux/blk-cgroup.h:23:
In file included from include/linux/blkdev.h:26:
In file included from include/linux/scatterlist.h:9:
In file included from arch/s390/include/asm/io.h:80:
include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
__raw_writeb(value, PCI_IOBASE + addr);
~~~~~~~~~~ ^
include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
__raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
~~~~~~~~~~ ^
include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
__raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
~~~~~~~~~~ ^
include/asm-generic/io.h:609:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
readsb(PCI_IOBASE + addr, buffer, count);
~~~~~~~~~~ ^
include/asm-generic/io.h:617:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
readsw(PCI_IOBASE + addr, buffer, count);
~~~~~~~~~~ ^
include/asm-generic/io.h:625:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
readsl(PCI_IOBASE + addr, buffer, count);
~~~~~~~~~~ ^
include/asm-generic/io.h:634:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
writesb(PCI_IOBASE + addr, buffer, count);
~~~~~~~~~~ ^
include/asm-generic/io.h:643:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
writesw(PCI_IOBASE + addr, buffer, count);
~~~~~~~~~~ ^
include/asm-generic/io.h:652:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
writesl(PCI_IOBASE + addr, buffer, count);
~~~~~~~~~~ ^
>> mm/vmscan.c:2819:7: warning: variable 'clean' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
if (reclaimable_file > dirty)
^~~~~~~~~~~~~~~~~~~~~~~~
mm/vmscan.c:2822:25: note: uninitialized use occurs here
sc->clean_below_low = clean < sysctl_clean_low_kbytes;
^~~~~
mm/vmscan.c:2819:3: note: remove the 'if' if its condition is always true
if (reclaimable_file > dirty)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mm/vmscan.c:2812:47: note: initialize the variable 'clean' to silence this warning
unsigned long reclaimable_file, dirty, clean;
^
= 0
13 warnings generated.


vim +2819 mm/vmscan.c

2706
2707 static void shrink_node(pg_data_t *pgdat, struct scan_control *sc)
2708 {
2709 struct reclaim_state *reclaim_state = current->reclaim_state;
2710 unsigned long nr_reclaimed, nr_scanned;
2711 struct lruvec *target_lruvec;
2712 bool reclaimable = false;
2713 unsigned long file;
2714
2715 target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat);
2716
2717 again:
2718 memset(&sc->nr, 0, sizeof(sc->nr));
2719
2720 nr_reclaimed = sc->nr_reclaimed;
2721 nr_scanned = sc->nr_scanned;
2722
2723 /*
2724 * Determine the scan balance between anon and file LRUs.
2725 */
2726 spin_lock_irq(&target_lruvec->lru_lock);
2727 sc->anon_cost = target_lruvec->anon_cost;
2728 sc->file_cost = target_lruvec->file_cost;
2729 spin_unlock_irq(&target_lruvec->lru_lock);
2730
2731 /*
2732 * Target desirable inactive:active list ratios for the anon
2733 * and file LRU lists.
2734 */
2735 if (!sc->force_deactivate) {
2736 unsigned long refaults;
2737
2738 refaults = lruvec_page_state(target_lruvec,
2739 WORKINGSET_ACTIVATE_ANON);
2740 if (refaults != target_lruvec->refaults[0] ||
2741 inactive_is_low(target_lruvec, LRU_INACTIVE_ANON))
2742 sc->may_deactivate |= DEACTIVATE_ANON;
2743 else
2744 sc->may_deactivate &= ~DEACTIVATE_ANON;
2745
2746 /*
2747 * When refaults are being observed, it means a new
2748 * workingset is being established. Deactivate to get
2749 * rid of any stale active pages quickly.
2750 */
2751 refaults = lruvec_page_state(target_lruvec,
2752 WORKINGSET_ACTIVATE_FILE);
2753 if (refaults != target_lruvec->refaults[1] ||
2754 inactive_is_low(target_lruvec, LRU_INACTIVE_FILE))
2755 sc->may_deactivate |= DEACTIVATE_FILE;
2756 else
2757 sc->may_deactivate &= ~DEACTIVATE_FILE;
2758 } else
2759 sc->may_deactivate = DEACTIVATE_ANON | DEACTIVATE_FILE;
2760
2761 /*
2762 * If we have plenty of inactive file pages that aren't
2763 * thrashing, try to reclaim those first before touching
2764 * anonymous pages.
2765 */
2766 file = lruvec_page_state(target_lruvec, NR_INACTIVE_FILE);
2767 if (file >> sc->priority && !(sc->may_deactivate & DEACTIVATE_FILE))
2768 sc->cache_trim_mode = 1;
2769 else
2770 sc->cache_trim_mode = 0;
2771
2772 /*
2773 * Prevent the reclaimer from falling into the cache trap: as
2774 * cache pages start out inactive, every cache fault will tip
2775 * the scan balance towards the file LRU. And as the file LRU
2776 * shrinks, so does the window for rotation from references.
2777 * This means we have a runaway feedback loop where a tiny
2778 * thrashing file LRU becomes infinitely more attractive than
2779 * anon pages. Try to detect this based on file LRU size.
2780 */
2781 if (!cgroup_reclaim(sc)) {
2782 unsigned long total_high_wmark = 0;
2783 unsigned long free, anon;
2784 int z;
2785
2786 free = sum_zone_node_page_state(pgdat->node_id, NR_FREE_PAGES);
2787 file = node_page_state(pgdat, NR_ACTIVE_FILE) +
2788 node_page_state(pgdat, NR_INACTIVE_FILE);
2789
2790 for (z = 0; z < MAX_NR_ZONES; z++) {
2791 struct zone *zone = &pgdat->node_zones[z];
2792 if (!managed_zone(zone))
2793 continue;
2794
2795 total_high_wmark += high_wmark_pages(zone);
2796 }
2797
2798 /*
2799 * Consider anon: if that's low too, this isn't a
2800 * runaway file reclaim problem, but rather just
2801 * extreme pressure. Reclaim as per usual then.
2802 */
2803 anon = node_page_state(pgdat, NR_INACTIVE_ANON);
2804
2805 sc->file_is_tiny =
2806 file + free <= total_high_wmark &&
2807 !(sc->may_deactivate & DEACTIVATE_ANON) &&
2808 anon >> sc->priority;
2809 }
2810
2811 if (sysctl_clean_low_kbytes || sysctl_clean_min_kbytes) {
2812 unsigned long reclaimable_file, dirty, clean;
2813
2814 reclaimable_file =
2815 node_page_state(pgdat, NR_ACTIVE_FILE) +
2816 node_page_state(pgdat, NR_INACTIVE_FILE) +
2817 node_page_state(pgdat, NR_ISOLATED_FILE);
2818 dirty = node_page_state(pgdat, NR_FILE_DIRTY);
> 2819 if (reclaimable_file > dirty)
2820 clean = (reclaimable_file - dirty) << (PAGE_SHIFT - 10);
2821
2822 sc->clean_below_low = clean < sysctl_clean_low_kbytes;
2823 sc->clean_below_min = clean < sysctl_clean_min_kbytes;
2824 } else {
2825 sc->clean_below_low = false;
2826 sc->clean_below_min = false;
2827 }
2828
2829 shrink_node_memcgs(pgdat, sc);
2830
2831 if (reclaim_state) {
2832 sc->nr_reclaimed += reclaim_state->reclaimed_slab;
2833 reclaim_state->reclaimed_slab = 0;
2834 }
2835
2836 /* Record the subtree's reclaim efficiency */
2837 vmpressure(sc->gfp_mask, sc->target_mem_cgroup, true,
2838 sc->nr_scanned - nr_scanned,
2839 sc->nr_reclaimed - nr_reclaimed);
2840
2841 if (sc->nr_reclaimed - nr_reclaimed)
2842 reclaimable = true;
2843
2844 if (current_is_kswapd()) {
2845 /*
2846 * If reclaim is isolating dirty pages under writeback,
2847 * it implies that the long-lived page allocation rate
2848 * is exceeding the page laundering rate. Either the
2849 * global limits are not being effective at throttling
2850 * processes due to the page distribution throughout
2851 * zones or there is heavy usage of a slow backing
2852 * device. The only option is to throttle from reclaim
2853 * context which is not ideal as there is no guarantee
2854 * the dirtying process is throttled in the same way
2855 * balance_dirty_pages() manages.
2856 *
2857 * Once a node is flagged PGDAT_WRITEBACK, kswapd will
2858 * count the number of pages under pages flagged for
2859 * immediate reclaim and stall if any are encountered
2860 * in the nr_immediate check below.
2861 */
2862 if (sc->nr.writeback && sc->nr.writeback == sc->nr.taken)
2863 set_bit(PGDAT_WRITEBACK, &pgdat->flags);
2864
2865 /* Allow kswapd to start writing pages during reclaim.*/
2866 if (sc->nr.unqueued_dirty == sc->nr.file_taken)
2867 set_bit(PGDAT_DIRTY, &pgdat->flags);
2868
2869 /*
2870 * If kswapd scans pages marked for immediate
2871 * reclaim and under writeback (nr_immediate), it
2872 * implies that pages are cycling through the LRU
2873 * faster than they are written so also forcibly stall.
2874 */
2875 if (sc->nr.immediate)
2876 congestion_wait(BLK_RW_ASYNC, HZ/10);
2877 }
2878
2879 /*
2880 * Tag a node/memcg as congested if all the dirty pages
2881 * scanned were backed by a congested BDI and
2882 * wait_iff_congested will stall.
2883 *
2884 * Legacy memcg will stall in page writeback so avoid forcibly
2885 * stalling in wait_iff_congested().
2886 */
2887 if ((current_is_kswapd() ||
2888 (cgroup_reclaim(sc) && writeback_throttling_sane(sc))) &&
2889 sc->nr.dirty && sc->nr.dirty == sc->nr.congested)
2890 set_bit(LRUVEC_CONGESTED, &target_lruvec->flags);
2891
2892 /*
2893 * Stall direct reclaim for IO completions if underlying BDIs
2894 * and node is congested. Allow kswapd to continue until it
2895 * starts encountering unqueued dirty pages or cycling through
2896 * the LRU too quickly.
2897 */
2898 if (!current_is_kswapd() && current_may_throttle() &&
2899 !sc->hibernation_mode &&
2900 test_bit(LRUVEC_CONGESTED, &target_lruvec->flags))
2901 wait_iff_congested(BLK_RW_ASYNC, HZ/10);
2902
2903 if (should_continue_reclaim(pgdat, sc->nr_reclaimed - nr_reclaimed,
2904 sc))
2905 goto again;
2906
2907 /*
2908 * Kswapd gives up on balancing particular nodes after too
2909 * many failures to reclaim anything from them and goes to
2910 * sleep. On reclaim progress, reset the failure counter. A
2911 * successful direct reclaim run will revive a dormant kswapd.
2912 */
2913 if (reclaimable)
2914 pgdat->kswapd_failures = 0;
2915 }
2916

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx

Attachment: .config.gz
Description: application/gzip