mm/damon: let DAMON be paused and resumed
Subsystems (5)
SeongJae Park
maintainerv5 cover mm/damon: let DAMON be paused and resumed
DAMON utilizes a few mechanisms that enhance itself over time. Adaptive regions adjustment, goal-based DAMOS quota auto-tuning and monitoring intervals auto-tuning like self-training mechanisms are such examples. It also adds access frequency stability information (age) to the monitoring results, which makes it enhanced over time.
Sometimes users have to stop DAMON. In this case, DAMON internal state that enhanced over the time of the last execution simply goes away. Restarted DAMON have to train itself and enhance its output from the scratch. This makes DAMON less useful in such cases. Introducing three such use cases below.
Investigation of DAMON. It is best to do the investigation online, especially when it is a production environment. DAMON therefore provides features for such online investigations, including DAMOS stats, monitoring result snapshot exposure, and multiple tracepoints. When those are insufficient, and there are additional clues that could be interfered by DAMON, users have to temporarily stop DAMON to collect the additional clues. It is not very useful since many of DAMON internal clues are gone when DAMON is stopped. The loss of the monitoring results that improved over time is also problematic, especially in production environments.
Monitoring of workloads that have different user-known phases. For example, in Android, applications are known to have very different access patterns and behaviors when they are running on the foreground and the background. It can therefore be useful to separate monitoring of apps based on whether they are running on the foreground and on the background. Having two DAMON threads per application that paused and resumed for the apps foreground/background switches can be useful for the purpose. But such pause/resume of the execution is not supported.
Tests of DAMON. A few DAMON selftests are using drgn to dump the internal DAMON status. The tests show if the dumped status is the same as what the test code expected. Because DAMON keeps running and modifying its internal status, there are chances of data races that can cause false test results. Stopping DAMON can avoid the race. But, since the internal state of DAMON is dropped, the test coverage will be limited.
Let DAMON execution be paused and resumed without loss of the internal state, to overhaul the limitations. For this, introduce a new DAMON context parameter, namely 'pause'. API callers can update it while the context is running, using the online parameters update functions (damon_commit_ctx() and damon_call()). Once it is set, kdamond_fn() main loop will do only limited works excluding the monitoring and DAMOS works, while sleeping sampling intervals per the work. The limited works include handling of the online parameters update. Hence users can unset the 'pause' parameter again. Once it is unset, kdamond_fn() main loop will do all the work again (resumed). Under the paused state, it also does stop condition checks and handling of it, so that paused DAMON can also be stopped if needed. Expose the feature to the user space via DAMON sysfs interface. Also, update existing drgn-based tests to test and use the feature.
Tests
=====
I confirmed the feature functionality using real time tracing ('perf trace' or 'trace-cmd stream') of damon:damon_aggregated DAMON tracepoint. By pausing and resuming the DAMON execution, I was able to see the trace stops and continued as expected. Note that the pause feature support is added to DAMON user-space tool (damo) after v3.1.9. Users can use '--pause_ctx' command line option of damo for that, and I actually used it for my test. The extended drgn-based selftests are also testing a part of the functionality.
Patches Sequence
================
Patch 1 introduces the new core API for the pause feature. Patch 2 extend DAMON sysfs interface for the new parameter. Patches 3-5 update design, usage and ABI documents for the new sysfs file, respectively. The following five patches are for tests. Patch 6 implements a new kunit test for the pause parameter online commitment. Patches 7 and 8 extend DAMON selftest helpers to support the new feature. Patch 9 extends selftest to test the commitment of the feature. Finally, patch 10 updates existing selftest to be safe from the race condition using the pause/resume feature.
Changelog
=========
Changes from RFC v4
(https://lore.kerneel.org/[email protected])
- Fix typo: selftets.
- Fix wrong selftests kdamonds resume iteration. Changes from v1 (or, RFC v3)
(https://lore.kernel.org/[email protected])
- Add RFC tag again.
- Handle maybe_corrupted inside pause-loop.
- Reduce unnecessary commits in sysfs.py selftest. Changes from RFC v2
(https://lore.kernel.org/[email protected])
- Move damon_ctx->pause to public fields section.
- Wordsmith design doc change.
- Fix unintended resume of contexts in multiple contexts use case.
- Rebase to latest mm-new.
Changes from RFC v1
(https://lore.kernel.org/[email protected])
- Continuously cancel new damos_walk() requests when paused.
- Initialize damon_sysfs_context->pause.
- Make sysfs.py dump-purpose pausing to work for all contexts.
SeongJae Park (10):
mm/damon/core: introduce damon_ctx->paused mm/damon/sysfs: add pause file under context dir Docs/mm/damon/design: update for context pause/resume feature Docs/admin-guide/mm/damon/usage: update for pause file Docs/ABI/damon: update for pause sysfs file mm/damon/tests/core-kunit: test pause commitment selftests/damon/_damon_sysfs: support pause file staging selftests/damon/drgn_dump_damon_status: dump pause selftests/damon/sysfs.py: check pause on assert_ctx_committed() selftests/damon/sysfs.py: pause DAMON before dumping status
.../ABI/testing/sysfs-kernel-mm-damon | 7 ++++ Documentation/admin-guide/mm/damon/usage.rst | 12 ++++-- Documentation/mm/damon/design.rst | 7 ++++ include/linux/damon.h | 2 + mm/damon/core.c | 9 +++++ mm/damon/sysfs.c | 31 +++++++++++++++ mm/damon/tests/core-kunit.h | 4 ++ tools/testing/selftests/damon/_damon_sysfs.py | 10 ++++- .../selftests/damon/drgn_dump_damon_status.py | 1 + tools/testing/selftests/damon/sysfs.py | 39 +++++++++++++++++++ 10 files changed, 117 insertions(+), 5 deletions(-)
base-commit: 4219363684c17e8704b4fd4ceac8940924a94b3d
Signature · 1 line
2.47.3
SeongJae Park
maintainerRFC PATCH v5 1/10 mm/damon/core: introduce damon_ctx->paused
DAMON supports only start and stop of the execution. When it is stopped, its internal data that it self-trained goes away. It will be useful if the execution can be paused and resumed with the previous self-trained data.
Introduce per-context API parameter, 'paused', for the purpose. The parameter can be set and unset while DAMON is running and paused, using the online parameters commit helper functions (damon_commit_ctx() and damon_call()). Once 'paused' is set, the kdamond_fn() main loop does only limited works with sampling interval sleep during the works. The limited works include the handling of the online parameters update, so that users can unset the 'pause' and resume the execution when they want. It also keep checking DAMON stop conditions and handling of it, so that DAMON can be stopped while paused if needed.
--- include/linux/damon.h | 2 ++ mm/damon/core.c | 9 +++++++++ 2 files changed, 11 insertions(+)
include/linux/damon.h +2 -0
@@ -787,6 +787,7 @@ struct damon_attrs {* @ops: Set of monitoring operations for given use cases. * @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. */
@@ -838,6 +839,7 @@ struct damon_ctx {struct damon_operations ops;unsigned long addr_unit;unsigned long min_region_sz; +bool pause;struct list_head adaptive_targets;struct list_head schemes;
mm/damon/core.c +9 -0
@@ -1349,6 +1349,7 @@ int damon_commit_ctx(struct damon_ctx *dst, struct damon_ctx *src)if (err)return err; } + dst->pause = src->pause; dst->ops = src->ops; dst->addr_unit = src->addr_unit; dst->min_region_sz = src->min_region_sz;
@@ -3003,6 +3004,14 @@ static int kdamond_fn(void *data)kdamond_call (ctx, false);if (ctx->maybe_corrupted)break ; +while (ctx->pause) { +damos_walk_cancel (ctx); +kdamond_usleep (ctx->attrs.sample_interval); +/* allow caller unset pause via damon_call() */ +kdamond_call (ctx, false); +if (kdamond_need_stop (ctx) || ctx->maybe_corrupted) + goto done; + }if (!list_empty (&ctx->schemes))kdamond_apply_schemes (ctx);else
Signature · 1 line
2.47.3
SeongJae Park
maintainerRe: (sashiko review) [RFC PATCH v5 01/10] mm/damon/core: introduce damon_ctx->paused
Forwarding Sashiko review for doing discussions via mails.
# review url: https://sashiko.dev/#/patchset/[email protected] # start of sashiko.dev inline review commit 011f7b451b6e4a657677ee09eada15a7980e8480 Author: SeongJae Park <[email protected]>
mm/damon/core: introduce damon_ctx->paused
This commit introduces a pause parameter to the DAMON context, allowing the kdamond main loop to be paused and resumed without losing its self-trained internal data.
Quoted 4 lines
mm/damon/core.c +0
-0
[ ... ]
mm/damon/core.c static int kdamond_fn(void *data) · line 3014
Quoted 12 lines
mm/damon/core.c +8
-0@@ -3003,6 +3004,14 @@ static int kdamond_fn(void *data)kdamond_call (ctx, false);if (ctx->maybe_corrupted)break ; +while (ctx->pause) { +damos_walk_cancel (ctx); +kdamond_usleep (ctx->attrs.sample_interval); +/* allow caller unset pause via damon_call() */ +kdamond_call (ctx, false); +if (kdamond_need_stop (ctx) || ctx->maybe_corrupted) + goto done; + }
Since this loop is located after ops.prepare_access_checks(), kdamond_usleep(), and ops.check_accesses(), does this unconditionally perform a full monitoring cycle before honoring the paused state?
If a context is started with pause set to true, or if pause is enabled while waiting in kdamond_wait_activation(), it appears it will still execute one complete active sampling cycle. Could this cause unexpected disruption, such as clearing PTE accessed bits, when the context is explicitly configured to be paused?
Additionally, when the context is paused, kdamond_fn remains in this sleep loop and skips calling damos_adjust_quota(), which means quota->charged_from is frozen.
If the pause lasts for more than LONG_MAX jiffies (e.g., about 24.8 days on a 32-bit system with HZ=1000), will system jiffies wrap past the half-range limit of the unsigned long type relative to the frozen timestamp?
If this wraparound occurs, time_after_eq(jiffies, quota->charged_from + interval) would evaluate to false when unpaused. Would this cause the quota window to not reset for another 24.8 days, accumulating charged_sz and blocking the scheme from being applied?
# end of sashiko.dev inline review # review url: https://sashiko.dev/#/patchset/[email protected] # # hkml [1] generated a draft of this mail. It can be regenerated # using below command: # # hkml patch sashiko_dev --for_forwarding \ # [email protected] # # [1] https://github.com/sjp38/hackermail
Sent using hkml (https://github.com/sjp38/hackermail)
SeongJae Park
maintainerRe: (sashiko review) [RFC PATCH v5 01/10] mm/damon/core: introduce damon_ctx->paused
Quoted 35 lines · On Mon, 23 Mar 2026 18:28:00 -0700 SeongJae Park <[email protected]> wrote:
Forwarding Sashiko review for doing discussions via mails.
# review url: https://sashiko.dev/#/patchset/[email protected] # start of sashiko.dev inline review commit 011f7b451b6e4a657677ee09eada15a7980e8480 Author: SeongJae Park <[email protected]>
mm/damon/core: introducedamon_ctx->pausedThis commit introduces a pause parameter to the DAMON context, allowing the kdamond main loop to be paused and resumed without losing its self-trained internal data.
Quoted 4 lines
mm/damon/core.c +0
-0[ ... ]
mm/damon/core.c static int kdamond_fn(void *data) · line 3014
Quoted 12 lines
mm/damon/core.c +8
-0@@ -3003,6 +3004,14 @@ static int kdamond_fn(void *data)kdamond_call (ctx, false);if (ctx->maybe_corrupted)break ; +while (ctx->pause) { +damos_walk_cancel (ctx); +kdamond_usleep (ctx->attrs.sample_interval); +/* allow caller unset pause via damon_call() */ +kdamond_call (ctx, false); +if (kdamond_need_stop (ctx) || ctx->maybe_corrupted) + goto done; + }Since this loop is located after
ops.prepare_access_checks(),kdamond_usleep(), andops.check_accesses(), does this unconditionally perform a full monitoring cycle before honoring the paused state?
Quoted 5 lines
If a context is started with pause set to true, or if pause is enabled while waiting in
kdamond_wait_activation(), it appears it will still execute one complete active sampling cycle. Could this cause unexpected disruption, such as clearing PTE accessed bits, when the context is explicitly configured to be paused?
Yes, DAMON would behave in the way. And having one more sampling work doesn't cause a real issue.
Quoted 5 lines
Additionally, when the context is paused,
kdamond_fnremains in this sleep loop and skips callingdamos_adjust_quota(), which meansquota->charged_fromis frozen.
Quoted 8 lines
If the pause lasts for more than
LONG_MAXjiffies (e.g., about 24.8 days on a 32-bit system with HZ=1000), will system jiffies wrap past the half-range limit of the unsigned long type relative to the frozen timestamp?If this wraparound occurs,
time_after_eq(jiffies, quota->charged_from + interval)would evaluate to false when unpaused. Would this cause the quota window to not reset for another 24.8 days, accumulatingcharged_szand blocking the scheme from being applied?
That's a wild corner case, but I agree it is better to avoid the problematic case. I'm still thinking about the good way for that. Anyway, I will address this in the next spin.
Thanks,
SJ
[...]
SeongJae Park
maintainerRe: (sashiko review) [RFC PATCH v5 01/10] mm/damon/core: introduce damon_ctx->paused
Quoted 3 lines · On Mon, 23 Mar 2026 21:07:21 -0700 SeongJae Park <[email protected]> wrote:
Quoted 1 line · On Mon, 23 Mar 2026 18:28:00 -0700 SeongJae Park <[email protected]> wrote:
Forwarding Sashiko review for doing discussions via mails.
[...]
Quoted 8 lines
Quoted 8 lines
Additionally, when the context is paused,
kdamond_fnremains in this sleep loop and skips callingdamos_adjust_quota(), which meansquota->charged_fromis frozen.If the pause lasts for more than
LONG_MAXjiffies (e.g., about 24.8 days on a 32-bit system with HZ=1000), will system jiffies wrap past the half-range limit of the unsigned long type relative to the frozen timestamp?
Quoted 8 lines
Quoted 4 lines
If this wraparound occurs,
time_after_eq(jiffies, quota->charged_from + interval)would evaluate to false when unpaused. Would this cause the quota window to not reset for another 24.8 days, accumulatingcharged_szand blocking the scheme from being applied?That's a wild corner case, but I agree it is better to avoid the problematic case. I'm still thinking about the good way for that. Anyway, I will address this in the next spin.
The root cause of the issue was introduced before this patch, so I fixed it with another hotfix [1]. So next spin of this patch will have no change.
[1] https://lore.kernel.org/[email protected]
Thanks,
SJ
[...]
SeongJae Park
maintainerRe: (sashiko review) [RFC PATCH v5 01/10] mm/damon/core: introduce damon_ctx->paused
Quoted 19 lines · On Wed, 1 Apr 2026 18:10:42 -0700 SeongJae Park <[email protected]> wrote:
Quoted 3 lines · On Mon, 23 Mar 2026 21:07:21 -0700 SeongJae Park <[email protected]> wrote:
Quoted 1 line · On Mon, 23 Mar 2026 18:28:00 -0700 SeongJae Park <[email protected]> wrote:
Forwarding Sashiko review for doing discussions via mails.
[...]
Quoted 13 lines
Quoted 12 lines
Additionally, when the context is paused,
kdamond_fnremains in this sleep loop and skips callingdamos_adjust_quota(), which meansquota->charged_fromis frozen.If the pause lasts for more than
LONG_MAXjiffies (e.g., about 24.8 days on a 32-bit system with HZ=1000), will system jiffies wrap past the half-range limit of the unsigned long type relative to the frozen timestamp?If this wraparound occurs,
time_after_eq(jiffies, quota->charged_from + interval)would evaluate to false when unpaused. Would this cause the quota window to not reset for another 24.8 days, accumulatingcharged_szand blocking the scheme from being applied?
Quoted 6 lines
Quoted 3 lines
That's a wild corner case, but I agree it is better to avoid the problematic case. I'm still thinking about the good way for that. Anyway, I will address this in the next spin.
The root cause of the issue was introduced before this patch, so I fixed it with another hotfix [1]. So next spin of this patch will have no change.
FWIW, I'm planning to post the next version of this series only after rebasing to the latest mm-new, after the all MM pull requests for next -rc1 are merged.
Quoted 2 lines
Thanks,
SJ
[...]
SeongJae Park
maintainerRFC PATCH v5 2/10 mm/damon/sysfs: add pause file under context dir
In reply to SeongJae ParkAdd pause DAMON sysfs file under the context directory. It exposes the damon_ctx->pause API parameter to the users so that they can use the pause/resume feature.
--- mm/damon/sysfs.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
mm/damon/sysfs.c +31 -0
@@ -866,6 +866,7 @@ struct damon_sysfs_context {struct damon_sysfs_attrs *attrs;struct damon_sysfs_targets *targets;struct damon_sysfs_schemes *schemes; +bool pause; }; static struct damon_sysfs_context *damon_sysfs_context_alloc(
@@ -878,6 +879,7 @@ static struct damon_sysfs_context *damon_sysfs_context_alloc( context->kobj = (struct kobject ){}; context->ops_id = ops_id; context->addr_unit =1 ; + context->pause = false;return context; }
@@ -1053,6 +1055,30 @@ static ssize_t addr_unit_store(struct kobject *kobj,return count; } +static ssize_t pause_show (struct kobject *kobj,struct kobj_attribute *attr, +char *buf) +{ +struct damon_sysfs_context *context =container_of (kobj, + struct damon_sysfs_context, kobj); + +return sysfs_emit (buf,"%c\n" , context->pause ?'Y' :'N' ); +} + +static ssize_t pause_store (struct kobject *kobj,struct kobj_attribute *attr, +const char *buf,size_t count) +{ +struct damon_sysfs_context *context =container_of (kobj, + struct damon_sysfs_context, kobj); +bool pause; +int err =kstrtobool (buf, &pause); + +if (err) +return err; + context->pause = pause; +return count; +} + +static void damon_sysfs_context_release (struct kobject *kobj) {kfree (container_of(kobj ,struct damon_sysfs_context ,kobj ));
@@ -1067,10 +1093,14 @@ static struct kobj_attribute damon_sysfs_context_operations_attr =static struct kobj_attribute damon_sysfs_context_addr_unit_attr =__ATTR_RW_MODE (addr_unit,0600 ); +static struct kobj_attribute damon_sysfs_context_pause_attr = +__ATTR_RW_MODE (pause,0600 ); +static struct attribute *damon_sysfs_context_attrs[] = { &damon_sysfs_context_avail_operations_attr.attr, &damon_sysfs_context_operations_attr.attr, &damon_sysfs_context_addr_unit_attr.attr, + &damon_sysfs_context_pause_attr.attr,NULL , };ATTRIBUTE_GROUPS (damon_sysfs_context);
@@ -1470,6 +1500,7 @@ static int damon_sysfs_apply_inputs(struct damon_ctx *ctx,if (sys_ctx->ops_id ==DAMON_OPS_PADDR ) ctx->min_region_sz =max (DAMON_MIN_REGION_SZ / sys_ctx->addr_unit,1 ); + ctx->pause = sys_ctx->pause; err =damon_sysfs_set_attrs (ctx, sys_ctx->attrs);if (err)return err;
Signature · 1 line
2.47.3
SeongJae Park
maintainerRFC PATCH v5 3/10 Docs/mm/damon/design: update for context pause/resume feature
In reply to SeongJae ParkUpdate DAMON design document for the context execution pause/resume feature.
--- Documentation/mm/damon/design.rst | 7 +++++++ 1 file changed, 7 insertions(+)
Documentation/mm/damon/design.rst +7 -0
@@ -19,6 +19,13 @@ types of monitoring. To know how user-space can do the configurations and start/stop DAMON, refer to :ref:`DAMON sysfs interface <sysfs_interface>` documentation. +Users can also request each context execution to be paused and resumed. When +it is paused, the kdamond does nothing other than applying online parameter +update. + +To know how user-space can pause/resume each context, refer to :ref:`DAMON +sysfs context <sysfs_context>` usage documentation. + Overall Architecture ====================
Signature · 1 line
2.47.3
SeongJae Park
maintainerRFC PATCH v5 4/10 Docs/admin-guide/mm/damon/usage: update for pause file
In reply to SeongJae ParkUpdate DAMON usage document for the DAMON context execution pause/resume feature.
--- Documentation/admin-guide/mm/damon/usage.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
Documentation/admin-guide/mm/damon/usage.rst +8 -4
@@ -66,7 +66,8 @@ comma (","). │ :ref:`kdamonds <sysfs_kdamonds>`/nr_kdamonds │ │ :ref:`0 <sysfs_kdamond>`/state,pid,refresh_ms │ │ │ :ref:`contexts <sysfs_contexts>`/nr_contexts - │ │ │ │ :ref:`0 <sysfs_context>`/avail_operations,operations,addr_unit + │ │ │ │ :ref:`0 <sysfs_context>`/avail_operations,operations,addr_unit, + │ │ │ │ pause │ │ │ │ │ :ref:`monitoring_attrs <sysfs_monitoring_attrs>`/ │ │ │ │ │ │ intervals/sample_us,aggr_us,update_us │ │ │ │ │ │ │ intervals_goal/access_bp,aggrs,min_sample_us,max_sample_us
@@ -194,9 +195,9 @@ details). At the moment, only one context per kdamond is supported, so only contexts/<N>/ ------------- -In each context directory, three files (``avail_operations``, ``operations`` -and ``addr_unit``) and three directories (``monitoring_attrs``, ``targets``, -and ``schemes``) exist. +In each context directory, four files (``avail_operations``, ``operations``, +``addr_unit`` and ``pause``) and three directories (``monitoring_attrs``, +``targets``, and ``schemes``) exist. DAMON supports multiple types of :ref:`monitoring operations <damon_design_configurable_operations_set>`, including those for virtual address
@@ -214,6 +215,9 @@ reading from the ``operations`` file. ``addr_unit`` file is for setting and getting the :ref:`address unit <damon_design_addr_unit>` parameter of the operations set. +``pause`` file is for setting and getting the :ref:`pause request +<damon_design_execution_model_and_data_structures>` parameter of the context. + .. _sysfs_monitoring_attrs: contexts/<N>/monitoring_attrs/
Signature · 1 line
2.47.3
SeongJae Park
maintainerRFC PATCH v5 5/10 Docs/ABI/damon: update for pause sysfs file
In reply to SeongJae ParkUpdate DAMON ABI document for the DAMON context execution pause/resume feature.
--- Documentation/ABI/testing/sysfs-kernel-mm-damon | 7 +++++++ 1 file changed, 7 insertions(+)
Documentation/ABI/testing/sysfs-kernel-mm-damon +7 -0
@@ -84,6 +84,13 @@ Description: Writing an integer to this file sets the 'address unit' parameter of the given operations set of the context. Reading the file returns the last-written 'address unit' value. +What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/pause +Date: Mar 2026 +Contact: SeongJae Park <[email protected]> +Description: Writing a boolean keyword to this file sets the 'pause' request + parameter for the context. Reading the file returns the + last-written 'pause' value. + What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/monitoring_attrs/intervals/sample_us Date: Mar 2022 Contact: SeongJae Park <[email protected]>
Signature · 1 line
2.47.3
SeongJae Park
maintainerRFC PATCH v5 6/10 mm/damon/tests/core-kunit: test pause commitment
In reply to SeongJae ParkAdd a kunit test for commitment of damon_ctx->pause parameter that can be done using damon_commit_ctx().
--- mm/damon/tests/core-kunit.h | 4 ++++ 1 file changed, 4 insertions(+)
mm/damon/tests/core-kunit.h +4 -0
@@ -1077,6 +1077,10 @@ static void damon_test_commit_ctx(struct kunit *test)KUNIT_EXPECT_EQ (test,damon_commit_ctx (dst, src),0 ); src->min_region_sz =4095 ;KUNIT_EXPECT_EQ (test,damon_commit_ctx (dst, src), -EINVAL ); + src->min_region_sz =4096 ; + src->pause = true; +KUNIT_EXPECT_EQ (test,damon_commit_ctx (dst, src),0 ); +KUNIT_EXPECT_TRUE (test, dst->pause);damon_destroy_ctx (src);damon_destroy_ctx (dst); }
Signature · 1 line
2.47.3
SeongJae Park
maintainerRFC PATCH v5 7/10 selftests/damon/_damon_sysfs: support pause file staging
In reply to SeongJae ParkDAMON test-purpose sysfs interface control Python module, _damon_sysfs, is not supporting the newly added pause file. Add the support of the file, for future test and use of the feature.
--- tools/testing/selftests/damon/_damon_sysfs.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
tools/testing/selftests/damon/_damon_sysfs.py +9 -1
@@ -604,10 +604,11 @@ class DamonCtx: targets = None schemes = None kdamond = None + pause = None idx = None def __init__(self, ops='paddr', monitoring_attrs=DamonAttrs(), targets=[], - schemes=[]): + schemes=[], pause=False): self.ops = ops self.monitoring_attrs = monitoring_attrs self.monitoring_attrs.context = self
@@ -622,6 +623,8 @@ class DamonCtx: scheme.idx = idx scheme.context = self + self.pause=pause + def sysfs_dir(self): return os.path.join(self.kdamond.sysfs_dir(), 'contexts', '%d' % self.idx)
@@ -662,6 +665,11 @@ class DamonCtx: err = scheme.stage() if err is not None: return err + + err = write_file(os.path.join(self.sysfs_dir(), 'pause'), self.pause) + if err is not None: + return err + return None class Kdamond:
Signature · 1 line
2.47.3
SeongJae Park
maintainerRe: (sashiko review) [RFC PATCH v5 07/10] selftests/damon/_damon_sysfs: support pause file staging
Forwarding Sashiko review for doing discussions via mails.
# review url: https://sashiko.dev/#/patchset/[email protected] # start of sashiko.dev inline review commit d9ca6c4a33fc4d613982730edda6f4b67ae30a67 Author: SeongJae Park <[email protected]> selftests/damon/_damon_sysfs: support pause file staging
This commit adds support for the newly added pause file to the DAMON test-purpose sysfs interface control Python module.
Quoted 3 lines
tools/testing/selftests/damon/_damon_sysfs.py +0
-0
[ ... ]
tools/testing/selftests/damon/_damon_sysfs.py class DamonCtx: · line 611
Quoted 10 lines
class DamonCtx:
targets = None
schemes = None
kdamond = Nonetools/testing/selftests/damon/_damon_sysfs.py +2
-1+ pause = None idx = None def __init__(self, ops='paddr', monitoring_attrs=DamonAttrs(), targets=[], - schemes=[]): + schemes=[], pause=False):
This isn't a bug introduced by this patch, but since the function signature is being modified here, is it a good time to address the mutable default arguments?
In Python, default arguments are evaluated exactly once at function definition time. This means any instances of DamonCtx created without explicitly providing targets, schemes, or monitoring_attrs will share the same list structures and DamonAttrs instance in memory.
For example, self.monitoring_attrs.context = self overwrites the context attribute of the shared DamonAttrs object for all default contexts.
Would it be better to change these defaults to None and instantiate them within the method body to avoid unexpected state sharing across instances?
Quoted 3 lines
self.ops = ops
self.monitoring_attrs =monitoring_attrs
self.monitoring_attrs.context = self
# end of sashiko.dev inline review # review url: https://sashiko.dev/#/patchset/[email protected] # # hkml [1] generated a draft of this mail. It can be regenerated # using below command: # # hkml patch sashiko_dev --for_forwarding \ # [email protected] # # [1] https://github.com/sjp38/hackermail
Sent using hkml (https://github.com/sjp38/hackermail)
SeongJae Park
maintainerRe: (sashiko review) [RFC PATCH v5 07/10] selftests/damon/_damon_sysfs: support pause file staging
Quoted 35 lines · On Mon, 23 Mar 2026 18:28:24 -0700 SeongJae Park <[email protected]> wrote:
Forwarding Sashiko review for doing discussions via mails.
# review url: https://sashiko.dev/#/patchset/[email protected] # start of sashiko.dev inline review commit d9ca6c4a33fc4d613982730edda6f4b67ae30a67 Author: SeongJae Park <[email protected]> selftests/damon/_damon_sysfs: support pause file stagingThis commit adds support for the newly added pause file to the DAMON test-purpose sysfs interface control Python module.
Quoted 3 lines
tools/testing/selftests/damon/_damon_sysfs.py +0
-0[ ... ]
tools/testing/selftests/damon/_damon_sysfs.py class DamonCtx: · line 611
Quoted 10 lines
class DamonCtx:
targets = None
schemes = None
kdamond = Nonetools/testing/selftests/damon/_damon_sysfs.py +2
-1+ pause = None idx = None def __init__(self, ops='paddr', monitoring_attrs=DamonAttrs(), targets=[], - schemes=[]): + schemes=[], pause=False):This isn't a bug introduced by this patch, but since the function signature is being modified here, is it a good time to address the mutable default arguments?
In Python, default arguments are evaluated exactly once at function definition time. This means any instances of DamonCtx created without explicitly providing targets, schemes, or
monitoring_attrswill share the same list structures and DamonAttrs instance in memory.
Quoted 5 lines
For example, self.monitoring_attrs.context = self overwrites the context attribute of the shared DamonAttrs object for all default contexts.
Would it be better to change these defaults to None and instantiate them within the method body to avoid unexpected state sharing across instances?
I agree changing the defaults to None is a good idea. But that would better to be another patch, not this one.
Thanks,
SJ
[...]
SeongJae Park
maintainerRFC PATCH v5 8/10 selftests/damon/drgn_dump_damon_status: dump pause
In reply to SeongJae Parkdrgn_dump_damon_status is not dumping the damon_ctx->pause parameter value, so it cannot be tested. Dump it for future tests.
--- tools/testing/selftests/damon/drgn_dump_damon_status.py | 1 + 1 file changed, 1 insertion(+)
tools/testing/selftests/damon/drgn_dump_damon_status.py +1 -0
@@ -200,6 +200,7 @@ def damon_ctx_to_dict(ctx): ['attrs', attrs_to_dict], ['adaptive_targets', targets_to_list], ['schemes', schemes_to_list], + ['pause', bool], ]) def main():
Signature · 1 line
2.47.3
SeongJae Park
maintainerRFC PATCH v5 9/10 selftests/damon/sysfs.py: check pause on assert_ctx_committed()
In reply to SeongJae ParkExtend sysfs.py tests to confirm damon_ctx->pause can be set using the pause sysfs file.
--- tools/testing/selftests/damon/sysfs.py | 1 + 1 file changed, 1 insertion(+)
tools/testing/selftests/damon/sysfs.py +1 -0
@@ -190,6 +190,7 @@ def assert_ctx_committed(ctx, dump): assert_monitoring_attrs_committed(ctx.monitoring_attrs, dump['attrs']) assert_monitoring_targets_committed(ctx.targets, dump['adaptive_targets']) assert_schemes_committed(ctx.schemes, dump['schemes']) + assert_true(dump['pause'] == ctx.pause, 'pause', dump) def assert_ctxs_committed(kdamonds): status, err = dump_damon_status_dict(kdamonds.kdamonds[0].pid)
Signature · 1 line
2.47.3
SeongJae Park
maintainerRFC PATCH v5 10/10 selftests/damon/sysfs.py: pause DAMON before dumping status
In reply to SeongJae ParkThe sysfs.py test commits DAMON parameters, dump the internal DAMON state, and show if the parameters are committed as expected using the dumped state. While the dumping is ongoing, DAMON is alive. It can make internal changes including addition and removal of regions. It can therefore make a race that can result in false test results. Pause DAMON execution during the state dumping to avoid such races.
--- tools/testing/selftests/damon/sysfs.py | 38 ++++++++++++++++++++++++++ 1 file changed, 38 insertions(+)
tools/testing/selftests/damon/sysfs.py +38 -0
@@ -193,18 +193,55 @@ def assert_ctx_committed(ctx, dump): assert_true(dump['pause'] == ctx.pause, 'pause', dump) def assert_ctxs_committed(kdamonds): + ctxs_paused_for_dump = [] + kdamonds_paused_for_dump = [] + # pause for safe state dumping + for kd in kdamonds.kdamonds: + for ctx in kd.contexts: + if ctx.pause is False: + ctx.pause = True + ctxs_paused_for_dump.append(ctx) + if not kd in kdamonds_paused_for_dump: + kdamonds_paused_for_dump.append(kd) + if kd in kdamonds_paused_for_dump: + err = kd.commit() + if err is not None: + print('pause fail (%s)' % err) + kdamonds.stop() + exit(1) + status, err = dump_damon_status_dict(kdamonds.kdamonds[0].pid) if err is not None: print(err) kdamonds.stop() exit(1) + # resume contexts paused for safe state dumping + for ctx in ctxs_paused_for_dump: + ctx.pause = False + for kd in kdamonds_paused_for_dump: + err = kd.commit() + if err is not None: + print('resume fail (%s)' % err) + kdamonds.stop() + exit(1) + + # restore for comparison + for ctx in ctxs_paused_for_dump: + ctx.pause = True + ctxs = kdamonds.kdamonds[0].contexts dump = status['contexts'] assert_true(len(ctxs) == len(dump), 'ctxs length', dump) for idx, ctx in enumerate(ctxs): assert_ctx_committed(ctx, dump[idx]) + # restore for the caller + for kd in kdamonds.kdamonds: + for ctx in kd.contexts: + if ctx in ctxs_paused_for_dump: + ctx.pause = False + def main(): kdamonds = _damon_sysfs.Kdamonds( [_damon_sysfs.Kdamond(
@@ -302,6 +339,7 @@ def main(): print('kdamond start failed: %s' % err) exit(1) kdamonds.kdamonds[0].contexts[0].targets[1].obsolete = True + kdamonds.kdamonds[0].contexts[0].pause = True kdamonds.kdamonds[0].commit() del kdamonds.kdamonds[0].contexts[0].targets[1] assert_ctxs_committed(kdamonds)
Signature · 1 line
2.47.3
SeongJae Park
maintainerRe: (sashiko status) [RFC PATCH v5 00/10] mm/damon: let DAMON be paused and resumed
In reply to SeongJae ParkForwarding sashiko.dev review status for this thread.
# review url: https://sashiko.dev/#/patchset/[email protected]
- [RFC PATCH v5 01/10] mm/damon/core: introduce damon_ctx->paused
- status: Reviewed
- review: ISSUES MAY FOUND
- [RFC PATCH v5 02/10] mm/damon/sysfs: add pause file under context dir
- status: Reviewed
- review: No issues found.
- [RFC PATCH v5 03/10] Docs/mm/damon/design: update for context pause/resume feature
- status: Reviewed
- review: No issues found.
- [RFC PATCH v5 04/10] Docs/admin-guide/mm/damon/usage: update for pause file
- status: Reviewed
- review: No issues found.
- [RFC PATCH v5 05/10] Docs/ABI/damon: update for pause sysfs file
- status: Reviewed
- review: No issues found.
- [RFC PATCH v5 06/10] mm/damon/tests/core-kunit: test pause commitment
- status: Reviewed
- review: No issues found.
- [RFC PATCH v5 07/10] selftests/damon/_damon_sysfs: support pause file staging
- status: Reviewed
- review: ISSUES MAY FOUND
- [RFC PATCH v5 08/10] selftests/damon/drgn_dump_damon_status: dump pause
- status: Reviewed
- review: No issues found.
- [RFC PATCH v5 09/10] selftests/damon/sysfs.py: check pause on assert_ctx_committed()
- status: Reviewed
- review: No issues found.
- [RFC PATCH v5 10/10] selftests/damon/sysfs.py: pause DAMON before dumping status
- status: Reviewed
- review: No issues found.
# hkml [1] generated a draft of this mail. It can be regenerated # using below command: # # hkml patch sashiko_dev --thread_status --for_forwarding \ # [email protected] # # [1] https://github.com/sjp38/hackermail
Sent using hkml (https://github.com/sjp38/hackermail)