All of lore.kernel.org
 help / color / mirror / Atom feed
From: Huan Yang <link@vivo.com>
To: SeongJae Park <sj@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	linux-kernel@vger.kernel.org (open list),
	damon@lists.linux.dev (open list:DATA ACCESS MONITOR),
	linux-mm@kvack.org (open list:DATA ACCESS MONITOR)
Cc: opensource.kernel@vivo.com, Huan Yang <link@vivo.com>
Subject: [RFC 1/2] mm/damos/filter: Add workingset page filter
Date: Tue, 19 Sep 2023 17:52:34 +0800	[thread overview]
Message-ID: <20230919095237.26613-2-link@vivo.com> (raw)
In-Reply-To: <20230919095237.26613-1-link@vivo.com>

Some page if marked as workingset, we'd better not touch it.
So, for damon pa scheme, this patch just add an new filter
DAMOS_FILTER_TYPE_WORKINGSET, which will filter page if it
marked as workingset.

Like skip anon, add a control skip_workingset.

To make code clean, fold reclaim's filter create logic into
__damon_reclaim_create_filters.

Signed-off-by: Huan Yang <link@vivo.com>
---
 include/linux/damon.h | 17 +++++++++-------
 mm/damon/core-test.h  |  7 +++++++
 mm/damon/paddr.c      |  4 ++++
 mm/damon/reclaim.c    | 47 ++++++++++++++++++++++++++++++++++---------
 4 files changed, 58 insertions(+), 17 deletions(-)

diff --git a/include/linux/damon.h b/include/linux/damon.h
index ae2664d1d5f1..8e8f35df6a5e 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -228,22 +228,25 @@ struct damos_stat {
  * @DAMOS_FILTER_TYPE_MEMCG:	Specific memcg's pages.
  * @DAMOS_FILTER_TYPE_ADDR:	Address range.
  * @DAMOS_FILTER_TYPE_TARGET:	Data Access Monitoring target.
+ * @DAMOS_FILTER_TYPE_WORKINGSET: Workingset pages, need protect.
  * @NR_DAMOS_FILTER_TYPES:	Number of filter types.
  *
- * The anon pages type and memcg type filters are handled by underlying
- * &struct damon_operations as a part of scheme action trying, and therefore
- * accounted as 'tried'.  In contrast, other types are handled by core layer
- * before trying of the action and therefore not accounted as 'tried'.
+ * The anon pages type, memcg type, workingset page type filters are handled
+ * by underlying &struct damon_operations as a part of scheme action trying,
+ * and therefore accounted as 'tried'.  In contrast, other types are handled
+ * by core layer before trying of the action and therefore not accounted as
+ * 'tried'.
  *
  * The support of the filters that handled by &struct damon_operations depend
  * on the running &struct damon_operations.
- * &enum DAMON_OPS_PADDR supports both anon pages type and memcg type filters,
- * while &enum DAMON_OPS_VADDR and &enum DAMON_OPS_FVADDR don't support any of
- * the two types.
+ * &enum DAMON_OPS_PADDR supports both anon pages type, memcg type and
+ * workingset page type filters, while &enum DAMON_OPS_VADDR and &enum
+ * DAMON_OPS_FVADDR don't support any of the two types.
  */
 enum damos_filter_type {
 	DAMOS_FILTER_TYPE_ANON,
 	DAMOS_FILTER_TYPE_MEMCG,
+	DAMOS_FILTER_TYPE_WORKINGSET,
 	DAMOS_FILTER_TYPE_ADDR,
 	DAMOS_FILTER_TYPE_TARGET,
 	NR_DAMOS_FILTER_TYPES,
diff --git a/mm/damon/core-test.h b/mm/damon/core-test.h
index 6cc8b245586d..c752e6e3cf3e 100644
--- a/mm/damon/core-test.h
+++ b/mm/damon/core-test.h
@@ -351,6 +351,13 @@ static void damos_test_new_filter(struct kunit *test)
 	KUNIT_EXPECT_PTR_EQ(test, filter->list.prev, &filter->list);
 	KUNIT_EXPECT_PTR_EQ(test, filter->list.next, &filter->list);
 	damos_destroy_filter(filter);
+
+	filter = damos_new_filter(DAMOS_FILTER_TYPE_WORKINGSET, true);
+	KUNIT_EXPECT_EQ(test, filter->type, DAMOS_FILTER_TYPE_WORKINGSET);
+	KUNIT_EXPECT_EQ(test, filter->matching, true);
+	KUNIT_EXPECT_PTR_EQ(test, filter->list.prev, &filter->list);
+	KUNIT_EXPECT_PTR_EQ(test, filter->list.next, &filter->list);
+	damos_destroy_filter(filter);
 }
 
 static void damos_test_filter_out(struct kunit *test)
diff --git a/mm/damon/paddr.c b/mm/damon/paddr.c
index 909db25efb35..8a690505e033 100644
--- a/mm/damon/paddr.c
+++ b/mm/damon/paddr.c
@@ -12,6 +12,7 @@
 #include <linux/pagemap.h>
 #include <linux/rmap.h>
 #include <linux/swap.h>
+#include <linux/mm_inline.h>
 
 #include "../internal.h"
 #include "ops-common.h"
@@ -204,6 +205,9 @@ static bool __damos_pa_filter_out(struct damos_filter *filter,
 			matched = filter->memcg_id == mem_cgroup_id(memcg);
 		rcu_read_unlock();
 		break;
+	case DAMOS_FILTER_TYPE_WORKINGSET:
+		matched = folio_test_workingset(folio);
+		break;
 	default:
 		break;
 	}
diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c
index 648d2a85523a..26ae8fa5d088 100644
--- a/mm/damon/reclaim.c
+++ b/mm/damon/reclaim.c
@@ -107,6 +107,15 @@ module_param(monitor_region_end, ulong, 0600);
 static bool skip_anon __read_mostly;
 module_param(skip_anon, bool, 0600);
 
+/*
+ * Skip workingset pages reclamation.
+ *
+ * If this parameter is set as ``Y``, DAMON_RECLAIM does not reclaim workingset
+ * pages.  By default, ``N``.
+ */
+static bool skip_workingset __read_mostly;
+module_param(skip_workingset, bool, 0600);
+
 /*
  * PID of the DAMON thread
  *
@@ -148,10 +157,25 @@ static struct damos *damon_reclaim_new_scheme(void)
 			&damon_reclaim_wmarks);
 }
 
+static int __damon_reclaim_create_filters(struct damos *scheme,
+					  enum damos_filter_type type,
+					  bool matching)
+{
+	struct damos_filter *filter = damos_new_filter(type, matching);
+
+	if (unlikely(!filter)) {
+		/* Will be freed by next 'damon_set_schemes()' below */
+		damon_destroy_scheme(scheme);
+		return -ENOMEM;
+	}
+
+	damos_add_filter(scheme, filter);
+	return 0;
+}
+
 static int damon_reclaim_apply_parameters(void)
 {
 	struct damos *scheme;
-	struct damos_filter *filter;
 	int err = 0;
 
 	err = damon_set_attrs(ctx, &damon_reclaim_mon_attrs);
@@ -162,15 +186,18 @@ static int damon_reclaim_apply_parameters(void)
 	scheme = damon_reclaim_new_scheme();
 	if (!scheme)
 		return -ENOMEM;
-	if (skip_anon) {
-		filter = damos_new_filter(DAMOS_FILTER_TYPE_ANON, true);
-		if (!filter) {
-			/* Will be freed by next 'damon_set_schemes()' below */
-			damon_destroy_scheme(scheme);
-			return -ENOMEM;
-		}
-		damos_add_filter(scheme, filter);
-	}
+
+	err = skip_anon && __damon_reclaim_create_filters(
+				   scheme, DAMOS_FILTER_TYPE_ANON, true);
+	if (err)
+		return err;
+
+	err = skip_workingset &&
+	      __damon_reclaim_create_filters(
+		      scheme, DAMOS_FILTER_TYPE_WORKINGSET, true);
+	if (err)
+		return err;
+
 	damon_set_schemes(ctx, &scheme, 1);
 
 	return damon_set_region_biggest_system_ram_default(target,
-- 
2.34.1


  reply	other threads:[~2023-09-19  9:53 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-19  9:52 [RFC 0/2] Damos filter cleanup code and implement workingset Huan Yang
2023-09-19  9:52 ` Huan Yang [this message]
2023-09-19  9:52 ` [RFC 2/2] mm/damos/filter: Damos filter cleanup Huan Yang
2023-09-21 19:36 ` [RFC 0/2] Damos filter cleanup code and implement workingset SeongJae Park
2023-09-22  2:54   ` 杨欢
2023-09-22 22:15     ` SeongJae Park
2023-09-25  2:10       ` 杨欢
2023-09-25 15:53         ` SeongJae Park

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230919095237.26613-2-link@vivo.com \
    --to=link@vivo.com \
    --cc=akpm@linux-foundation.org \
    --cc=damon@lists.linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=opensource.kernel@vivo.com \
    --cc=sj@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.