|
@@ -249,6 +249,7 @@ compound_page_dtor * const compound_page_dtors[] = {
|
|
|
|
|
|
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;
|
|
@@ -6347,8 +6348,17 @@ static void __setup_per_zone_wmarks(void)
|
|
|
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) -
|
|
@@ -6489,6 +6499,21 @@ int min_free_kbytes_sysctl_handler(struct ctl_table *table, int write,
|
|
|
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)
|