summaryrefslogtreecommitdiff
path: root/mm/vmpressure.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/vmpressure.c')
-rw-r--r--mm/vmpressure.c22
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);
}