* [PATCH] mm/damon/core: eliminate hot-path integer division in damon_max_nr_accesses()
@ 2026-03-24 15:40 Josh Law
2026-03-25 1:16 ` (sashiko review) " SeongJae Park
2026-03-25 14:54 ` SeongJae Park
0 siblings, 2 replies; 6+ messages in thread
From: Josh Law @ 2026-03-24 15:40 UTC (permalink / raw)
To: sj, akpm; +Cc: damon, linux-mm, linux-kernel, Josh Law
Hardware integer division is slow. The function damon_max_nr_accesses(),
which is called very frequently, performs an integer division.
However, the struct damon_attrs already caches this exact ratio in the
internal field aggr_samples. We can eliminate the hardware division in
the hot path by simply returning aggr_samples.
Signed-off-by: Josh Law <objecting@objecting.org>
---
include/linux/damon.h | 3 +--
mm/damon/core.c | 1 +
mm/damon/tests/core-kunit.h | 16 ++++++++++++----
3 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/include/linux/damon.h b/include/linux/damon.h
index 6bd71546f7b2..438fe6f3eab4 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -960,8 +960,7 @@ static inline bool damon_target_has_pid(const struct damon_ctx *ctx)
static inline unsigned int damon_max_nr_accesses(const struct damon_attrs *attrs)
{
/* {aggr,sample}_interval are unsigned long, hence could overflow */
- return min(attrs->aggr_interval / attrs->sample_interval,
- (unsigned long)UINT_MAX);
+ return min_t(unsigned long, attrs->aggr_samples, UINT_MAX);
}
diff --git a/mm/damon/core.c b/mm/damon/core.c
index b0ab0ee6eab9..59b709f04975 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -582,6 +582,7 @@ struct damon_ctx *damon_new_ctx(void)
ctx->attrs.sample_interval = 5 * 1000;
ctx->attrs.aggr_interval = 100 * 1000;
ctx->attrs.ops_update_interval = 60 * 1000 * 1000;
+ ctx->attrs.aggr_samples = 20;
ctx->passed_sample_intervals = 0;
/* These will be set from kdamond_init_ctx() */
diff --git a/mm/damon/tests/core-kunit.h b/mm/damon/tests/core-kunit.h
index e86d4f4fe261..56d03ef6a5a4 100644
--- a/mm/damon/tests/core-kunit.h
+++ b/mm/damon/tests/core-kunit.h
@@ -416,6 +416,8 @@ static void damon_test_nr_accesses_to_accesses_bp(struct kunit *test)
.aggr_interval = ((unsigned long)UINT_MAX + 1) * 10
};
+ attrs.aggr_samples = attrs.aggr_interval / attrs.sample_interval;
+
/*
* In some cases such as 32bit architectures where UINT_MAX is
* ULONG_MAX, attrs.aggr_interval becomes zero. Calling
@@ -434,7 +436,8 @@ static void damon_test_nr_accesses_to_accesses_bp(struct kunit *test)
static void damon_test_update_monitoring_result(struct kunit *test)
{
struct damon_attrs old_attrs = {
- .sample_interval = 10, .aggr_interval = 1000,};
+ .sample_interval = 10, .aggr_interval = 1000,
+ .aggr_samples = 100,};
struct damon_attrs new_attrs;
struct damon_region *r = damon_new_region(3, 7);
@@ -446,19 +449,24 @@ static void damon_test_update_monitoring_result(struct kunit *test)
r->age = 20;
new_attrs = (struct damon_attrs){
- .sample_interval = 100, .aggr_interval = 10000,};
+ .sample_interval = 100, .aggr_interval = 10000,
+ .aggr_samples = 100,};
damon_update_monitoring_result(r, &old_attrs, &new_attrs, false);
KUNIT_EXPECT_EQ(test, r->nr_accesses, 15);
KUNIT_EXPECT_EQ(test, r->age, 2);
new_attrs = (struct damon_attrs){
- .sample_interval = 1, .aggr_interval = 1000};
+ .sample_interval = 1, .aggr_interval = 1000,
+ .aggr_samples = 1000,
+ };
damon_update_monitoring_result(r, &old_attrs, &new_attrs, false);
KUNIT_EXPECT_EQ(test, r->nr_accesses, 150);
KUNIT_EXPECT_EQ(test, r->age, 2);
new_attrs = (struct damon_attrs){
- .sample_interval = 1, .aggr_interval = 100};
+ .sample_interval = 1, .aggr_interval = 100,
+ .aggr_samples = 100,
+ };
damon_update_monitoring_result(r, &old_attrs, &new_attrs, false);
KUNIT_EXPECT_EQ(test, r->nr_accesses, 150);
KUNIT_EXPECT_EQ(test, r->age, 20);
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: (sashiko review) [PATCH] mm/damon/core: eliminate hot-path integer division in damon_max_nr_accesses()
2026-03-24 15:40 [PATCH] mm/damon/core: eliminate hot-path integer division in damon_max_nr_accesses() Josh Law
@ 2026-03-25 1:16 ` SeongJae Park
2026-03-25 7:36 ` Josh Law
2026-03-25 14:57 ` SeongJae Park
2026-03-25 14:54 ` SeongJae Park
1 sibling, 2 replies; 6+ messages in thread
From: SeongJae Park @ 2026-03-25 1:16 UTC (permalink / raw)
To: Josh Law; +Cc: SeongJae Park, akpm, damon, linux-mm, linux-kernel
Forwarding Sashiko review for doing discussions via mails.
# review url: https://sashiko.dev/#/patchset/20260324154005.83651-1-objecting@objecting.org
# start of sashiko.dev inline review
commit ff5e227a18cd69435749b0aae0dc2c762c4f0a47
Author: Josh Law <objecting@objecting.org>
mm/damon/core: eliminate hot-path integer division in damon_max_nr_accesses()
Hardware integer division is slow. The function damon_max_nr_accesses(),
which is called very frequently, performs an integer division.
However, the struct damon_attrs already caches this exact ratio in the
internal field aggr_samples. We can eliminate the hardware division in
the hot path by simply returning aggr_samples.
> diff --git a/include/linux/damon.h b/include/linux/damon.h
> index d9a3babbafc1..04c8a052fcfb 100644
> --- a/include/linux/damon.h
> +++ b/include/linux/damon.h
> @@ -978,8 +978,7 @@ static inline bool damon_target_has_pid(const struct damon_ctx *ctx)
> static inline unsigned int damon_max_nr_accesses(const struct damon_attrs *attrs)
> {
> /* {aggr,sample}_interval are unsigned long, hence could overflow */
> - return min(attrs->aggr_interval / attrs->sample_interval,
> - (unsigned long)UINT_MAX);
> + return min_t(unsigned long, attrs->aggr_samples, UINT_MAX);
> }
If an administrator dynamically updates aggr_interval via sysfs and commits
the inputs, will attrs->aggr_samples be correctly recalculated?
If aggr_samples becomes stale, kdamond_fn() will compute the real aggregation
loop count and allow r->nr_accesses to increment up to the new bounds (for
example, 80 loops). Meanwhile, damon_max_nr_accesses() will return the
stale aggr_samples cache (for example, 20).
When evaluating schemes, damon_hot_score() normalizes r->nr_accesses against
this stale maximum, producing a freq_subscore that severely exceeds
DAMON_MAX_SUBSCORE. This causes the calculated hotness to exceed
DAMOS_MAX_SCORE.
For DAMOS_PAGEOUT actions used by damon_reclaim, damon_cold_score() returns
DAMOS_MAX_SCORE - hotness, yielding a highly negative score.
Could this negative score cause an out-of-bounds write on the
kernel heap when used as an array index?
mm/damon/core.c:damos_walk() {
...
c->regions_score_histogram[score] += damon_sz_region(r);
...
}
> diff --git a/mm/damon/core.c b/mm/damon/core.c
> index db6c67e52d2b..afb058f7da5c 100644
> --- a/mm/damon/core.c
> +++ b/mm/damon/core.c
> @@ -587,6 +587,7 @@ struct damon_ctx *damon_new_ctx(void)
> ctx->attrs.sample_interval = 5 * 1000;
> ctx->attrs.aggr_interval = 100 * 1000;
> ctx->attrs.ops_update_interval = 60 * 1000 * 1000;
> + ctx->attrs.aggr_samples = 20;
Since this value is cached here, but not updated when intervals change, does
it remain permanently stale during dynamic updates?
# end of sashiko.dev inline review
# review url: https://sashiko.dev/#/patchset/20260324154005.83651-1-objecting@objecting.org
#
# hkml [1] generated a draft of this mail. It can be regenerated
# using below command:
#
# hkml patch sashiko_dev --for_forwarding \
# 20260324154005.83651-1-objecting@objecting.org
#
# [1] https://github.com/sjp38/hackermail
Sent using hkml (https://github.com/sjp38/hackermail)
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: (sashiko review) [PATCH] mm/damon/core: eliminate hot-path integer division in damon_max_nr_accesses()
2026-03-25 1:16 ` (sashiko review) " SeongJae Park
@ 2026-03-25 7:36 ` Josh Law
2026-03-25 14:43 ` SeongJae Park
2026-03-25 14:57 ` SeongJae Park
1 sibling, 1 reply; 6+ messages in thread
From: Josh Law @ 2026-03-25 7:36 UTC (permalink / raw)
To: SeongJae Park; +Cc: akpm, damon, linux-mm, linux-kernel
On 25 March 2026 01:16:52 GMT, SeongJae Park <sj@kernel.org> wrote:
>Forwarding Sashiko review for doing discussions via mails.
>
># review url: https://sashiko.dev/#/patchset/20260324154005.83651-1-objecting@objecting.org
># start of sashiko.dev inline review
>commit ff5e227a18cd69435749b0aae0dc2c762c4f0a47
>Author: Josh Law <objecting@objecting.org>
>
>mm/damon/core: eliminate hot-path integer division in damon_max_nr_accesses()
>
>Hardware integer division is slow. The function damon_max_nr_accesses(),
>which is called very frequently, performs an integer division.
>However, the struct damon_attrs already caches this exact ratio in the
>internal field aggr_samples. We can eliminate the hardware division in
>the hot path by simply returning aggr_samples.
>
>> diff --git a/include/linux/damon.h b/include/linux/damon.h
>> index d9a3babbafc1..04c8a052fcfb 100644
>> --- a/include/linux/damon.h
>> +++ b/include/linux/damon.h
>> @@ -978,8 +978,7 @@ static inline bool damon_target_has_pid(const struct damon_ctx *ctx)
>> static inline unsigned int damon_max_nr_accesses(const struct damon_attrs *attrs)
>> {
>> /* {aggr,sample}_interval are unsigned long, hence could overflow */
>> - return min(attrs->aggr_interval / attrs->sample_interval,
>> - (unsigned long)UINT_MAX);
>> + return min_t(unsigned long, attrs->aggr_samples, UINT_MAX);
>> }
>
>If an administrator dynamically updates aggr_interval via sysfs and commits
>the inputs, will attrs->aggr_samples be correctly recalculated?
>
>If aggr_samples becomes stale, kdamond_fn() will compute the real aggregation
>loop count and allow r->nr_accesses to increment up to the new bounds (for
>example, 80 loops). Meanwhile, damon_max_nr_accesses() will return the
>stale aggr_samples cache (for example, 20).
>
>When evaluating schemes, damon_hot_score() normalizes r->nr_accesses against
>this stale maximum, producing a freq_subscore that severely exceeds
>DAMON_MAX_SUBSCORE. This causes the calculated hotness to exceed
>DAMOS_MAX_SCORE.
>
>For DAMOS_PAGEOUT actions used by damon_reclaim, damon_cold_score() returns
>DAMOS_MAX_SCORE - hotness, yielding a highly negative score.
>
>Could this negative score cause an out-of-bounds write on the
>kernel heap when used as an array index?
>
>mm/damon/core.c:damos_walk() {
> ...
> c->regions_score_histogram[score] += damon_sz_region(r);
> ...
>}
>
>> diff --git a/mm/damon/core.c b/mm/damon/core.c
>> index db6c67e52d2b..afb058f7da5c 100644
>> --- a/mm/damon/core.c
>> +++ b/mm/damon/core.c
>> @@ -587,6 +587,7 @@ struct damon_ctx *damon_new_ctx(void)
>> ctx->attrs.sample_interval = 5 * 1000;
>> ctx->attrs.aggr_interval = 100 * 1000;
>> ctx->attrs.ops_update_interval = 60 * 1000 * 1000;
>> + ctx->attrs.aggr_samples = 20;
>
>Since this value is cached here, but not updated when intervals change, does
>it remain permanently stale during dynamic updates?
>
>
># end of sashiko.dev inline review
># review url: https://sashiko.dev/#/patchset/20260324154005.83651-1-objecting@objecting.org
>#
># hkml [1] generated a draft of this mail. It can be regenerated
># using below command:
>#
># hkml patch sashiko_dev --for_forwarding \
># 20260324154005.83651-1-objecting@objecting.org
>#
># [1] https://github.com/sjp38/hackermail
>
>Sent using hkml (https://github.com/sjp38/hackermail)
So it's nacked? Or is it just a review
V/R
Josh Law
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: (sashiko review) [PATCH] mm/damon/core: eliminate hot-path integer division in damon_max_nr_accesses()
2026-03-25 7:36 ` Josh Law
@ 2026-03-25 14:43 ` SeongJae Park
0 siblings, 0 replies; 6+ messages in thread
From: SeongJae Park @ 2026-03-25 14:43 UTC (permalink / raw)
To: Josh Law; +Cc: SeongJae Park, akpm, damon, linux-mm, linux-kernel
On Wed, 25 Mar 2026 07:36:20 +0000 Josh Law <objecting@objecting.org> wrote:
>
>
> On 25 March 2026 01:16:52 GMT, SeongJae Park <sj@kernel.org> wrote:
> >Forwarding Sashiko review for doing discussions via mails.
> >
> ># review url: https://sashiko.dev/#/patchset/20260324154005.83651-1-objecting@objecting.org
> ># start of sashiko.dev inline review
> >commit ff5e227a18cd69435749b0aae0dc2c762c4f0a47
> >Author: Josh Law <objecting@objecting.org>
> >
> >mm/damon/core: eliminate hot-path integer division in damon_max_nr_accesses()
> >
> >Hardware integer division is slow. The function damon_max_nr_accesses(),
> >which is called very frequently, performs an integer division.
> >However, the struct damon_attrs already caches this exact ratio in the
> >internal field aggr_samples. We can eliminate the hardware division in
> >the hot path by simply returning aggr_samples.
> >
> >> diff --git a/include/linux/damon.h b/include/linux/damon.h
> >> index d9a3babbafc1..04c8a052fcfb 100644
> >> --- a/include/linux/damon.h
> >> +++ b/include/linux/damon.h
> >> @@ -978,8 +978,7 @@ static inline bool damon_target_has_pid(const struct damon_ctx *ctx)
> >> static inline unsigned int damon_max_nr_accesses(const struct damon_attrs *attrs)
> >> {
> >> /* {aggr,sample}_interval are unsigned long, hence could overflow */
> >> - return min(attrs->aggr_interval / attrs->sample_interval,
> >> - (unsigned long)UINT_MAX);
> >> + return min_t(unsigned long, attrs->aggr_samples, UINT_MAX);
> >> }
> >
> >If an administrator dynamically updates aggr_interval via sysfs and commits
> >the inputs, will attrs->aggr_samples be correctly recalculated?
> >
> >If aggr_samples becomes stale, kdamond_fn() will compute the real aggregation
> >loop count and allow r->nr_accesses to increment up to the new bounds (for
> >example, 80 loops). Meanwhile, damon_max_nr_accesses() will return the
> >stale aggr_samples cache (for example, 20).
> >
> >When evaluating schemes, damon_hot_score() normalizes r->nr_accesses against
> >this stale maximum, producing a freq_subscore that severely exceeds
> >DAMON_MAX_SUBSCORE. This causes the calculated hotness to exceed
> >DAMOS_MAX_SCORE.
> >
> >For DAMOS_PAGEOUT actions used by damon_reclaim, damon_cold_score() returns
> >DAMOS_MAX_SCORE - hotness, yielding a highly negative score.
> >
> >Could this negative score cause an out-of-bounds write on the
> >kernel heap when used as an array index?
> >
> >mm/damon/core.c:damos_walk() {
> > ...
> > c->regions_score_histogram[score] += damon_sz_region(r);
> > ...
> >}
> >
> >> diff --git a/mm/damon/core.c b/mm/damon/core.c
> >> index db6c67e52d2b..afb058f7da5c 100644
> >> --- a/mm/damon/core.c
> >> +++ b/mm/damon/core.c
> >> @@ -587,6 +587,7 @@ struct damon_ctx *damon_new_ctx(void)
> >> ctx->attrs.sample_interval = 5 * 1000;
> >> ctx->attrs.aggr_interval = 100 * 1000;
> >> ctx->attrs.ops_update_interval = 60 * 1000 * 1000;
> >> + ctx->attrs.aggr_samples = 20;
> >
> >Since this value is cached here, but not updated when intervals change, does
> >it remain permanently stale during dynamic updates?
> >
> >
> ># end of sashiko.dev inline review
> ># review url: https://sashiko.dev/#/patchset/20260324154005.83651-1-objecting@objecting.org
> >#
> ># hkml [1] generated a draft of this mail. It can be regenerated
> ># using below command:
> >#
> ># hkml patch sashiko_dev --for_forwarding \
> ># 20260324154005.83651-1-objecting@objecting.org
> >#
> ># [1] https://github.com/sjp38/hackermail
> >
> >Sent using hkml (https://github.com/sjp38/hackermail)
>
>
>
> So it's nacked? Or is it just a review
Just a review from an AI :)
I treat sashiko review as just another review comments. I'm forwarding these
in this way for a case that someone is interested in the comments and want to
share some findings from those in a way easy for mailing list based
communication.
Thanks,
SJ
[...]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] mm/damon/core: eliminate hot-path integer division in damon_max_nr_accesses()
2026-03-24 15:40 [PATCH] mm/damon/core: eliminate hot-path integer division in damon_max_nr_accesses() Josh Law
2026-03-25 1:16 ` (sashiko review) " SeongJae Park
@ 2026-03-25 14:54 ` SeongJae Park
1 sibling, 0 replies; 6+ messages in thread
From: SeongJae Park @ 2026-03-25 14:54 UTC (permalink / raw)
To: Josh Law; +Cc: SeongJae Park, akpm, damon, linux-mm, linux-kernel
On Tue, 24 Mar 2026 15:40:05 +0000 Josh Law <objecting@objecting.org> wrote:
> Hardware integer division is slow. The function damon_max_nr_accesses(),
> which is called very frequently, performs an integer division.
> However, the struct damon_attrs already caches this exact ratio in the
> internal field aggr_samples. We can eliminate the hardware division in
> the hot path by simply returning aggr_samples.
>
> Signed-off-by: Josh Law <objecting@objecting.org>
> ---
> include/linux/damon.h | 3 +--
> mm/damon/core.c | 1 +
> mm/damon/tests/core-kunit.h | 16 ++++++++++++----
> 3 files changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/include/linux/damon.h b/include/linux/damon.h
> index 6bd71546f7b2..438fe6f3eab4 100644
> --- a/include/linux/damon.h
> +++ b/include/linux/damon.h
> @@ -960,8 +960,7 @@ static inline bool damon_target_has_pid(const struct damon_ctx *ctx)
> static inline unsigned int damon_max_nr_accesses(const struct damon_attrs *attrs)
> {
> /* {aggr,sample}_interval are unsigned long, hence could overflow */
> - return min(attrs->aggr_interval / attrs->sample_interval,
> - (unsigned long)UINT_MAX);
> + return min_t(unsigned long, attrs->aggr_samples, UINT_MAX);
> }
>
>
> diff --git a/mm/damon/core.c b/mm/damon/core.c
> index b0ab0ee6eab9..59b709f04975 100644
> --- a/mm/damon/core.c
> +++ b/mm/damon/core.c
> @@ -582,6 +582,7 @@ struct damon_ctx *damon_new_ctx(void)
> ctx->attrs.sample_interval = 5 * 1000;
> ctx->attrs.aggr_interval = 100 * 1000;
> ctx->attrs.ops_update_interval = 60 * 1000 * 1000;
> + ctx->attrs.aggr_samples = 20;
>
> ctx->passed_sample_intervals = 0;
> /* These will be set from kdamond_init_ctx() */
> diff --git a/mm/damon/tests/core-kunit.h b/mm/damon/tests/core-kunit.h
> index e86d4f4fe261..56d03ef6a5a4 100644
> --- a/mm/damon/tests/core-kunit.h
> +++ b/mm/damon/tests/core-kunit.h
> @@ -416,6 +416,8 @@ static void damon_test_nr_accesses_to_accesses_bp(struct kunit *test)
> .aggr_interval = ((unsigned long)UINT_MAX + 1) * 10
> };
>
> + attrs.aggr_samples = attrs.aggr_interval / attrs.sample_interval;
> +
> /*
> * In some cases such as 32bit architectures where UINT_MAX is
> * ULONG_MAX, attrs.aggr_interval becomes zero. Calling
> @@ -434,7 +436,8 @@ static void damon_test_nr_accesses_to_accesses_bp(struct kunit *test)
> static void damon_test_update_monitoring_result(struct kunit *test)
> {
> struct damon_attrs old_attrs = {
> - .sample_interval = 10, .aggr_interval = 1000,};
> + .sample_interval = 10, .aggr_interval = 1000,
> + .aggr_samples = 100,};
> struct damon_attrs new_attrs;
> struct damon_region *r = damon_new_region(3, 7);
>
> @@ -446,19 +449,24 @@ static void damon_test_update_monitoring_result(struct kunit *test)
> r->age = 20;
>
> new_attrs = (struct damon_attrs){
> - .sample_interval = 100, .aggr_interval = 10000,};
> + .sample_interval = 100, .aggr_interval = 10000,
> + .aggr_samples = 100,};
> damon_update_monitoring_result(r, &old_attrs, &new_attrs, false);
> KUNIT_EXPECT_EQ(test, r->nr_accesses, 15);
> KUNIT_EXPECT_EQ(test, r->age, 2);
>
> new_attrs = (struct damon_attrs){
> - .sample_interval = 1, .aggr_interval = 1000};
> + .sample_interval = 1, .aggr_interval = 1000,
> + .aggr_samples = 1000,
> + };
> damon_update_monitoring_result(r, &old_attrs, &new_attrs, false);
> KUNIT_EXPECT_EQ(test, r->nr_accesses, 150);
> KUNIT_EXPECT_EQ(test, r->age, 2);
>
> new_attrs = (struct damon_attrs){
> - .sample_interval = 1, .aggr_interval = 100};
> + .sample_interval = 1, .aggr_interval = 100,
> + .aggr_samples = 100,
> + };
> damon_update_monitoring_result(r, &old_attrs, &new_attrs, false);
> KUNIT_EXPECT_EQ(test, r->nr_accesses, 150);
> KUNIT_EXPECT_EQ(test, r->age, 20);
> --
> 2.34.1
I think this amount of change is somewhat too much maintenance burden for the
simple optimization. Apparently aggr_samples was not designed for this use
case. I think another way should be used, but failing at finding a good
alternative. And I'm not very sure damon_max_nr_accesses() deserves that much
time to optimize.
So, if you find a better way for optimizing damon_max_nr_accesses()
without adding maintenance burden or evidence of benefit that justifies this
amount of maintenance burden, please feel free to repost a new version. But,
in my humble and frank opinion, I don't see that much worth in the
optimization.
Thanks,
SJ
[...]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: (sashiko review) [PATCH] mm/damon/core: eliminate hot-path integer division in damon_max_nr_accesses()
2026-03-25 1:16 ` (sashiko review) " SeongJae Park
2026-03-25 7:36 ` Josh Law
@ 2026-03-25 14:57 ` SeongJae Park
1 sibling, 0 replies; 6+ messages in thread
From: SeongJae Park @ 2026-03-25 14:57 UTC (permalink / raw)
To: SeongJae Park; +Cc: Josh Law, akpm, damon, linux-mm, linux-kernel
On Tue, 24 Mar 2026 18:16:52 -0700 SeongJae Park <sj@kernel.org> wrote:
> Forwarding Sashiko review for doing discussions via mails.
>
> # review url: https://sashiko.dev/#/patchset/20260324154005.83651-1-objecting@objecting.org
> # start of sashiko.dev inline review
> commit ff5e227a18cd69435749b0aae0dc2c762c4f0a47
> Author: Josh Law <objecting@objecting.org>
>
> mm/damon/core: eliminate hot-path integer division in damon_max_nr_accesses()
>
> Hardware integer division is slow. The function damon_max_nr_accesses(),
> which is called very frequently, performs an integer division.
> However, the struct damon_attrs already caches this exact ratio in the
> internal field aggr_samples. We can eliminate the hardware division in
> the hot path by simply returning aggr_samples.
>
> > diff --git a/include/linux/damon.h b/include/linux/damon.h
> > index d9a3babbafc1..04c8a052fcfb 100644
> > --- a/include/linux/damon.h
> > +++ b/include/linux/damon.h
> > @@ -978,8 +978,7 @@ static inline bool damon_target_has_pid(const struct damon_ctx *ctx)
> > static inline unsigned int damon_max_nr_accesses(const struct damon_attrs *attrs)
> > {
> > /* {aggr,sample}_interval are unsigned long, hence could overflow */
> > - return min(attrs->aggr_interval / attrs->sample_interval,
> > - (unsigned long)UINT_MAX);
> > + return min_t(unsigned long, attrs->aggr_samples, UINT_MAX);
> > }
>
> If an administrator dynamically updates aggr_interval via sysfs and commits
> the inputs, will attrs->aggr_samples be correctly recalculated?
>
> If aggr_samples becomes stale, kdamond_fn() will compute the real aggregation
> loop count and allow r->nr_accesses to increment up to the new bounds (for
> example, 80 loops). Meanwhile, damon_max_nr_accesses() will return the
> stale aggr_samples cache (for example, 20).
>
> When evaluating schemes, damon_hot_score() normalizes r->nr_accesses against
> this stale maximum, producing a freq_subscore that severely exceeds
> DAMON_MAX_SUBSCORE. This causes the calculated hotness to exceed
> DAMOS_MAX_SCORE.
>
> For DAMOS_PAGEOUT actions used by damon_reclaim, damon_cold_score() returns
> DAMOS_MAX_SCORE - hotness, yielding a highly negative score.
>
> Could this negative score cause an out-of-bounds write on the
> kernel heap when used as an array index?
>
> mm/damon/core.c:damos_walk() {
> ...
> c->regions_score_histogram[score] += damon_sz_region(r);
> ...
> }
I didn't take deep look here, but sounds like true. I also had similar
concern.
But this takes too much time for the small optimization, so I suggested another
direction. So I will not take more time on this sashiko comment.
>
> > diff --git a/mm/damon/core.c b/mm/damon/core.c
> > index db6c67e52d2b..afb058f7da5c 100644
> > --- a/mm/damon/core.c
> > +++ b/mm/damon/core.c
> > @@ -587,6 +587,7 @@ struct damon_ctx *damon_new_ctx(void)
> > ctx->attrs.sample_interval = 5 * 1000;
> > ctx->attrs.aggr_interval = 100 * 1000;
> > ctx->attrs.ops_update_interval = 60 * 1000 * 1000;
> > + ctx->attrs.aggr_samples = 20;
>
> Since this value is cached here, but not updated when intervals change, does
> it remain permanently stale during dynamic updates?
Ditto.
Thanks,
SJ
[...]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-03-25 14:57 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-24 15:40 [PATCH] mm/damon/core: eliminate hot-path integer division in damon_max_nr_accesses() Josh Law
2026-03-25 1:16 ` (sashiko review) " SeongJae Park
2026-03-25 7:36 ` Josh Law
2026-03-25 14:43 ` SeongJae Park
2026-03-25 14:57 ` SeongJae Park
2026-03-25 14:54 ` SeongJae Park
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox