[RFC PATCH 5/7] mm/damon: add sysfs binding and dispatch hookup for paddr_ibs operations
From: Ravi Jonnalagadda
Date: Sat May 16 2026 - 18:36:34 EST
Extend damon_ops_id enum to include DAMON_OPS_PADDR_IBS and add the
corresponding 'paddr_ibs' name to the sysfs ops_names array so users
can select AMD IBS-based PA-mode monitoring via
/sys/kernel/mm/damon/admin/kdamonds/<N>/contexts/<N>/operations.
Route ops that report accesses through the hardware-sampling ring
(currently only DAMON_OPS_PADDR_IBS) through the existing
kdamond_check_reported_accesses() drain path used for page-fault
reports. A small helper damon_ops_is_hw_hotness() centralises the
classification so any future paddr-family backend that also reports
through the ring just adds a case here.
This routing is bound to ops.id rather than to a separate per-context
flag. A flag in damon_sample_control would have to be set by the ops
.init callback after damon_select_ops() and would then need to be
preserved by damon_commit_sample_control() across sysfs commits;
deriving from ops.id avoids both pitfalls.
Signed-off-by: Ravi Jonnalagadda <ravis.opensrc@xxxxxxxxx>
---
include/linux/damon.h | 2 ++
mm/damon/core.c | 13 ++++++++++++-
mm/damon/sysfs.c | 12 +++++++++---
3 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/include/linux/damon.h b/include/linux/damon.h
index 35cc3d42fcba8..16da528845d03 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -669,12 +669,14 @@ struct damos {
* @DAMON_OPS_FVADDR: Monitoring operations for only fixed ranges of virtual
* address spaces
* @DAMON_OPS_PADDR: Monitoring operations for the physical address space
+ * @DAMON_OPS_PADDR_IBS: AMD IBS-based PA-mode monitoring
* @NR_DAMON_OPS: Number of monitoring operations implementations
*/
enum damon_ops_id {
DAMON_OPS_VADDR,
DAMON_OPS_FVADDR,
DAMON_OPS_PADDR,
+ DAMON_OPS_PADDR_IBS,
NR_DAMON_OPS,
};
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 03f9c671e8bc9..2aa031cbc70b7 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -73,6 +73,16 @@ static bool __damon_is_registered_ops(enum damon_ops_id id)
return true;
}
+/*
+ * Returns true if the given ops id reports access samples through the
+ * hardware-sampling ring-buffer drain path (rather than its own
+ * .check_accesses callback).
+ */
+static bool damon_ops_is_hw_hotness(enum damon_ops_id id)
+{
+ return id == DAMON_OPS_PADDR_IBS;
+}
+
/**
* damon_is_registered_ops() - Check if a given damon_operations is registered.
* @id: Id of the damon_operations to check if registered.
@@ -4048,7 +4058,8 @@ static int kdamond_fn(void *data)
ctx->passed_sample_intervals++;
/* todo: make these non-exclusive */
- if (ctx->sample_control.primitives_enabled.page_fault)
+ if (ctx->sample_control.primitives_enabled.page_fault ||
+ damon_ops_is_hw_hotness(ctx->ops.id))
max_nr_accesses = kdamond_check_reported_accesses(ctx);
else if (ctx->ops.check_accesses)
max_nr_accesses = ctx->ops.check_accesses(ctx);
diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
index fc7256e522a69..261ccf0c61846 100644
--- a/mm/damon/sysfs.c
+++ b/mm/damon/sysfs.c
@@ -1388,6 +1388,10 @@ static const struct damon_sysfs_ops_name damon_sysfs_ops_names[] = {
.ops_id = DAMON_OPS_PADDR,
.name = "paddr",
},
+ {
+ .ops_id = DAMON_OPS_PADDR_IBS,
+ .name = "paddr_ibs",
+ },
};
struct damon_sysfs_context {
@@ -2023,7 +2027,8 @@ 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 ((ctx->ops.id == DAMON_OPS_PADDR ||
+ ctx->ops.id == DAMON_OPS_PADDR_IBS) && sysfs_targets->nr > 1)
return -EINVAL;
for (i = 0; i < sysfs_targets->nr; i++) {
@@ -2072,8 +2077,9 @@ static int damon_sysfs_apply_inputs(struct damon_ctx *ctx,
if (err)
return err;
ctx->addr_unit = sys_ctx->addr_unit;
- /* addr_unit is respected by only DAMON_OPS_PADDR */
- if (sys_ctx->ops_id == DAMON_OPS_PADDR)
+ /* addr_unit is respected by only paddr-family ops */
+ if (sys_ctx->ops_id == DAMON_OPS_PADDR ||
+ sys_ctx->ops_id == DAMON_OPS_PADDR_IBS)
ctx->min_region_sz = max(
DAMON_MIN_REGION_SZ / sys_ctx->addr_unit, 1);
ctx->pause = sys_ctx->pause;
--
2.43.0