All of lore.kernel.org
 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 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.