]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mm/damon/lru_sort: support young page filters
authorSeongJae Park <sj@kernel.org>
Tue, 13 Jan 2026 15:27:11 +0000 (07:27 -0800)
committerAndrew Morton <akpm@linux-foundation.org>
Tue, 27 Jan 2026 04:02:30 +0000 (20:02 -0800)
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>
mm/damon/lru_sort.c

index a74c4ec170a953277c8a623b93a2af8a08e53e0c..f1fdb37b9b47c8d8fe93df1aa0fae6398db826b6 100644 (file)
@@ -41,6 +41,21 @@ static bool enabled __read_mostly;
 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.
  *
@@ -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,