summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeongJae Park <sj@kernel.org>2026-01-13 07:27:11 -0800
committerAndrew Morton <akpm@linux-foundation.org>2026-01-26 20:02:30 -0800
commit303dbb1f08cfe844d095fe008bd4d04e89d447f1 (patch)
treeb0a63db71ab889dadd5930cdc4d87adc2f17bfc1
parent57d96d1ad2ccb29f0b8d67acd79e2f978bf165c4 (diff)
mm/damon/lru_sort: support young page filters
DAMON monitors access patterns at the region level, and hence there could be some page level mismatches. A few hot pages could be located in cold regions, and vice versa. Young page filters can be useful for doing additional page level access checks before applying some DAMOS action. DAMON_LRU_SORT is not using young page filters, though. Add a parameter for using it. Link: https://lkml.kernel.org/r/20260113152717.70459-7-sj@kernel.org Signed-off-by: SeongJae Park <sj@kernel.org> Cc: David Hildenbrand <david@kernel.org> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Liam Howlett <liam.howlett@oracle.com> Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Cc: Michal Hocko <mhocko@suse.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-rw-r--r--mm/damon/lru_sort.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c
index a74c4ec170a9..f1fdb37b9b47 100644
--- a/mm/damon/lru_sort.c
+++ b/mm/damon/lru_sort.c
@@ -42,6 +42,21 @@ static bool commit_inputs __read_mostly;
module_param(commit_inputs, bool, 0600);
/*
+ * Filter [non-]young pages accordingly for LRU [de]prioritizations.
+ *
+ * If this is set, check page level access (youngness) once again before each
+ * LRU [de]prioritization operation. LRU prioritization operation is skipped
+ * if the page has not accessed since the last check (not young). LRU
+ * deprioritization operation is skipped if the page has accessed since the
+ * last check (young). The feature is enabled or disabled if this parameter is
+ * set as ``Y`` or ``N``, respectively.
+ *
+ * Disabled by default.
+ */
+static bool filter_young_pages __read_mostly;
+module_param(filter_young_pages, bool, 0600);
+
+/*
* Access frequency threshold for hot memory regions identification in permil.
*
* If a memory region is accessed in frequency of this or higher,
@@ -193,6 +208,28 @@ static struct damos *damon_lru_sort_new_cold_scheme(unsigned int cold_thres)
return damon_lru_sort_new_scheme(&pattern, DAMOS_LRU_DEPRIO);
}
+static int damon_lru_sort_add_filters(struct damos *hot_scheme,
+ struct damos *cold_scheme)
+{
+ struct damos_filter *filter;
+
+ if (!filter_young_pages)
+ return 0;
+
+ /* disallow prioritizing not-young pages */
+ filter = damos_new_filter(DAMOS_FILTER_TYPE_YOUNG, false, false);
+ if (!filter)
+ return -ENOMEM;
+ damos_add_filter(hot_scheme, filter);
+
+ /* disabllow de-prioritizing young pages */
+ filter = damos_new_filter(DAMOS_FILTER_TYPE_YOUNG, true, false);
+ if (!filter)
+ return -ENOMEM;
+ damos_add_filter(cold_scheme, filter);
+ return 0;
+}
+
static int damon_lru_sort_apply_parameters(void)
{
struct damon_ctx *param_ctx;
@@ -240,6 +277,10 @@ static int damon_lru_sort_apply_parameters(void)
damon_set_schemes(param_ctx, &hot_scheme, 1);
damon_add_scheme(param_ctx, cold_scheme);
+ err = damon_lru_sort_add_filters(hot_scheme, cold_scheme);
+ if (err)
+ goto out;
+
err = damon_set_region_biggest_system_ram_default(param_target,
&monitor_region_start,
&monitor_region_end,