directory and inode objects. With vfs_cache_pressure=1000, it will look for
 ten times more freeable objects than there are.
 
+=============================================================
+
+watermark_scale_factor:
+
+This factor controls the aggressiveness of kswapd. It defines the
+amount of memory left in a node/system before kswapd is woken up and
+how much memory needs to be free before kswapd goes back to sleep.
+
+The unit is in fractions of 10,000. The default value of 10 means the
+distances between watermarks are 0.1% of the available memory in the
+node/system. The maximum value is 1000, or 10% of memory.
+
+A high rate of threads entering direct reclaim (allocstall) or kswapd
+going to sleep prematurely (kswapd_low_wmark_hit_quickly) can indicate
+that the number of free pages kswapd maintains for latency reasons is
+too small for the allocation bursts occurring in the system. This knob
+can then be used to tune kswapd aggressiveness accordingly.
+
 ==============================================================
 
 zone_reclaim_mode:
 
 
 /* page_alloc.c */
 extern int min_free_kbytes;
+extern int watermark_scale_factor;
 
 /* nommu.c */
 extern atomic_long_t mmap_pages_allocated;
 
 struct ctl_table;
 int min_free_kbytes_sysctl_handler(struct ctl_table *, int,
                                        void __user *, size_t *, loff_t *);
+int watermark_scale_factor_sysctl_handler(struct ctl_table *, int,
+                                       void __user *, size_t *, loff_t *);
 extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1];
 int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int,
                                        void __user *, size_t *, loff_t *);
 
 static int __maybe_unused four = 4;
 static unsigned long one_ul = 1;
 static int one_hundred = 100;
+static int one_thousand = 1000;
 #ifdef CONFIG_PRINTK
 static int ten_thousand = 10000;
 #endif
                .proc_handler   = min_free_kbytes_sysctl_handler,
                .extra1         = &zero,
        },
+       {
+               .procname       = "watermark_scale_factor",
+               .data           = &watermark_scale_factor,
+               .maxlen         = sizeof(watermark_scale_factor),
+               .mode           = 0644,
+               .proc_handler   = watermark_scale_factor_sysctl_handler,
+               .extra1         = &one,
+               .extra2         = &one_thousand,
+       },
        {
                .procname       = "percpu_pagelist_fraction",
                .data           = &percpu_pagelist_fraction,
 
 
 int min_free_kbytes = 1024;
 int user_min_free_kbytes = -1;
+int watermark_scale_factor = 10;
 
 static unsigned long __meminitdata nr_kernel_pages;
 static unsigned long __meminitdata nr_all_pages;
                        zone->watermark[WMARK_MIN] = tmp;
                }
 
-               zone->watermark[WMARK_LOW]  = min_wmark_pages(zone) + (tmp >> 2);
-               zone->watermark[WMARK_HIGH] = min_wmark_pages(zone) + (tmp >> 1);
+               /*
+                * Set the kswapd watermarks distance according to the
+                * scale factor in proportion to available memory, but
+                * ensure a minimum size on small systems.
+                */
+               tmp = max_t(u64, tmp >> 2,
+                           mult_frac(zone->managed_pages,
+                                     watermark_scale_factor, 10000));
+
+               zone->watermark[WMARK_LOW]  = min_wmark_pages(zone) + tmp;
+               zone->watermark[WMARK_HIGH] = min_wmark_pages(zone) + tmp * 2;
 
                __mod_zone_page_state(zone, NR_ALLOC_BATCH,
                        high_wmark_pages(zone) - low_wmark_pages(zone) -
        return 0;
 }
 
+int watermark_scale_factor_sysctl_handler(struct ctl_table *table, int write,
+       void __user *buffer, size_t *length, loff_t *ppos)
+{
+       int rc;
+
+       rc = proc_dointvec_minmax(table, write, buffer, length, ppos);
+       if (rc)
+               return rc;
+
+       if (write)
+               setup_per_zone_wmarks();
+
+       return 0;
+}
+
 #ifdef CONFIG_NUMA
 int sysctl_min_unmapped_ratio_sysctl_handler(struct ctl_table *table, int write,
        void __user *buffer, size_t *length, loff_t *ppos)