[RFC PATCH v4 04/16] mm/mglru: boost swappiness responsiveness in get_type_to_scan()

From: Barry Song (Xiaomi)

Date: Wed Aug 12 2026 - 08:34:41 EST


The linear weight in get_type_to_scan() can easily be overwhelmed
by historical refault costs when swappiness deviates from neutral (100).
As a result, user-configured swappiness often feels unresponsive under
memory pressure.

Apply a smooth quadratic boost based on the distance from the neutral
balance point (MAX_SWAPPINESS / 2). This amplifies the weight of the
preferred scanning type (anon vs file) while avoiding hardware division
via bitwise shift.

Assisted-by: gemini:gemini-3.6-flash
Signed-off-by: Barry Song (Xiaomi) <baohua@xxxxxxxxxx>
---
mm/vmscan.c | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index dddd2ecf970a..2fd1e06eb192 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -4838,18 +4838,42 @@ static int get_tier_idx(struct lruvec *lruvec, int type)
static int get_type_to_scan(struct lruvec *lruvec, int swappiness)
{
struct ctrl_pos sp, pv = {};
+ int anon_gain, file_gain;

if (swappiness <= MIN_SWAPPINESS + 1)
return LRU_GEN_FILE;

if (swappiness >= MAX_SWAPPINESS)
return LRU_GEN_ANON;
+
+ /*
+ * Apply a quadratic boost based on the distance from the neutral
+ * balance point (swappiness = MAX_SWAPPINESS / 2).
+ *
+ * A linear weight is easily overwhelmed by historical refault cost
+ * when swappiness deviates from neutral. The quadratic scaling
+ * amplifies the weight of the preferred type smoothly.
+ */
+ if (swappiness < MAX_SWAPPINESS / 2) {
+ int delta = (MAX_SWAPPINESS / 2) - swappiness;
+ int boost = (delta * delta) >> 4;
+
+ anon_gain = swappiness;
+ file_gain = (MAX_SWAPPINESS - swappiness) + boost;
+ } else {
+ int delta = swappiness - (MAX_SWAPPINESS / 2);
+ int boost = (delta * delta) >> 4;
+
+ anon_gain = swappiness + boost;
+ file_gain = MAX_SWAPPINESS - swappiness;
+ }
+
/*
* Compare the sum of all tiers of anon with that of file to determine
* which type to scan.
*/
- read_ctrl_pos(lruvec, LRU_GEN_ANON, MAX_NR_TIERS, swappiness, &sp);
- read_ctrl_pos(lruvec, LRU_GEN_FILE, MAX_NR_TIERS, MAX_SWAPPINESS - swappiness, &pv);
+ read_ctrl_pos(lruvec, LRU_GEN_ANON, MAX_NR_TIERS, anon_gain, &sp);
+ read_ctrl_pos(lruvec, LRU_GEN_FILE, MAX_NR_TIERS, file_gain, &pv);

return positive_ctrl_err(&sp, &pv);
}
--
2.34.1