DAMON development mailing list
 help / color / mirror / Atom feed
* [RFC PATCH 00/10] mm/damon/core: hide core-private struct fields
@ 2026-07-14  4:34 SJ Park
  2026-07-14  4:34 ` [RFC PATCH 01/10] mm/damon/core: hide private damon_region fields SJ Park
                   ` (9 more replies)
  0 siblings, 10 replies; 14+ messages in thread
From: SJ Park @ 2026-07-14  4:34 UTC (permalink / raw)
  Cc: SJ Park, Andrew Morton, damon, linux-kernel, linux-mm

DAMON core structs hide core-private fields using 'private:' comment
tags.  It is incomplete and inconsistent.  The linked list heads in a
few structs, for example, are intended to be hidden, and always be used
using the wrapper macros like damon_for_each_region().  But those were
mistakenly marked as non-private.  A few core layer-only fields were
also mistakenly added as non-private.

This only encourages callers to directly use the private fields.  It is
easy to make mistakes, and difficult to control.  Mark all such DAMON
core struct fields as private.

Patches 1-8 mark the private fields for damon_region, damon_target,
damos_quota_goal, damos_quota, damos_filter, damos, damon_filter and
damon_probe, respectively.  Patch 9 removes DAMON_SYSFS's direct access
to core-private field, damon_ctx->ops.  Finally patch 10 mark the
private fields for damon_ctx.

SJ Park (10):
  mm/damon/core: hide private damon_region fields
  mm/damon/core: hide private damon_target fields
  mm/damon/core: hide private damos_quota_goal fields
  mm/damon/core: hide private damos_quota fields
  mm/damon/core: hide private damos_filter fields
  mm/damon/core: hide private damos fields
  mm/damon/core: hide private damon_filter fields
  mm/damon/core: hide private damon_probe fields
  mm/damon/sysfs: do not directly access damon_ctx->ops
  mm/damon/core: hide core-private damon_ctx fields

 include/linux/damon.h | 110 +++++++++++++++++++++++-------------------
 mm/damon/sysfs.c      |   2 +-
 2 files changed, 62 insertions(+), 50 deletions(-)


base-commit: ddf3f75c217672edd46466c9156d64abf5119b68
-- 
2.47.3

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [RFC PATCH 01/10] mm/damon/core: hide private damon_region fields
  2026-07-14  4:34 [RFC PATCH 00/10] mm/damon/core: hide core-private struct fields SJ Park
@ 2026-07-14  4:34 ` SJ Park
  2026-07-14  4:34 ` [RFC PATCH 02/10] mm/damon/core: hide private damon_target fields SJ Park
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: SJ Park @ 2026-07-14  4:34 UTC (permalink / raw)
  Cc: SJ Park, damon, linux-kernel, linux-mm

damon_region->list is intended to be used by only the DAMON core layer.
But it is mistakenly not marked as private.  Hide it from the callers by
marking it private.

Signed-off-by: SJ Park <sj@kernel.org>
---
 include/linux/damon.h | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/include/linux/damon.h b/include/linux/damon.h
index f69442a9d4312..d32377e7e535e 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -46,7 +46,6 @@ struct damon_size_range {
  * @sampling_addr:	Address of the sample for the next access check.
  * @nr_accesses:	Access frequency of this region.
  * @probe_hits:		Number of probe-positive region samples.
- * @list:		List head for siblings.
  * @age:		Age of this region.
  *
  * For any use case, @ar should be non-zero positive size.  damon_set_regions()
@@ -68,9 +67,11 @@ struct damon_region {
 	unsigned long sampling_addr;
 	unsigned int nr_accesses;
 	unsigned char probe_hits[DAMON_MAX_PROBES];
-	struct list_head list;
 	unsigned int age;
-/* private: Internal value for age calculation. */
+/* private: internal use only. */
+	/* List head for siblings. */
+	struct list_head list;
+	/* for age calculation. */
 	unsigned int last_nr_accesses;
 	unsigned char last_probe_hits[DAMON_MAX_PROBES];
 };
-- 
2.47.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 02/10] mm/damon/core: hide private damon_target fields
  2026-07-14  4:34 [RFC PATCH 00/10] mm/damon/core: hide core-private struct fields SJ Park
  2026-07-14  4:34 ` [RFC PATCH 01/10] mm/damon/core: hide private damon_region fields SJ Park
@ 2026-07-14  4:34 ` SJ Park
  2026-07-14  4:34 ` [RFC PATCH 03/10] mm/damon/core: hide private damos_quota_goal fields SJ Park
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: SJ Park @ 2026-07-14  4:34 UTC (permalink / raw)
  Cc: SJ Park, damon, linux-kernel, linux-mm

'nr_regions', 'regions_list' and 'list' fields of damon_target are
intended to be used by only the DAMON core layer.  Those are mistakenly
not marked as private.  Mark as private.

Signed-off-by: SJ Park <sj@kernel.org>
---
 include/linux/damon.h | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/include/linux/damon.h b/include/linux/damon.h
index d32377e7e535e..6e160557a0014 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -79,9 +79,6 @@ struct damon_region {
 /**
  * struct damon_target - Represents a monitoring target.
  * @pid:		The PID of the virtual address space to monitor.
- * @nr_regions:		Number of monitoring target regions of this target.
- * @regions_list:	Head of the monitoring target regions of this target.
- * @list:		List head for siblings.
  * @obsolete:		Whether the commit destination target is obsolete.
  *
  * Each monitoring context could have multiple targets.  For example, a context
@@ -95,10 +92,14 @@ struct damon_region {
  */
 struct damon_target {
 	struct pid *pid;
+	bool obsolete;
+/* private: */
+	/* Number of monitoring target regions of this target. */
 	unsigned int nr_regions;
+	/* Head of the monitoring target regions of this target. */
 	struct list_head regions_list;
+	/* List head for siblings. */
 	struct list_head list;
-	bool obsolete;
 };
 
 /**
-- 
2.47.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 03/10] mm/damon/core: hide private damos_quota_goal fields
  2026-07-14  4:34 [RFC PATCH 00/10] mm/damon/core: hide core-private struct fields SJ Park
  2026-07-14  4:34 ` [RFC PATCH 01/10] mm/damon/core: hide private damon_region fields SJ Park
  2026-07-14  4:34 ` [RFC PATCH 02/10] mm/damon/core: hide private damon_target fields SJ Park
@ 2026-07-14  4:34 ` SJ Park
  2026-07-14  4:34 ` [RFC PATCH 04/10] mm/damon/core: hide private damos_quota fields SJ Park
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: SJ Park @ 2026-07-14  4:34 UTC (permalink / raw)
  Cc: SJ Park, damon, linux-kernel, linux-mm

'last_psi_total' and 'list' of damos_quota_goal are intended to be used
by only the DAMON core layer.  Those are mistakenly not marked as
private, though.  Mark as private.

Signed-off-by: SJ Park <sj@kernel.org>
---
 include/linux/damon.h | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/include/linux/damon.h b/include/linux/damon.h
index 6e160557a0014..d838cc27ee72a 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -175,10 +175,8 @@ enum damos_quota_goal_metric {
  * @metric:		Metric to be used for representing the goal.
  * @target_value:	Target value of @metric to achieve with the tuning.
  * @current_value:	Current value of @metric.
- * @last_psi_total:	Last measured total PSI
  * @nid:		Node id.
  * @memcg_id:		Memcg id.
- * @list:		List head for siblings.
  *
  * Data structure for getting the current score of the quota tuning goal.  The
  * score is calculated by how close @current_value and @target_value are.  Then
@@ -201,12 +199,17 @@ struct damos_quota_goal {
 	unsigned long current_value;
 	/* metric-dependent fields */
 	union {
-		u64 last_psi_total;
 		struct {
 			int nid;
 			u64 memcg_id;
 		};
+/* private: */
+		/* Last measured total PSI */
+		u64 last_psi_total;
+
 	};
+/* private: */
+	/* List head for siblings. */
 	struct list_head list;
 };
 
-- 
2.47.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 04/10] mm/damon/core: hide private damos_quota fields
  2026-07-14  4:34 [RFC PATCH 00/10] mm/damon/core: hide core-private struct fields SJ Park
                   ` (2 preceding siblings ...)
  2026-07-14  4:34 ` [RFC PATCH 03/10] mm/damon/core: hide private damos_quota_goal fields SJ Park
@ 2026-07-14  4:34 ` SJ Park
  2026-07-14  4:34 ` [RFC PATCH 05/10] mm/damon/core: hide private damos_filter fields SJ Park
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: SJ Park @ 2026-07-14  4:34 UTC (permalink / raw)
  Cc: SJ Park, damon, linux-kernel, linux-mm

damos_quota->goals is intended to be used by only the DAMON core layer.
But it is mistakenly not marked as private.  Mark as private.

Signed-off-by: SJ Park <sj@kernel.org>
---
 include/linux/damon.h | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/include/linux/damon.h b/include/linux/damon.h
index d838cc27ee72a..bd024b89adfa3 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -228,7 +228,6 @@ enum damos_quota_goal_tuner {
  * @reset_interval:	Charge reset interval in milliseconds.
  * @ms:			Maximum milliseconds that the scheme can use.
  * @sz:			Maximum bytes of memory that the action can be applied.
- * @goals:		Head of quota tuning goals (&damos_quota_goal) list.
  * @goal_tuner:		Goal-based @esz tuning algorithm to use.
  * @esz:		Effective size quota in bytes.
  * @fail_charge_num:	Failed regions charge rate numerator.
@@ -255,7 +254,7 @@ enum damos_quota_goal_tuner {
  * the scheme's action.  DAMON then compares it against &sz and uses smaller
  * one as the effective quota.
  *
- * If @goals is not empty, DAMON calculates yet another size quota based on the
+ * If goals is not empty, DAMON calculates yet another size quota based on the
  * goals using its internal feedback loop algorithm, for every @reset_interval.
  * Then, if the new size quota is smaller than the effective quota, it uses the
  * new size quota as the effective quota.
@@ -276,7 +275,7 @@ struct damos_quota {
 	unsigned long reset_interval;
 	unsigned long ms;
 	unsigned long sz;
-	struct list_head goals;
+
 	enum damos_quota_goal_tuner goal_tuner;
 	unsigned long esz;
 
@@ -288,6 +287,8 @@ struct damos_quota {
 	unsigned int weight_age;
 
 /* private: */
+	/* Head of quota tuning goals (&damos_quota_goal) list. */
+	struct list_head goals;
 	/* For throughput estimation */
 	unsigned long total_charged_sz;
 	unsigned long total_charged_ns;
-- 
2.47.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 05/10] mm/damon/core: hide private damos_filter fields
  2026-07-14  4:34 [RFC PATCH 00/10] mm/damon/core: hide core-private struct fields SJ Park
                   ` (3 preceding siblings ...)
  2026-07-14  4:34 ` [RFC PATCH 04/10] mm/damon/core: hide private damos_quota fields SJ Park
@ 2026-07-14  4:34 ` SJ Park
  2026-07-14  4:34 ` [RFC PATCH 06/10] mm/damon/core: hide private damos fields SJ Park
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: SJ Park @ 2026-07-14  4:34 UTC (permalink / raw)
  Cc: SJ Park, damon, linux-kernel, linux-mm

damos_filter->list is intended to be used by only the DAMON core layer.
However, it is mistakenly not marked as private.  Mark as private.

Signed-off-by: SJ Park <sj@kernel.org>
---
 include/linux/damon.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/linux/damon.h b/include/linux/damon.h
index bd024b89adfa3..15517be3e4960 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -432,7 +432,6 @@ enum damos_filter_type {
  *		&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
  * byte of the region matches to this given condition and avoid applying the
@@ -450,6 +449,8 @@ struct damos_filter {
 		int target_idx;
 		struct damon_size_range sz_range;
 	};
+/* private: */
+	/* List head for siblings. */
 	struct list_head list;
 };
 
-- 
2.47.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 06/10] mm/damon/core: hide private damos fields
  2026-07-14  4:34 [RFC PATCH 00/10] mm/damon/core: hide core-private struct fields SJ Park
                   ` (4 preceding siblings ...)
  2026-07-14  4:34 ` [RFC PATCH 05/10] mm/damon/core: hide private damos_filter fields SJ Park
@ 2026-07-14  4:34 ` SJ Park
  2026-07-14  4:52   ` sashiko-bot
  2026-07-14  4:34 ` [RFC PATCH 07/10] mm/damon/core: hide private damon_filter fields SJ Park
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: SJ Park @ 2026-07-14  4:34 UTC (permalink / raw)
  Cc: SJ Park, damon, linux-kernel, linux-mm

'core_filters', 'ops_filters', 'last_applied' and 'list' fields of damos
are intended to be used by only the DAMON core layer.  However, those
are mistakenly not marked as private.  Mark as private.

Signed-off-by: SJ Park <sj@kernel.org>
---
 include/linux/damon.h | 52 ++++++++++++++++++++++---------------------
 1 file changed, 27 insertions(+), 25 deletions(-)

diff --git a/include/linux/damon.h b/include/linux/damon.h
index 15517be3e4960..907d65f03d083 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -522,12 +522,8 @@ struct damos_migrate_dests {
  * @wmarks:		Watermarks for automated (in)activation of this scheme.
  * @migrate_dests:	Destination nodes if @action is "migrate_{hot,cold}".
  * @target_nid:		Destination node if @action is "migrate_{hot,cold}".
- * @core_filters:	Additional set of &struct damos_filter for &action.
- * @ops_filters:	ops layer handling &struct damos_filter objects list.
- * @last_applied:	Last @action applied ops-managing entity.
  * @stat:		Statistics of this scheme.
  * @max_nr_snapshots:	Upper limit of nr_snapshots stat.
- * @list:		List head for siblings.
  *
  * For each @apply_interval_us, DAMON finds regions which fit in the
  * &pattern and applies &action to those. To avoid consuming too much
@@ -549,16 +545,7 @@ struct damos_migrate_dests {
  *
  * Before applying the &action to a memory region, &struct damon_operations
  * implementation could check pages of the region and skip &action to respect
- * &core_filters
- *
- * The minimum entity that @action can be applied depends on the underlying
- * &struct damon_operations.  Since it may not be aligned with the core layer
- * abstract, namely &struct damon_region, &struct damon_operations could apply
- * @action to same entity multiple times.  Large folios that underlying on
- * multiple &struct damon region objects could be such examples.  The &struct
- * damon_operations can use @last_applied to avoid that.  DAMOS core logic
- * unsets @last_applied when each regions walking for applying the scheme is
- * finished.
+ * &struct damos_filter.
  *
  * After applying the &action to each region, &stat is updated.
  *
@@ -569,6 +556,16 @@ struct damos {
 	struct damos_access_pattern pattern;
 	enum damos_action action;
 	unsigned long apply_interval_us;
+	struct damos_quota quota;
+	struct damos_watermarks wmarks;
+	union {
+		struct {
+			int target_nid;
+			struct damos_migrate_dests migrate_dests;
+		};
+	};
+	struct damos_stat stat;
+	unsigned long max_nr_snapshots;
 /* private: internal use only */
 	/*
 	 * number of sample intervals that should be passed before applying
@@ -585,20 +582,25 @@ struct damos {
 	/* whether to reject core/ops filters umatched regions */
 	bool core_filters_default_reject;
 	bool ops_filters_default_reject;
-/* public: */
-	struct damos_quota quota;
-	struct damos_watermarks wmarks;
-	union {
-		struct {
-			int target_nid;
-			struct damos_migrate_dests migrate_dests;
-		};
-	};
+	/* Additional set of &struct damos_filter for &action. */
 	struct list_head core_filters;
+	/* ops layer handling &struct damos_filter objects list. */
 	struct list_head ops_filters;
+	/*
+	 * Last @action applied ops-managing entity.
+	 *
+	 * The minimum entity that @action can be applied depends on the
+	 * underlying &struct damon_operations.  Since it may not be aligned
+	 * with the core layer abstract, namely &struct damon_region, &struct
+	 * damon_operations could apply @action to same entity multiple times.
+	 * Large folios that underlying on multiple &struct damon region
+	 * objects could be such examples.  The &struct damon_operations can
+	 * use @last_applied to avoid that.  DAMOS core logic unsets
+	 * @last_applied when each regions walking for applying the scheme is
+	 * finished.
+	 */
 	void *last_applied;
-	struct damos_stat stat;
-	unsigned long max_nr_snapshots;
+	/* List head for siblings. */
 	struct list_head list;
 };
 
-- 
2.47.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 07/10] mm/damon/core: hide private damon_filter fields
  2026-07-14  4:34 [RFC PATCH 00/10] mm/damon/core: hide core-private struct fields SJ Park
                   ` (5 preceding siblings ...)
  2026-07-14  4:34 ` [RFC PATCH 06/10] mm/damon/core: hide private damos fields SJ Park
@ 2026-07-14  4:34 ` SJ Park
  2026-07-14  4:34 ` [RFC PATCH 08/10] mm/damon/core: hide private damon_probe fields SJ Park
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: SJ Park @ 2026-07-14  4:34 UTC (permalink / raw)
  Cc: SJ Park, damon, linux-kernel, linux-mm

damon_filter->list is intended to be used by only the DAMON core layer.
However, it is mistakenly not marked as private.  Mark as private.

Signed-off-by: SJ Park <sj@kernel.org>
---
 include/linux/damon.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/linux/damon.h b/include/linux/damon.h
index 907d65f03d083..6c3c7c75b6ca3 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -758,7 +758,6 @@ enum damon_filter_type {
  * @matching:	Whether this filter is for the type-matching ones.
  * @allow:	Whether the @type-@matching ones should pass this filter.
  * @memcg_id:	Memcg id of the question if @type is DAMON_FILTER_MEMCG.
- * @list:	Siblings list.
  */
 struct damon_filter {
 	enum damon_filter_type type;
@@ -767,6 +766,8 @@ struct damon_filter {
 	union {
 		u64 memcg_id;
 	};
+/* private: */
+	/* Siblings list. */
 	struct list_head list;
 };
 
-- 
2.47.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 08/10] mm/damon/core: hide private damon_probe fields
  2026-07-14  4:34 [RFC PATCH 00/10] mm/damon/core: hide core-private struct fields SJ Park
                   ` (6 preceding siblings ...)
  2026-07-14  4:34 ` [RFC PATCH 07/10] mm/damon/core: hide private damon_filter fields SJ Park
@ 2026-07-14  4:34 ` SJ Park
  2026-07-14  4:34 ` [RFC PATCH 09/10] mm/damon/sysfs: do not directly access damon_ctx->ops SJ Park
  2026-07-14  4:34 ` [RFC PATCH 10/10] mm/damon/core: hide core-private damon_ctx fields SJ Park
  9 siblings, 0 replies; 14+ messages in thread
From: SJ Park @ 2026-07-14  4:34 UTC (permalink / raw)
  Cc: SJ Park, damon, linux-kernel, linux-mm

'filters' and 'list' fields of damon_probe are intended to be used by
only the DAMON core layer.  However, those are mistakenly not marked as
private.  Mark as private.

Signed-off-by: SJ Park <sj@kernel.org>
---
 include/linux/damon.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/linux/damon.h b/include/linux/damon.h
index 6c3c7c75b6ca3..537e59bfd7072 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -775,12 +775,13 @@ struct damon_filter {
  * struct damon_probe - Data region attribute probe.
  *
  * @weight:	Relative priority of the attribute for this probe.
- * @filters:	Filters for assessing if a given region is for this probe.
- * @list:	Siblings list.
  */
 struct damon_probe {
 	unsigned int weight;
+/* private: */
+	/* Filters for assessing if a given region is for this probe. */
 	struct list_head filters;
+	/* Siblings list. */
 	struct list_head list;
 };
 
-- 
2.47.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 09/10] mm/damon/sysfs: do not directly access damon_ctx->ops
  2026-07-14  4:34 [RFC PATCH 00/10] mm/damon/core: hide core-private struct fields SJ Park
                   ` (7 preceding siblings ...)
  2026-07-14  4:34 ` [RFC PATCH 08/10] mm/damon/core: hide private damon_probe fields SJ Park
@ 2026-07-14  4:34 ` SJ Park
  2026-07-14  4:34 ` [RFC PATCH 10/10] mm/damon/core: hide core-private damon_ctx fields SJ Park
  9 siblings, 0 replies; 14+ messages in thread
From: SJ Park @ 2026-07-14  4:34 UTC (permalink / raw)
  Cc: SJ Park, Andrew Morton, damon, linux-kernel, linux-mm

damon_ctx->ops field is intended to be used by only the DAMON core
layer.  DAMON_SYSFS is directly reading the field to find if it is for
physical address monitoring, though.  Use the API function for the
purpose, damon_target_has_pid(), instead.

Signed-off-by: SJ Park <sj@kernel.org>
---
 mm/damon/sysfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
index 60a1a9e4ada34..228ceb4df5f97 100644
--- a/mm/damon/sysfs.c
+++ b/mm/damon/sysfs.c
@@ -2051,7 +2051,7 @@ static int damon_sysfs_add_targets(struct damon_ctx *ctx,
 	int i, err;
 
 	/* Multiple physical address space monitoring targets makes no sense */
-	if (ctx->ops.id == DAMON_OPS_PADDR && sysfs_targets->nr > 1)
+	if (!damon_target_has_pid(ctx) && sysfs_targets->nr > 1)
 		return -EINVAL;
 
 	for (i = 0; i < sysfs_targets->nr; i++) {
-- 
2.47.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 10/10] mm/damon/core: hide core-private damon_ctx fields
  2026-07-14  4:34 [RFC PATCH 00/10] mm/damon/core: hide core-private struct fields SJ Park
                   ` (8 preceding siblings ...)
  2026-07-14  4:34 ` [RFC PATCH 09/10] mm/damon/sysfs: do not directly access damon_ctx->ops SJ Park
@ 2026-07-14  4:34 ` SJ Park
  9 siblings, 0 replies; 14+ messages in thread
From: SJ Park @ 2026-07-14  4:34 UTC (permalink / raw)
  Cc: SJ Park, damon, linux-kernel, linux-mm

'ops', 'probes', 'adaptive_targets', 'schemes', and 'rnd_state' fields
of damon_ctx are intended to be used by only the DAMON core layer.
However, those are mistakenly not marked as private.  Mark as private.

Signed-off-by: SJ Park <sj@kernel.org>
---
 include/linux/damon.h | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/include/linux/damon.h b/include/linux/damon.h
index 537e59bfd7072..327f534696aa8 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -848,14 +848,9 @@ struct damon_attrs {
  * thread other than the kdamond should be made using safe DAMON APIs,
  * including damon_call() and damos_walk().
  *
- * @ops:	Set of monitoring operations for given use cases.
- * @probes:	Head of probes (&damon_probe) list.
  * @addr_unit:	Scale factor for core to ops address conversion.
  * @min_region_sz:	Minimum region size.
  * @pause:	Pause kdamond main loop.
- * @adaptive_targets:	Head of monitoring targets (&damon_target) list.
- * @schemes:		Head of schemes (&damos) list.
- * @rnd_state:	Per-ctx PRNG state for damon_rand().
  */
 struct damon_ctx {
 	struct damon_attrs attrs;
@@ -904,15 +899,21 @@ struct damon_ctx {
 	struct mutex kdamond_lock;
 
 /* public: */
-	struct damon_operations ops;
-	struct list_head probes;
 	unsigned long addr_unit;
 	unsigned long min_region_sz;
 	bool pause;
 
+/* private: */
+	/* Set of monitoring operations for given use cases. */
+	struct damon_operations ops;
+	/* Head of monitoring targets (&damon_target) list. */
 	struct list_head adaptive_targets;
+	/* Head of probes (&damon_probe) list. */
+	struct list_head probes;
+	/* Head of schemes (&damos) list. */
 	struct list_head schemes;
 
+	/* @rnd_state:	Per-ctx PRNG state for damon_rand(). */
 	struct rnd_state rnd_state;
 };
 
-- 
2.47.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH 06/10] mm/damon/core: hide private damos fields
  2026-07-14  4:34 ` [RFC PATCH 06/10] mm/damon/core: hide private damos fields SJ Park
@ 2026-07-14  4:52   ` sashiko-bot
  2026-07-14  5:54     ` SJ Park
  0 siblings, 1 reply; 14+ messages in thread
From: sashiko-bot @ 2026-07-14  4:52 UTC (permalink / raw)
  To: SJ Park; +Cc: damon

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] `struct damos->last_applied` is left uninitialized upon allocation in `damon_new_scheme()`, leading to a potential read of uninitialized memory during the first scheme application.
--

--- Patch [6]: [RFC PATCH 06/10] mm/damon/core: hide private damos fields ---
Note: The format of this report has been altered to provide a free-form
summary instead of quoting the original patch code directly, due to system
recitation restrictions.

commit 74f6565901cd9e992427e68af079cc1885de502e
Author: SJ Park <sj@kernel.org>
mm/damon/core: hide private damos fields

This commit updates struct damos to hide several fields intended only for
the DAMON core layer by moving them under a private comment block.

[Severity: High]
This isn't a bug introduced by this patch, but while reviewing the changes
to the last_applied field, I noticed a potential uninitialized memory read.

In mm/damon/core.c:damon_new_scheme(), a new struct damos is allocated
using a non-zeroing kmalloc variant. While several fields are explicitly
initialized in this function, the last_applied pointer is skipped and
left uninitialized.

When kdamond_apply_schemes() performs the very first region walk, it calls
into operations layers like mm/damon/paddr.c:damon_pa_invalid_damos_folio()
before last_applied is ever cleared to NULL.

This causes damon_pa_invalid_damos_folio() to read the uninitialized heap
value and compare it against the valid folio pointer currently being
walked.

If a local user configures DAMON and the uninitialized heap memory happens
to match a valid folio pointer being walked, could this result in an
erroneous folio_put() being executed prematurely? Does this open up an
exploitable use-after-free vulnerability during the initial scheme
application?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260714043437.95811-1-sj@kernel.org?part=6

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH 06/10] mm/damon/core: hide private damos fields
  2026-07-14  4:52   ` sashiko-bot
@ 2026-07-14  5:54     ` SJ Park
  2026-07-14  6:16       ` SJ Park
  0 siblings, 1 reply; 14+ messages in thread
From: SJ Park @ 2026-07-14  5:54 UTC (permalink / raw)
  To: sashiko-bot; +Cc: SJ Park, damon

On Tue, 14 Jul 2026 04:52:40 +0000 sashiko-bot@kernel.org wrote:

> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> 
> Pre-existing issues:
> - [High] `struct damos->last_applied` is left uninitialized upon allocation in `damon_new_scheme()`, leading to a potential read of uninitialized memory during the first scheme application.
> --
> 
> --- Patch [6]: [RFC PATCH 06/10] mm/damon/core: hide private damos fields ---
> Note: The format of this report has been altered to provide a free-form
> summary instead of quoting the original patch code directly, due to system
> recitation restrictions.
> 
> commit 74f6565901cd9e992427e68af079cc1885de502e
> Author: SJ Park <sj@kernel.org>
> mm/damon/core: hide private damos fields
> 
> This commit updates struct damos to hide several fields intended only for
> the DAMON core layer by moving them under a private comment block.
> 
> [Severity: High]
> This isn't a bug introduced by this patch, but while reviewing the changes
> to the last_applied field, I noticed a potential uninitialized memory read.
> 
> In mm/damon/core.c:damon_new_scheme(), a new struct damos is allocated
> using a non-zeroing kmalloc variant. While several fields are explicitly
> initialized in this function, the last_applied pointer is skipped and
> left uninitialized.
> 
> When kdamond_apply_schemes() performs the very first region walk, it calls
> into operations layers like mm/damon/paddr.c:damon_pa_invalid_damos_folio()
> before last_applied is ever cleared to NULL.
> 
> This causes damon_pa_invalid_damos_folio() to read the uninitialized heap
> value and compare it against the valid folio pointer currently being
> walked.
> 
> If a local user configures DAMON and the uninitialized heap memory happens
> to match a valid folio pointer being walked, could this result in an
> erroneous folio_put() being executed prematurely? Does this open up an
> exploitable use-after-free vulnerability during the initial scheme
> application?

Good finding.  I will separately work on this.

> 
> -- 
> Sashiko AI review · https://sashiko.dev/#/patchset/20260714043437.95811-1-sj@kernel.org?part=6


Thanks,
SJ

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH 06/10] mm/damon/core: hide private damos fields
  2026-07-14  5:54     ` SJ Park
@ 2026-07-14  6:16       ` SJ Park
  0 siblings, 0 replies; 14+ messages in thread
From: SJ Park @ 2026-07-14  6:16 UTC (permalink / raw)
  To: SJ Park; +Cc: sashiko-bot, damon

On Mon, 13 Jul 2026 22:54:50 -0700 SJ Park <sj@kernel.org> wrote:

> On Tue, 14 Jul 2026 04:52:40 +0000 sashiko-bot@kernel.org wrote:
> 
> > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> > 
> > Pre-existing issues:
> > - [High] `struct damos->last_applied` is left uninitialized upon allocation in `damon_new_scheme()`, leading to a potential read of uninitialized memory during the first scheme application.
> > --
> > 
> > --- Patch [6]: [RFC PATCH 06/10] mm/damon/core: hide private damos fields ---
> > Note: The format of this report has been altered to provide a free-form
> > summary instead of quoting the original patch code directly, due to system
> > recitation restrictions.
> > 
> > commit 74f6565901cd9e992427e68af079cc1885de502e
> > Author: SJ Park <sj@kernel.org>
> > mm/damon/core: hide private damos fields
> > 
> > This commit updates struct damos to hide several fields intended only for
> > the DAMON core layer by moving them under a private comment block.
> > 
> > [Severity: High]
> > This isn't a bug introduced by this patch, but while reviewing the changes
> > to the last_applied field, I noticed a potential uninitialized memory read.
> > 
> > In mm/damon/core.c:damon_new_scheme(), a new struct damos is allocated
> > using a non-zeroing kmalloc variant. While several fields are explicitly
> > initialized in this function, the last_applied pointer is skipped and
> > left uninitialized.
> > 
> > When kdamond_apply_schemes() performs the very first region walk, it calls
> > into operations layers like mm/damon/paddr.c:damon_pa_invalid_damos_folio()
> > before last_applied is ever cleared to NULL.
> > 
> > This causes damon_pa_invalid_damos_folio() to read the uninitialized heap
> > value and compare it against the valid folio pointer currently being
> > walked.
> > 
> > If a local user configures DAMON and the uninitialized heap memory happens
> > to match a valid folio pointer being walked, could this result in an
> > erroneous folio_put() being executed prematurely? Does this open up an
> > exploitable use-after-free vulnerability during the initial scheme
> > application?
> 
> Good finding.  I will separately work on this.

That said, the premature folio_put() and use-after-free cannot happen, because
damon_pa_invalid_damos_folio() is called only for the folio that DAMON_PADDR
has increased the reference.  The consequence is just not applying DAMOS action
to a valid folio, only once per DAMOS run, only if the uninitialized value
matches the valid folio.

I think this is still better to be fixed as long as the fix is simple.  Quite a
mild issue, though.


Thanks,
SJ

[...]

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-07-14  6:16 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-14  4:34 [RFC PATCH 00/10] mm/damon/core: hide core-private struct fields SJ Park
2026-07-14  4:34 ` [RFC PATCH 01/10] mm/damon/core: hide private damon_region fields SJ Park
2026-07-14  4:34 ` [RFC PATCH 02/10] mm/damon/core: hide private damon_target fields SJ Park
2026-07-14  4:34 ` [RFC PATCH 03/10] mm/damon/core: hide private damos_quota_goal fields SJ Park
2026-07-14  4:34 ` [RFC PATCH 04/10] mm/damon/core: hide private damos_quota fields SJ Park
2026-07-14  4:34 ` [RFC PATCH 05/10] mm/damon/core: hide private damos_filter fields SJ Park
2026-07-14  4:34 ` [RFC PATCH 06/10] mm/damon/core: hide private damos fields SJ Park
2026-07-14  4:52   ` sashiko-bot
2026-07-14  5:54     ` SJ Park
2026-07-14  6:16       ` SJ Park
2026-07-14  4:34 ` [RFC PATCH 07/10] mm/damon/core: hide private damon_filter fields SJ Park
2026-07-14  4:34 ` [RFC PATCH 08/10] mm/damon/core: hide private damon_probe fields SJ Park
2026-07-14  4:34 ` [RFC PATCH 09/10] mm/damon/sysfs: do not directly access damon_ctx->ops SJ Park
2026-07-14  4:34 ` [RFC PATCH 10/10] mm/damon/core: hide core-private damon_ctx fields SJ Park

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox