diff options
Diffstat (limited to 'mm/vmpressure.c')
-rw-r--r-- | mm/vmpressure.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/mm/vmpressure.c b/mm/vmpressure.c index 0801e12fc3b7..b843993a9a7c 100644 --- a/mm/vmpressure.c +++ b/mm/vmpressure.c @@ -24,6 +24,7 @@ #include <linux/printk.h> #include <linux/notifier.h> #include <linux/init.h> +#include <linux/module.h> #include <linux/vmpressure.h> /* @@ -51,6 +52,10 @@ static const unsigned long vmpressure_win = SWAP_CLUSTER_MAX * 16; static const unsigned int vmpressure_level_med = 60; static const unsigned int vmpressure_level_critical = 95; +static unsigned long vmpressure_scale_max = 100; +module_param_named(vmpressure_scale_max, vmpressure_scale_max, + ulong, S_IRUGO | S_IWUSR); + static struct vmpressure global_vmpressure; BLOCKING_NOTIFIER_HEAD(vmpressure_notifier); @@ -157,6 +162,15 @@ static unsigned long vmpressure_calc_pressure(unsigned long scanned, return pressure; } +static unsigned long vmpressure_account_stall(unsigned long pressure, + unsigned long stall, unsigned long scanned) +{ + unsigned long scale = + ((vmpressure_scale_max - pressure) * stall) / scanned; + + return pressure + scale; +} + struct vmpressure_event { struct eventfd_ctx *efd; enum vmpressure_levels level; @@ -272,6 +286,7 @@ void vmpressure_global(gfp_t gfp, unsigned long scanned, { struct vmpressure *vmpr = &global_vmpressure; unsigned long pressure; + unsigned long stall; if (!(gfp & (__GFP_HIGHMEM | __GFP_MOVABLE | __GFP_IO | __GFP_FS))) return; @@ -282,6 +297,11 @@ void vmpressure_global(gfp_t gfp, unsigned long scanned, spin_lock(&vmpr->sr_lock); vmpr->scanned += scanned; vmpr->reclaimed += reclaimed; + + if (!current_is_kswapd()) + vmpr->stall += scanned; + + stall = vmpr->stall; scanned = vmpr->scanned; reclaimed = vmpr->reclaimed; spin_unlock(&vmpr->sr_lock); @@ -292,9 +312,11 @@ void vmpressure_global(gfp_t gfp, unsigned long scanned, spin_lock(&vmpr->sr_lock); vmpr->scanned = 0; vmpr->reclaimed = 0; + vmpr->stall = 0; spin_unlock(&vmpr->sr_lock); pressure = vmpressure_calc_pressure(scanned, reclaimed); + pressure = vmpressure_account_stall(pressure, stall, scanned); vmpressure_notify(pressure); } |