mm/damon: introduce DAMOS filter type hugepage_size
authorUsama Arif <usamaarif642@gmail.com>
Tue, 11 Feb 2025 12:43:40 +0000 (12:43 +0000)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 17 Mar 2025 05:06:12 +0000 (22:06 -0700)
Patch series "mm/damon: add support for hugepage_size DAMOS filter", v5.

hugepage_size DAMOS filter can be used to gather statistics to check if
memory regions of specific access tempratures are backed by hugepages of a
size in a specific range.  This filter can help to observe and prove the
effectivenes of different schemes for shrinking/collapsing hugepages.

This patch (of 4):

This is to gather statistics to check if memory regions of specific access
tempratures are backed by pages of a size in a specific range.  This
filter can help to observe and prove the effectivenes of different schemes
for shrinking/collapsing hugepages.

[sj@kernel.org: add kernel-doc comment for damos_filter->sz_range]
Link: https://lkml.kernel.org/r/20250218223058.52459-1-sj@kernel.org
Link: https://lkml.kernel.org/r/20250211124437.278873-1-usamaarif642@gmail.com
Link: https://lkml.kernel.org/r/20250211124437.278873-2-usamaarif642@gmail.com
Signed-off-by: Usama Arif <usamaarif642@gmail.com>
Reviewed-by: SeongJae Park <sj@kernel.org>
Cc: David Hildenbrand <david@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Usama Arif <usamaarif642@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
include/linux/damon.h
mm/damon/core.c
mm/damon/paddr.c
mm/damon/sysfs-schemes.c

index b4d37d9b92212e8ba9006a91b34116b1672f4a4e..5e7ae7bca5dc47f1c934e80f1d42ef6e3ec3c8df 100644 (file)
@@ -35,6 +35,16 @@ struct damon_addr_range {
        unsigned long end;
 };
 
+/**
+ * struct damon_size_range - Represents size for filter to operate on [@min, @max].
+ * @min:       Min size (inclusive).
+ * @max:       Max size (inclusive).
+ */
+struct damon_size_range {
+       unsigned long min;
+       unsigned long max;
+};
+
 /**
  * struct damon_region - Represents a monitoring target region.
  * @ar:                        The address range of the region.
@@ -326,6 +336,7 @@ struct damos_stat {
  * @DAMOS_FILTER_TYPE_ANON:    Anonymous pages.
  * @DAMOS_FILTER_TYPE_MEMCG:   Specific memcg's pages.
  * @DAMOS_FILTER_TYPE_YOUNG:   Recently accessed pages.
+ * @DAMOS_FILTER_TYPE_HUGEPAGE_SIZE:   Page is part of a hugepage.
  * @DAMOS_FILTER_TYPE_ADDR:    Address range.
  * @DAMOS_FILTER_TYPE_TARGET:  Data Access Monitoring target.
  * @NR_DAMOS_FILTER_TYPES:     Number of filter types.
@@ -345,6 +356,7 @@ enum damos_filter_type {
        DAMOS_FILTER_TYPE_ANON,
        DAMOS_FILTER_TYPE_MEMCG,
        DAMOS_FILTER_TYPE_YOUNG,
+       DAMOS_FILTER_TYPE_HUGEPAGE_SIZE,
        DAMOS_FILTER_TYPE_ADDR,
        DAMOS_FILTER_TYPE_TARGET,
        NR_DAMOS_FILTER_TYPES,
@@ -360,6 +372,7 @@ enum damos_filter_type {
  * @target_idx:        Index of the &struct damon_target of
  *             &damon_ctx->adaptive_targets if @type is
  *             DAMOS_FILTER_TYPE_TARGET.
+ * @sz_range:  Size range if @type is DAMOS_FILTER_TYPE_HUGEPAGE_SIZE.
  * @list:      List head for siblings.
  *
  * Before applying the &damos->action to a memory region, DAMOS checks if each
@@ -376,6 +389,7 @@ struct damos_filter {
                unsigned short memcg_id;
                struct damon_addr_range addr_range;
                int target_idx;
+               struct damon_size_range sz_range;
        };
        struct list_head list;
 };
index f663c8e99dfa28862fa670b2fa46fe67bcc81fa8..b1ce072b56f22889ff822d2720690d33556da5d3 100644 (file)
@@ -777,6 +777,9 @@ static void damos_commit_filter_arg(
        case DAMOS_FILTER_TYPE_TARGET:
                dst->target_idx = src->target_idx;
                break;
+       case DAMOS_FILTER_TYPE_HUGEPAGE_SIZE:
+               dst->sz_range = src->sz_range;
+               break;
        default:
                break;
        }
index eb10a723b0a73e34de82652d27339771d6fc0ab6..1a5974640b93179ca7899c7ba6d80490fa2eb7a7 100644 (file)
@@ -211,6 +211,7 @@ static bool damos_pa_filter_match(struct damos_filter *filter,
 {
        bool matched = false;
        struct mem_cgroup *memcg;
+       size_t folio_sz;
 
        switch (filter->type) {
        case DAMOS_FILTER_TYPE_ANON:
@@ -230,6 +231,11 @@ static bool damos_pa_filter_match(struct damos_filter *filter,
                if (matched)
                        damon_folio_mkold(folio);
                break;
+       case DAMOS_FILTER_TYPE_HUGEPAGE_SIZE:
+               folio_sz = folio_size(folio);
+               matched = filter->sz_range.min <= folio_sz &&
+                         folio_sz <= filter->sz_range.max;
+               break;
        default:
                break;
        }
index 98f93ae9f59e7d6419f048315b605b56331fcfb6..9020bc9befac4f6fe2afb2f93eecab8f06be4c41 100644 (file)
@@ -329,6 +329,7 @@ static const char * const damon_sysfs_scheme_filter_type_strs[] = {
        "anon",
        "memcg",
        "young",
+       "hugepage_size",
        "addr",
        "target",
 };