* [RFC PATCH 0/2] DAMON: add priority-based scheme application control
@ 2025-09-22 10:10 Enze Li
2025-09-22 10:10 ` [RFC PATCH 1/2] mm/damon/core: introduce priority concept for DAMON Enze Li
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Enze Li @ 2025-09-22 10:10 UTC (permalink / raw)
To: sj, akpm; +Cc: damon, linux-mm, enze.li, Enze Li
This patchset introduces a priority mechanism for DAMON's scheme
application, allowing users to specify the relative importance of
monitored processes. The changes ensure that higher-priority targets
receive more frequent memory management operations while maintaining
fairness across all monitored processes.
The first patch modifies kdamond_apply_schemes to implement
priority-based scheduling, where targets are processed in proportion to
their assigned priority values. For example, a target with priority 50
will be serviced 50 times for every 30 times a target with priority 30
is processed.
The second patch adds a sysfs interface (priority under each target's
directory) to dynamically configure these priorities at runtime. This
enables fine-grained control over DAMON's behavior, making it more
adaptable to performance-sensitive workloads.
Together, these changes provide better flexibility for users who need
differentiated memory management policies across different processes
while maintaining backward compatibility with existing setups.
You may want to verify this feature using the following testing
procedure:
# git clone -b v2 https://github.com/lienze/damo.git
# cd damo
# ./damo start --target_pid $(pidof <target1>) --priority 50 \
--target_pid $(pidof <target2>) --priority 30 --damos_action \
pageout --damos_age 5s 5s
Enze Li (2):
mm/damon/core: introduce priority concept for DAMON
mm/damon/sysfs: add priority support for DAMOS targets
include/linux/damon.h | 2 +
mm/damon/core.c | 91 ++++++++++++++++++++++++++++++++++++++++++-
mm/damon/sysfs.c | 28 +++++++++++++
3 files changed, 119 insertions(+), 2 deletions(-)
--
2.51.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [RFC PATCH 1/2] mm/damon/core: introduce priority concept for DAMON 2025-09-22 10:10 [RFC PATCH 0/2] DAMON: add priority-based scheme application control Enze Li @ 2025-09-22 10:10 ` Enze Li 2025-09-22 11:16 ` Gutierrez Asier 2025-09-22 10:10 ` [RFC PATCH 2/2] mm/damon/sysfs: add priority support for DAMOS targets Enze Li 2025-09-22 13:01 ` [RFC PATCH 0/2] DAMON: add priority-based scheme application control SeongJae Park 2 siblings, 1 reply; 8+ messages in thread From: Enze Li @ 2025-09-22 10:10 UTC (permalink / raw) To: sj, akpm; +Cc: damon, linux-mm, enze.li, Enze Li This patch introduces a priority-based scheme application mechanism to DAMON, enhancing its ability to prioritize memory management operations for specific processes. Currently, DAMON applies schemes uniformly across all monitored processes without regard to their relative importance. This change allows users to assign a priority value to each target process, influencing the frequency with which schemes are applied. The core implementation modifies kdamond_apply_schemes to track and apply schemes according to user-defined priorities. For instance, if process A has priority 50 and process B has priority 30, damon_do_apply_schemes will be called 50 times on A for every 30 times on B. This ratio ensures that higher-priority processes receive more frequent attention from DAMON's operations, which can be critical for performance-sensitive workloads or prioritized tasks. The change maintains the overall fairness and non-starvation properties by cycling through targets proportionally. Existing behavior is preserved for targets without a priority assigned, ensuring backward compatibility. This provides system administrators with finer control over how DAMON’s memory optimizations are distributed, making the subsystem more adaptable to varied use cases and performance requirements. Signed-off-by: Enze Li <lienze@kylinos.cn> --- include/linux/damon.h | 2 + mm/damon/core.c | 91 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/include/linux/damon.h b/include/linux/damon.h index f13664c62ddd..a6d3ce186fdc 100644 --- a/include/linux/damon.h +++ b/include/linux/damon.h @@ -102,6 +102,8 @@ struct damon_target { unsigned int nr_regions; struct list_head regions_list; struct list_head list; + unsigned int priority; + struct list_head pr_list; }; /** diff --git a/mm/damon/core.c b/mm/damon/core.c index 106ee8b0f2d5..c336914d03cc 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -15,6 +15,7 @@ #include <linux/slab.h> #include <linux/string.h> #include <linux/string_choices.h> +#include <linux/list_sort.h> #define CREATE_TRACE_POINTS #include <trace/events/damon.h> @@ -28,6 +29,11 @@ static DEFINE_MUTEX(damon_lock); static int nr_running_ctxs; static bool running_exclusive_ctxs; +static LIST_HEAD(priority_list); +static bool init_priority_list; +static int priority_level; +static int priority_tick; + static DEFINE_MUTEX(damon_ops_lock); static struct damon_operations damon_registered_ops[NR_DAMON_OPS]; @@ -474,6 +480,7 @@ struct damon_target *damon_new_target(void) t->nr_regions = 0; INIT_LIST_HEAD(&t->regions_list); INIT_LIST_HEAD(&t->list); + t->priority = 0; return t; } @@ -2154,6 +2161,72 @@ static void damos_adjust_quota(struct damon_ctx *c, struct damos *s) quota->min_score = score; } +static int damon_priority_head(void) +{ + struct damon_target *t = list_first_entry_or_null(&priority_list, + struct damon_target, pr_list); + + return t->priority; +} + +static int damon_priority_find_next(void) +{ + struct damon_target *t; + + list_for_each_entry(t, &priority_list, pr_list) + if (priority_level > t->priority) { + priority_level = t->priority; + return t->priority; + } + return damon_priority_head(); +} + +static bool kdamond_targets_priority_enabled(struct damon_ctx *c) +{ + struct damon_target *t; + + damon_for_each_target(t, c) + if (t->priority > 0) + return true; + return false; +} + +static int damon_priority_cmp(void *priv, const struct list_head *a, + const struct list_head *b) +{ + struct damon_target *ta = container_of(a, struct damon_target, pr_list); + struct damon_target *tb = container_of(b, struct damon_target, pr_list); + + if (ta->priority < tb->priority) + return 1; + else + return 0; +} + +static bool kdamond_targets_priority_init(struct damon_ctx *c) +{ + struct damon_target *t; + + damon_for_each_target(t, c) + list_add_tail(&t->pr_list, &priority_list); + + list_for_each_entry(t, &priority_list, pr_list) + pr_debug("damon target priority %d %p\n", t->priority, t->pid); + + list_sort(NULL, &priority_list, damon_priority_cmp); + + list_for_each_entry(t, &priority_list, pr_list) + pr_debug("damon target priority after sort %d %p\n", + t->priority, t->pid); + + init_priority_list = true; + priority_level = damon_priority_head(); + priority_tick = priority_level; + pr_debug("damon target priority init level=%d tick=%d\n", + priority_level, priority_tick); + return true; +} + static void kdamond_apply_schemes(struct damon_ctx *c) { struct damon_target *t; @@ -2162,6 +2235,7 @@ static void kdamond_apply_schemes(struct damon_ctx *c) unsigned long sample_interval = c->attrs.sample_interval ? c->attrs.sample_interval : 1; bool has_schemes_to_apply = false; + bool priority_enabled = false; damon_for_each_scheme(s, c) { if (c->passed_sample_intervals < s->next_apply_sis) @@ -2178,10 +2252,23 @@ static void kdamond_apply_schemes(struct damon_ctx *c) if (!has_schemes_to_apply) return; + priority_enabled = kdamond_targets_priority_enabled(c); + if (priority_enabled && !init_priority_list) + kdamond_targets_priority_init(c); + mutex_lock(&c->walk_control_lock); damon_for_each_target(t, c) { - damon_for_each_region_safe(r, next_r, t) - damon_do_apply_schemes(c, t, r); + if (priority_enabled == false || + (priority_enabled == true && t->priority == priority_level && + priority_tick-- > 0)) { + if (priority_enabled == true && priority_tick <= 0) { + priority_level = damon_priority_find_next(); + priority_tick = priority_level; + } + pr_debug("tick() %d(%d)\n", priority_level, priority_tick); + damon_for_each_region_safe(r, next_r, t) + damon_do_apply_schemes(c, t, r); + } } damon_for_each_scheme(s, c) { -- 2.51.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC PATCH 1/2] mm/damon/core: introduce priority concept for DAMON 2025-09-22 10:10 ` [RFC PATCH 1/2] mm/damon/core: introduce priority concept for DAMON Enze Li @ 2025-09-22 11:16 ` Gutierrez Asier 2025-09-26 3:57 ` Enze Li 0 siblings, 1 reply; 8+ messages in thread From: Gutierrez Asier @ 2025-09-22 11:16 UTC (permalink / raw) To: Enze Li, sj, akpm; +Cc: damon, linux-mm, enze.li Hi, On 9/22/2025 1:10 PM, Enze Li wrote: > This patch introduces a priority-based scheme application mechanism to > DAMON, enhancing its ability to prioritize memory management operations > for specific processes. Currently, DAMON applies schemes uniformly > across all monitored processes without regard to their relative > importance. This change allows users to assign a priority value to each > target process, influencing the frequency with which schemes are applied. > > The core implementation modifies kdamond_apply_schemes to track and apply > schemes according to user-defined priorities. For instance, if process A > has priority 50 and process B has priority 30, damon_do_apply_schemes > will be called 50 times on A for every 30 times on B. This ratio > ensures that higher-priority processes receive more frequent attention > from DAMON's operations, which can be critical for performance-sensitive > workloads or prioritized tasks. > > The change maintains the overall fairness and non-starvation properties > by cycling through targets proportionally. Existing behavior is > preserved for targets without a priority assigned, ensuring backward > compatibility. This provides system administrators with finer control > over how DAMON’s memory optimizations are distributed, making the > subsystem more adaptable to varied use cases and performance > requirements. > > Signed-off-by: Enze Li <lienze@kylinos.cn> > --- > include/linux/damon.h | 2 + > mm/damon/core.c | 91 ++++++++++++++++++++++++++++++++++++++++++- > 2 files changed, 91 insertions(+), 2 deletions(-) > > diff --git a/include/linux/damon.h b/include/linux/damon.h > index f13664c62ddd..a6d3ce186fdc 100644 > --- a/include/linux/damon.h > +++ b/include/linux/damon.h > @@ -102,6 +102,8 @@ struct damon_target { > unsigned int nr_regions; > struct list_head regions_list; > struct list_head list; > + unsigned int priority; > + struct list_head pr_list; > }; > > /** > diff --git a/mm/damon/core.c b/mm/damon/core.c > index 106ee8b0f2d5..c336914d03cc 100644 > --- a/mm/damon/core.c > +++ b/mm/damon/core.c > @@ -15,6 +15,7 @@ > #include <linux/slab.h> > #include <linux/string.h> > #include <linux/string_choices.h> > +#include <linux/list_sort.h> > > #define CREATE_TRACE_POINTS > #include <trace/events/damon.h> > @@ -28,6 +29,11 @@ static DEFINE_MUTEX(damon_lock); > static int nr_running_ctxs; > static bool running_exclusive_ctxs; > > +static LIST_HEAD(priority_list); > +static bool init_priority_list; > +static int priority_level; > +static int priority_tick; What would happen if you have 2 kdamond threads running at the same time? I guess that you will end up a data race in priority_tick. > + > static DEFINE_MUTEX(damon_ops_lock); > static struct damon_operations damon_registered_ops[NR_DAMON_OPS]; > > @@ -474,6 +480,7 @@ struct damon_target *damon_new_target(void) > t->nr_regions = 0; > INIT_LIST_HEAD(&t->regions_list); > INIT_LIST_HEAD(&t->list); > + t->priority = 0; > > return t; > } > @@ -2154,6 +2161,72 @@ static void damos_adjust_quota(struct damon_ctx *c, struct damos *s) > quota->min_score = score; > } > > +static int damon_priority_head(void) > +{ > + struct damon_target *t = list_first_entry_or_null(&priority_list, > + struct damon_target, pr_list); Don't we need to check for a null pointer here? > + > + return t->priority; > +} > + > +static int damon_priority_find_next(void) > +{ > + struct damon_target *t; > + > + list_for_each_entry(t, &priority_list, pr_list) > + if (priority_level > t->priority) { > + priority_level = t->priority; > + return t->priority; > + } > + return damon_priority_head(); > +} > + > +static bool kdamond_targets_priority_enabled(struct damon_ctx *c) > +{ > + struct damon_target *t; > + > + damon_for_each_target(t, c) > + if (t->priority > 0) > + return true; > + return false; > +} > + > +static int damon_priority_cmp(void *priv, const struct list_head *a, > + const struct list_head *b) > +{ > + struct damon_target *ta = container_of(a, struct damon_target, pr_list); > + struct damon_target *tb = container_of(b, struct damon_target, pr_list); > + > + if (ta->priority < tb->priority) > + return 1; > + else > + return 0; > +} > + > +static bool kdamond_targets_priority_init(struct damon_ctx *c) > +{ > + struct damon_target *t; > + > + damon_for_each_target(t, c) > + list_add_tail(&t->pr_list, &priority_list); > + > + list_for_each_entry(t, &priority_list, pr_list) > + pr_debug("damon target priority %d %p\n", t->priority, t->pid); > + > + list_sort(NULL, &priority_list, damon_priority_cmp); > + > + list_for_each_entry(t, &priority_list, pr_list) > + pr_debug("damon target priority after sort %d %p\n", > + t->priority, t->pid); > + > + init_priority_list = true; > + priority_level = damon_priority_head(); > + priority_tick = priority_level; > + pr_debug("damon target priority init level=%d tick=%d\n", > + priority_level, priority_tick); > + return true; > +} > + > static void kdamond_apply_schemes(struct damon_ctx *c) > { > struct damon_target *t; > @@ -2162,6 +2235,7 @@ static void kdamond_apply_schemes(struct damon_ctx *c) > unsigned long sample_interval = c->attrs.sample_interval ? > c->attrs.sample_interval : 1; > bool has_schemes_to_apply = false; > + bool priority_enabled = false; > > damon_for_each_scheme(s, c) { > if (c->passed_sample_intervals < s->next_apply_sis) > @@ -2178,10 +2252,23 @@ static void kdamond_apply_schemes(struct damon_ctx *c) > if (!has_schemes_to_apply) > return; > > + priority_enabled = kdamond_targets_priority_enabled(c); > + if (priority_enabled && !init_priority_list) > + kdamond_targets_priority_init(c); What happens if you later add a new target? priority_list is already initialized, which means that list sorting will not take place and it will break your logic. > + > mutex_lock(&c->walk_control_lock); > damon_for_each_target(t, c) { > - damon_for_each_region_safe(r, next_r, t) > - damon_do_apply_schemes(c, t, r); > + if (priority_enabled == false || > + (priority_enabled == true && t->priority == priority_level && > + priority_tick-- > 0)) { > + if (priority_enabled == true && priority_tick <= 0) { > + priority_level = damon_priority_find_next(); > + priority_tick = priority_level; > + } > + pr_debug("tick() %d(%d)\n", priority_level, priority_tick); > + damon_for_each_region_safe(r, next_r, t) > + damon_do_apply_schemes(c, t, r); > + } > } > > damon_for_each_scheme(s, c) { -- Asier Gutierrez Huawei ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC PATCH 1/2] mm/damon/core: introduce priority concept for DAMON 2025-09-22 11:16 ` Gutierrez Asier @ 2025-09-26 3:57 ` Enze Li 0 siblings, 0 replies; 8+ messages in thread From: Enze Li @ 2025-09-26 3:57 UTC (permalink / raw) To: Gutierrez Asier; +Cc: sj, akpm, damon, linux-mm, enze.li Hi Gutierrez, On Mon, Sep 22 2025 at 02:16:31 PM +0300, Gutierrez Asier wrote: > Hi, > > On 9/22/2025 1:10 PM, Enze Li wrote: >> This patch introduces a priority-based scheme application mechanism to >> DAMON, enhancing its ability to prioritize memory management operations >> for specific processes. Currently, DAMON applies schemes uniformly >> across all monitored processes without regard to their relative >> importance. This change allows users to assign a priority value to each >> target process, influencing the frequency with which schemes are applied. >> >> The core implementation modifies kdamond_apply_schemes to track and apply >> schemes according to user-defined priorities. For instance, if process A >> has priority 50 and process B has priority 30, damon_do_apply_schemes >> will be called 50 times on A for every 30 times on B. This ratio >> ensures that higher-priority processes receive more frequent attention >> from DAMON's operations, which can be critical for performance-sensitive >> workloads or prioritized tasks. >> >> The change maintains the overall fairness and non-starvation properties >> by cycling through targets proportionally. Existing behavior is >> preserved for targets without a priority assigned, ensuring backward >> compatibility. This provides system administrators with finer control >> over how DAMON’s memory optimizations are distributed, making the >> subsystem more adaptable to varied use cases and performance >> requirements. >> >> Signed-off-by: Enze Li <lienze@kylinos.cn> >> --- >> include/linux/damon.h | 2 + >> mm/damon/core.c | 91 ++++++++++++++++++++++++++++++++++++++++++- >> 2 files changed, 91 insertions(+), 2 deletions(-) >> >> diff --git a/include/linux/damon.h b/include/linux/damon.h >> index f13664c62ddd..a6d3ce186fdc 100644 >> --- a/include/linux/damon.h >> +++ b/include/linux/damon.h >> @@ -102,6 +102,8 @@ struct damon_target { >> unsigned int nr_regions; >> struct list_head regions_list; >> struct list_head list; >> + unsigned int priority; >> + struct list_head pr_list; >> }; >> >> /** >> diff --git a/mm/damon/core.c b/mm/damon/core.c >> index 106ee8b0f2d5..c336914d03cc 100644 >> --- a/mm/damon/core.c >> +++ b/mm/damon/core.c >> @@ -15,6 +15,7 @@ >> #include <linux/slab.h> >> #include <linux/string.h> >> #include <linux/string_choices.h> >> +#include <linux/list_sort.h> >> >> #define CREATE_TRACE_POINTS >> #include <trace/events/damon.h> >> @@ -28,6 +29,11 @@ static DEFINE_MUTEX(damon_lock); >> static int nr_running_ctxs; >> static bool running_exclusive_ctxs; >> >> +static LIST_HEAD(priority_list); >> +static bool init_priority_list; >> +static int priority_level; >> +static int priority_tick; > > What would happen if you have 2 kdamond threads running at the same time? > I guess that you will end up a data race in priority_tick. Currently, DAMON operates with just one kdamond thread. I'm not certain about the plans for multi-kdamond support, but I agree that it's a significant limitation for certain use cases. > >> + >> static DEFINE_MUTEX(damon_ops_lock); >> static struct damon_operations damon_registered_ops[NR_DAMON_OPS]; >> >> @@ -474,6 +480,7 @@ struct damon_target *damon_new_target(void) >> t->nr_regions = 0; >> INIT_LIST_HEAD(&t->regions_list); >> INIT_LIST_HEAD(&t->list); >> + t->priority = 0; >> >> return t; >> } >> @@ -2154,6 +2161,72 @@ static void damos_adjust_quota(struct damon_ctx *c, struct damos *s) >> quota->min_score = score; >> } >> >> +static int damon_priority_head(void) >> +{ >> + struct damon_target *t = list_first_entry_or_null(&priority_list, >> + struct damon_target, pr_list); > > Don't we need to check for a null pointer here? Oh, good catch! I totally overlooked that validation. Thanks for pointing it out. > >> + >> + return t->priority; >> +} >> + >> +static int damon_priority_find_next(void) >> +{ >> + struct damon_target *t; >> + >> + list_for_each_entry(t, &priority_list, pr_list) >> + if (priority_level > t->priority) { >> + priority_level = t->priority; >> + return t->priority; >> + } >> + return damon_priority_head(); >> +} >> + >> +static bool kdamond_targets_priority_enabled(struct damon_ctx *c) >> +{ >> + struct damon_target *t; >> + >> + damon_for_each_target(t, c) >> + if (t->priority > 0) >> + return true; >> + return false; >> +} >> + >> +static int damon_priority_cmp(void *priv, const struct list_head *a, >> + const struct list_head *b) >> +{ >> + struct damon_target *ta = container_of(a, struct damon_target, pr_list); >> + struct damon_target *tb = container_of(b, struct damon_target, pr_list); >> + >> + if (ta->priority < tb->priority) >> + return 1; >> + else >> + return 0; >> +} >> + >> +static bool kdamond_targets_priority_init(struct damon_ctx *c) >> +{ >> + struct damon_target *t; >> + >> + damon_for_each_target(t, c) >> + list_add_tail(&t->pr_list, &priority_list); >> + >> + list_for_each_entry(t, &priority_list, pr_list) >> + pr_debug("damon target priority %d %p\n", t->priority, t->pid); >> + >> + list_sort(NULL, &priority_list, damon_priority_cmp); >> + >> + list_for_each_entry(t, &priority_list, pr_list) >> + pr_debug("damon target priority after sort %d %p\n", >> + t->priority, t->pid); >> + >> + init_priority_list = true; >> + priority_level = damon_priority_head(); >> + priority_tick = priority_level; >> + pr_debug("damon target priority init level=%d tick=%d\n", >> + priority_level, priority_tick); >> + return true; >> +} >> + >> static void kdamond_apply_schemes(struct damon_ctx *c) >> { >> struct damon_target *t; >> @@ -2162,6 +2235,7 @@ static void kdamond_apply_schemes(struct damon_ctx *c) >> unsigned long sample_interval = c->attrs.sample_interval ? >> c->attrs.sample_interval : 1; >> bool has_schemes_to_apply = false; >> + bool priority_enabled = false; >> >> damon_for_each_scheme(s, c) { >> if (c->passed_sample_intervals < s->next_apply_sis) >> @@ -2178,10 +2252,23 @@ static void kdamond_apply_schemes(struct damon_ctx *c) >> if (!has_schemes_to_apply) >> return; >> >> + priority_enabled = kdamond_targets_priority_enabled(c); >> + if (priority_enabled && !init_priority_list) >> + kdamond_targets_priority_init(c); > > What happens if you later add a new target? priority_list is already > initialized, which means that list sorting will not take place and it will > break your logic. My idea is to keep it user-triggered, following DAMON's general pattern -- Hmm, just a thought. > >> + >> mutex_lock(&c->walk_control_lock); >> damon_for_each_target(t, c) { >> - damon_for_each_region_safe(r, next_r, t) >> - damon_do_apply_schemes(c, t, r); >> + if (priority_enabled == false || >> + (priority_enabled == true && t->priority == priority_level && >> + priority_tick-- > 0)) { >> + if (priority_enabled == true && priority_tick <= 0) { >> + priority_level = damon_priority_find_next(); >> + priority_tick = priority_level; >> + } >> + pr_debug("tick() %d(%d)\n", priority_level, priority_tick); >> + damon_for_each_region_safe(r, next_r, t) >> + damon_do_apply_schemes(c, t, r); >> + } >> } >> >> damon_for_each_scheme(s, c) { Thank you for your attention to this patch. This is a quick proof-of-concept patch intended to discuss whether the idea has merit. There might be aspects I have overlooked, and I greatly appreciate you pointing them out. It's worth noting that similar functionality might be achievable through a combination of existing schemes and filters. Thank you once again for your valuable review. Best Regards, Enze ^ permalink raw reply [flat|nested] 8+ messages in thread
* [RFC PATCH 2/2] mm/damon/sysfs: add priority support for DAMOS targets 2025-09-22 10:10 [RFC PATCH 0/2] DAMON: add priority-based scheme application control Enze Li 2025-09-22 10:10 ` [RFC PATCH 1/2] mm/damon/core: introduce priority concept for DAMON Enze Li @ 2025-09-22 10:10 ` Enze Li 2025-09-22 13:01 ` [RFC PATCH 0/2] DAMON: add priority-based scheme application control SeongJae Park 2 siblings, 0 replies; 8+ messages in thread From: Enze Li @ 2025-09-22 10:10 UTC (permalink / raw) To: sj, akpm; +Cc: damon, linux-mm, enze.li, Enze Li This patch extends the DAMON sysfs interface to support the configuration of target priorities, enabling users to assign and adjust the relative importance of monitored processes at runtime. A new sysfs file, priority, is added under each target’s directory (e.g., /sys/kernel/mm/damon/admin/kdamonds/0/contexts/<ctx>/targets/<target>/priority). Users can write an integer value to this file to set the priority level for the corresponding target. Reading the file returns the currently assigned priority. The interface integrates seamlessly with the existing priority-based scheduling mechanism introduced in the core DAMON logic. When a priority value is set via sysfs, it directly influences the frequency of scheme applications for the target. This enhancement provides user-space administrators and adaptive system controllers with the ability to dynamically adjust monitoring and memory management priorities based on real-time workload requirements. The change maintains full backward compatibility -- targets without a configured priority use the default behavior, ensuring no disruption to existing deployments. Signed-off-by: Enze Li <lienze@kylinos.cn> --- mm/damon/sysfs.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c index 6d2b0dab50cb..cd08732f3b6d 100644 --- a/mm/damon/sysfs.c +++ b/mm/damon/sysfs.c @@ -212,6 +212,7 @@ struct damon_sysfs_target { struct kobject kobj; struct damon_sysfs_regions *regions; int pid; + int priority; }; static struct damon_sysfs_target *damon_sysfs_target_alloc(void) @@ -271,8 +272,33 @@ static void damon_sysfs_target_release(struct kobject *kobj) static struct kobj_attribute damon_sysfs_target_pid_attr = __ATTR_RW_MODE(pid_target, 0600); +static ssize_t target_priority_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct damon_sysfs_target *target = container_of(kobj, + struct damon_sysfs_target, kobj); + + return sysfs_emit(buf, "%d\n", target->priority); +} + +static ssize_t target_priority_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + struct damon_sysfs_target *target = container_of(kobj, + struct damon_sysfs_target, kobj); + int err = kstrtoint(buf, 0, &target->priority); + + if (err) + return -EINVAL; + return count; +} + +static struct kobj_attribute damon_sysfs_target_priority = + __ATTR_RW_MODE(target_priority, 0600); + static struct attribute *damon_sysfs_target_attrs[] = { &damon_sysfs_target_pid_attr.attr, + &damon_sysfs_target_priority.attr, NULL, }; ATTRIBUTE_GROUPS(damon_sysfs_target); @@ -1340,6 +1366,8 @@ static int damon_sysfs_add_target(struct damon_sysfs_target *sys_target, /* caller will destroy targets */ return -EINVAL; } + t->priority = sys_target->priority; + return damon_sysfs_set_regions(t, sys_target->regions); } -- 2.51.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC PATCH 0/2] DAMON: add priority-based scheme application control 2025-09-22 10:10 [RFC PATCH 0/2] DAMON: add priority-based scheme application control Enze Li 2025-09-22 10:10 ` [RFC PATCH 1/2] mm/damon/core: introduce priority concept for DAMON Enze Li 2025-09-22 10:10 ` [RFC PATCH 2/2] mm/damon/sysfs: add priority support for DAMOS targets Enze Li @ 2025-09-22 13:01 ` SeongJae Park 2025-09-26 3:23 ` Enze Li 2 siblings, 1 reply; 8+ messages in thread From: SeongJae Park @ 2025-09-22 13:01 UTC (permalink / raw) To: Enze Li; +Cc: SeongJae Park, akpm, damon, linux-mm, enze.li Hello Enze, On Mon, 22 Sep 2025 18:10:20 +0800 Enze Li <lienze@kylinos.cn> wrote: > This patchset introduces a priority mechanism for DAMON's scheme > application, allowing users to specify the relative importance of > monitored processes. The changes ensure that higher-priority targets > receive more frequent memory management operations while maintaining > fairness across all monitored processes. Thank you for this patchset. There are features for monitoring target-based DAMOS filtering (DAMOS_FILTER_TYPE_TARGET) and per-scheme applying time interval (apply_interval_us). Couldn't those be used for your purpose? > > The first patch modifies kdamond_apply_schemes to implement > priority-based scheduling, where targets are processed in proportion to > their assigned priority values. For example, a target with priority 50 > will be serviced 50 times for every 30 times a target with priority 30 > is processed. > > The second patch adds a sysfs interface (priority under each target's > directory) to dynamically configure these priorities at runtime. This > enables fine-grained control over DAMON's behavior, making it more > adaptable to performance-sensitive workloads. > > Together, these changes provide better flexibility for users who need > differentiated memory management policies across different processes > while maintaining backward compatibility with existing setups. > > You may want to verify this feature using the following testing > procedure: > > # git clone -b v2 https://github.com/lienze/damo.git > # cd damo > # ./damo start --target_pid $(pidof <target1>) --priority 50 \ > --target_pid $(pidof <target2>) --priority 30 --damos_action \ > pageout --damos_age 5s 5s So I'm wondering a command like below could be used instead. $ sudo ./damo args damon \ --target_pid 123 \ --damos_action pageout --damos_age 5s 5s \ --damos_filter allow target 0 --damos_apply_interval 3s \ --target_pid 456 \ --damos_action pageout --damos_age 5s 5s \ --damos_filter allow target 1 --damos_apply_interval 5s \ --damos_nr_filters 1 1 Thanks, SJ [...] ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC PATCH 0/2] DAMON: add priority-based scheme application control 2025-09-22 13:01 ` [RFC PATCH 0/2] DAMON: add priority-based scheme application control SeongJae Park @ 2025-09-26 3:23 ` Enze Li 2025-09-26 17:37 ` SeongJae Park 0 siblings, 1 reply; 8+ messages in thread From: Enze Li @ 2025-09-26 3:23 UTC (permalink / raw) To: SeongJae Park; +Cc: akpm, damon, linux-mm, enze.li Hello SJ, On Mon, Sep 22 2025 at 06:01:32 AM -0700, SeongJae Park wrote: > Hello Enze, > > On Mon, 22 Sep 2025 18:10:20 +0800 Enze Li <lienze@kylinos.cn> wrote: > >> This patchset introduces a priority mechanism for DAMON's scheme >> application, allowing users to specify the relative importance of >> monitored processes. The changes ensure that higher-priority targets >> receive more frequent memory management operations while maintaining >> fairness across all monitored processes. > > Thank you for this patchset. > > There are features for monitoring target-based DAMOS filtering > (DAMOS_FILTER_TYPE_TARGET) and per-scheme applying time interval > (apply_interval_us). Couldn't those be used for your purpose? > Sorry for the delay. I've been testing it for the past few days. The combination of schemes and filters does indeed emulate a priority-like mechanism quite effectively. This is a fantastic feature! It's exactly what I needed for managing my workload's priorities. >> >> The first patch modifies kdamond_apply_schemes to implement >> priority-based scheduling, where targets are processed in proportion to >> their assigned priority values. For example, a target with priority 50 >> will be serviced 50 times for every 30 times a target with priority 30 >> is processed. >> >> The second patch adds a sysfs interface (priority under each target's >> directory) to dynamically configure these priorities at runtime. This >> enables fine-grained control over DAMON's behavior, making it more >> adaptable to performance-sensitive workloads. >> >> Together, these changes provide better flexibility for users who need >> differentiated memory management policies across different processes >> while maintaining backward compatibility with existing setups. >> >> You may want to verify this feature using the following testing >> procedure: >> >> # git clone -b v2 https://github.com/lienze/damo.git >> # cd damo >> # ./damo start --target_pid $(pidof <target1>) --priority 50 \ >> --target_pid $(pidof <target2>) --priority 30 --damos_action \ >> pageout --damos_age 5s 5s > > So I'm wondering a command like below could be used instead. > > $ sudo ./damo args damon \ > --target_pid 123 \ > --damos_action pageout --damos_age 5s 5s \ > --damos_filter allow target 0 --damos_apply_interval 3s \ > --target_pid 456 \ > --damos_action pageout --damos_age 5s 5s \ > --damos_filter allow target 1 --damos_apply_interval 5s \ > --damos_nr_filters 1 1 > > I've been wondering, though -- for users seeking a simpler interface, could we allow them to define a basic priority value and let the kernel handle the resource distribution automatically? This would require the DAMON system to intelligently translate a user-defined priority value into appropriate internal operations based on current system resources. WDYT? Best Regards, Enze <...> ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC PATCH 0/2] DAMON: add priority-based scheme application control 2025-09-26 3:23 ` Enze Li @ 2025-09-26 17:37 ` SeongJae Park 0 siblings, 0 replies; 8+ messages in thread From: SeongJae Park @ 2025-09-26 17:37 UTC (permalink / raw) To: Enze Li; +Cc: SeongJae Park, akpm, damon, linux-mm, enze.li On Fri, 26 Sep 2025 11:23:33 +0800 Enze Li <lienze@kylinos.cn> wrote: > Hello SJ, > > On Mon, Sep 22 2025 at 06:01:32 AM -0700, SeongJae Park wrote: > > > Hello Enze, > > > > On Mon, 22 Sep 2025 18:10:20 +0800 Enze Li <lienze@kylinos.cn> wrote: > > > >> This patchset introduces a priority mechanism for DAMON's scheme > >> application, allowing users to specify the relative importance of > >> monitored processes. The changes ensure that higher-priority targets > >> receive more frequent memory management operations while maintaining > >> fairness across all monitored processes. > > > > Thank you for this patchset. > > > > There are features for monitoring target-based DAMOS filtering > > (DAMOS_FILTER_TYPE_TARGET) and per-scheme applying time interval > > (apply_interval_us). Couldn't those be used for your purpose? > > > > Sorry for the delay. I've been testing it for the past few days. No worry, take your time! :) > > The combination of schemes and filters does indeed emulate a > priority-like mechanism quite effectively. This is a fantastic feature! > It's exactly what I needed for managing my workload's priorities. Thank you for letting me know it works for you! [...] > I've been wondering, though -- for users seeking a simpler interface, > could we allow them to define a basic priority value and let the kernel > handle the resource distribution automatically? This would require the > DAMON system to intelligently translate a user-defined priority value > into appropriate internal operations based on current system resources. > WDYT? I agree the priority based interface could be better and easier to use than the target filter + apply_interval combination, for some people. That said, the user interface for achieving the same goal already exists. I think adding another user interface here could be a duplicate that only increases maintenace burden. Particularly because we need to support every user interface of the kernel for long term, the burden may be not that cheap. And I think the kernel ABI is not necessarily the only single place that can be modified to help users. Users are recommended to use DAMON user-space tool (damo) rather than directly using DAMON sysfs ABI. So I think we could add priority based interface as another wrapper of the target filter + apply_interval combination, on DAMON user-space tool. Thanks, SJ [...] ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-09-26 17:37 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2025-09-22 10:10 [RFC PATCH 0/2] DAMON: add priority-based scheme application control Enze Li 2025-09-22 10:10 ` [RFC PATCH 1/2] mm/damon/core: introduce priority concept for DAMON Enze Li 2025-09-22 11:16 ` Gutierrez Asier 2025-09-26 3:57 ` Enze Li 2025-09-22 10:10 ` [RFC PATCH 2/2] mm/damon/sysfs: add priority support for DAMOS targets Enze Li 2025-09-22 13:01 ` [RFC PATCH 0/2] DAMON: add priority-based scheme application control SeongJae Park 2025-09-26 3:23 ` Enze Li 2025-09-26 17:37 ` SeongJae Park
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox