[RFC PATCH v4 0/9] mm/damon: hardware-sampled access reports
From: Liew Rui Yan
Date: Sat Oct 17 2026 - 17:17:03 EST
On Sat, 17 Oct 2026 15:11:18 +0800 Liew Rui Yan <aethernet65535@xxxxxxxxx> wrote:
> Hi Ravi,
>
>
> TLDR
> ====
>
> I have noticed that there might have an issue with this patch or my CPU.
> I am not sure. I have provided some details below.
>
> On Mon, 05 Oct 2026 01:46:44 -0700 Ravi Jonnalagadda <ravis.opensrc@xxxxxxxxx> wrote:
>
> > This series lets DAMON monitor a hardware-sampled data attribute -- the
> > addresses a PMU saw accessed -- through the data attributes monitoring
> > (probe) interface, and run DAMOS schemes on it in data attributes-only
> > mode. Patches 3, 5, and 6 are co-developed with Akinobu Mita, building
> > on his earlier perf-event proposal [3].
> >
>
> I expected it to monitor regions in the same way as PTE sampling, that
> is, if the system has hot memory, DAMON should be able to detect it, or
> at least with some probability. However, it is not always work like
> that. After I starting DAMON about 10 minutes, the DAMON cannot found
> any hot page, even when I am running 'stress-ng --vm 6 --vm-bytes 6G':
>
> snapshot time: [0 ns, 100 ms] (100 ms)
> |0000000000000000000000000000000000000000| size 1.461 GiB access 0 age 3 m 3.200 s
> |000000000| size 1.465 GiB access 0 age 3 m 1 s
> |00| size 2.922 GiB access 0 age 3 m 0.500 s
> |0000000000000000000| size 1.471 GiB access 0 age 3 m 1.700 s
> |000000000000000000000000| size 1.462 GiB access 0 age 3 m 2.100 s
> |00| size 1.470 GiB access 0 age 3 m 0.500 s
> |0| size 2.926 GiB access 0 age 3 m 0.400 s
> |00| size 1.544 GiB access 0 age 3 m 0.500 s
> memory bw estimate: 0 B per second
> total size: 14.722 GiB
> record DAMON intervals: sample 5 ms, aggr 100 ms
>
> Note that this is my own fork of damo [1].
>
> To ensure this was not a bug in my damo fork [1], I adding a tracing
> statistic [2] to DAMON to confirm whether this was indeed a DAMON issue.
>
> TLDR for new tracing statsistic: 'seen' means how many times
> damon_perf_overflow() was called.
>
> Later, I noticed that about 10 minutes after starting DAMON, the 'seen'
> stopped increasing:
>
> I am running 'stress-ng --vm 6 --vm-bytes 6G' during recording this
> statistic.
>
> Start Time: 19:25:42 | End Time: 19:42:18
> Time Unit: 1 step = 1.81 minutes
>
> Seen (Delta)
> ^
> |
> 100k | *
> 36k | *
> 18k | * *
> 17k | *
> 15k | *
> 4k | *
> 453 | *
> 106 | *
> 0 | *
> +--+---+---+---+---+---+---+---+---+---+---> Step
> 1 2 3 4 5 6 7 8 9 10
>
> Note: Zero delta from 19:42:18 (step 10) till 20:00:00 (I close my
> machine after that).
>
> My DAMON Perf Config
> ====================
>
> K=/sys/kernel/mm/damon/admin/kdamonds/0
> C=$K/contexts/0
> P=$C/monitoring_attrs/probes
>
> echo 1 > $P/0/preps/nr_preps
> echo perf_event > $P/0/preps/0/prep_action
> cat /sys/bus/event_source/devices/ibs_op/type > $P/0/preps/0/type
> echo 0 > $P/0/preps/0/config
> echo 0 > $P/0/preps/0/config2
> echo 0 > $P/0/preps/0/sample_freq
> echo 100000 > $P/0/preps/0/sample_period
> echo 1 > $P/0/preps/0/sample_phys_addr
> echo 0 > $P/0/preps/0/exclude_kernel
> echo 0 > $P/0/preps/0/exclude_hv
> echo 1 > $P/0/weight
>
> Note that this issue can also reproduce even when
> 'kernel.perf_cpu_time_max_percent=100'.
>
> My CPU Specification
> ====================
>
> CPU(s): 12
> On-line CPU(s) list: 0-11
> Vendor ID: AuthenticAMD
> Model name: AMD Ryzen 5 5600H with Radeon Graphics
> CPU family: 25
> Model: 80
> Thread(s) per core: 2
> Core(s) per socket: 6
> Socket(s): 1
> Stepping: 0
> Microcode version: 0xa500012
> Frequency boost: enabled
> CPU(s) scaling MHz: 48%
> CPU max MHz: 4280.9849
> CPU min MHz: 412.6250
> BogoMIPS: 6587.34
>
> I am trying to figure out if this is a CPU issue, or if there is an
> issue with this patch. I would be happy to provide more information.
>
> [...]
>
> [1] https://github.com/aethernet65535/damo/tree/probe
> [2] Trace patch diff
> '''
> diff --git a/include/trace/events/damon.h b/include/trace/events/damon.h
> index 4dfc9467ea4b..290d3ee2d836 100644
> --- a/include/trace/events/damon.h
> +++ b/include/trace/events/damon.h
> @@ -199,6 +199,23 @@ TRACE_EVENT(damon_aggregated,
> __entry->nr_accesses, __entry->age)
> );
>
> +TRACE_EVENT(damon_perf_source_stats,
> +
> + TP_PROTO(unsigned long seen),
> +
> + TP_ARGS(seen),
> +
> + TP_STRUCT__entry(
> + __field(unsigned long, seen)
> + ),
> +
> + TP_fast_assign(
> + __entry->seen = seen;
> + ),
> +
> + TP_printk("seen=%lu", __entry->seen)
> +)
> +
> #endif /* _TRACE_DAMON_H */
>
> /* This part must be outside protection */
> diff --git a/mm/damon/core.c b/mm/damon/core.c
> index bae4569f0ab3..73988ce82b1a 100644
> --- a/mm/damon/core.c
> +++ b/mm/damon/core.c
> @@ -4927,6 +4927,8 @@ static void kdamond_check_reported_accesses(struct damon_ctx *ctx)
> if (damon_drains_ring_perf(ctx))
> __kdamond_drain_ring(ctx, tbl, ctx->perf_rings,
> &ctx->perf_pending);
> +
> + trace_damon_perf_source_stats(damon_get_perf_seen());
> }
>
> /*
> diff --git a/mm/damon/perf_source.c b/mm/damon/perf_source.c
> index 4baa8aebcfa8..e8365dbe1744 100644
> --- a/mm/damon/perf_source.c
> +++ b/mm/damon/perf_source.c
> @@ -27,6 +27,8 @@ struct damon_perf_probe_state {
> struct perf_event *single_event;
> };
>
> +static DEFINE_PER_CPU(unsigned long, damon_perf_seen);
> +
> static void damon_perf_overflow(struct perf_event *perf_event,
> struct perf_sample_data *data,
> struct pt_regs *regs)
> @@ -40,6 +42,8 @@ static void damon_perf_overflow(struct perf_event *perf_event,
> .cpu = smp_processor_id(),
> };
>
> + this_cpu_inc(damon_perf_seen);
> +
> /*
> * Teardown NULLs event->ctx (with a release barrier) before releasing
> * the per-CPU perf events, so an in-flight overflow racing the
> @@ -84,6 +88,16 @@ static void damon_perf_overflow(struct perf_event *perf_event,
> damon_report_access(&report);
> }
>
> +unsigned long damon_get_perf_seen(void)
> +{
> + unsigned long sum = 0;
> + int cpu;
> +
> + for_each_possible_cpu(cpu)
> + sum += per_cpu(damon_perf_seen, cpu);
> + return sum;
> +}
> +
> static enum cpuhp_state damon_perf_cpuhp_state;
>
> /*
> diff --git a/mm/damon/perf_source.h b/mm/damon/perf_source.h
> index 12ca61be7243..49beca6e3189 100644
> --- a/mm/damon/perf_source.h
> +++ b/mm/damon/perf_source.h
> @@ -50,6 +50,7 @@ int damon_perf_probe_setup(struct damon_ctx *ctx,
> struct damon_perf_probe_event *event);
> void damon_perf_probe_teardown(struct damon_ctx *ctx,
> struct damon_perf_probe_event *event);
> +unsigned long damon_get_perf_seen(void);
>
> #endif /* CONFIG_DAMON_PERF_SOURCE */
> #endif /* _DAMON_PERF_SOURCE_H */
> '''
I found that if I enable the kernel NMI watchdog, this issue can be
fixed. So I think this is not issue of this patch. What do you think?
[...]
Best regards,
Rui Yan