mm/damon: improve/fixup/update ratio calculation, test and documentation
Subsystems (5)
SeongJae Park
maintainercover mm/damon: improve/fixup/update ratio calculation, test and documentation
Yet another batch of misc/minor improvements and fixups. Use mult_frac() instead of the worse open-coding for rate calculations (patch 1). Add a test for a previously found and fixed bug (patch 2). Improve and update comments and documentations for easier code review and up-to-date information (patches 3-6). Finally, fix an obvious typo (patch 7).
SeongJae Park (7):
mm/damon/core: use mult_frac() mm/damon/tests/core-kunit: add a test for damon_is_last_region() mm/damon/core: clarify damon_set_attrs() usages mm/damon: document non-zero length damon_region assumption Docs/admin-guide/mm/damn/lru_sort: fix intervals autotune parameter
name
Docs/mm/damon/maintainer-profile: use flexible review cadence Docs/mm/damon/index: fix typo: autoamted -> automated
.../admin-guide/mm/damon/lru_sort.rst | 4 +-- Documentation/mm/damon/index.rst | 2 +- Documentation/mm/damon/maintainer-profile.rst | 8 ++--- include/linux/damon.h | 2 ++ mm/damon/core.c | 32 ++++++++++++------- mm/damon/tests/core-kunit.h | 23 +++++++++++++ 6 files changed, 52 insertions(+), 19 deletions(-)
base-commit: fa1e30b2dede645519bf6743439d3925922651bc
Signature · 1 line
2.47.3
SeongJae Park
maintainerPATCH 1/7 mm/damon/core: use mult_frac()
There are multiple places in core code that do open-code rate calculations. Use mult_frac(), which is developed for doing that in a way more safe from overflow and precision loss.
--- mm/damon/core.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
mm/damon/core.c +10 -10
@@ -665,7 +665,7 @@ static unsigned int damon_accesses_bp_to_nr_accesses(static unsigned int damon_nr_accesses_to_accesses_bp (unsigned int nr_accesses,struct damon_attrs *attrs) { -return nr_accesses *10000 /damon_max_nr_accesses (attrs); +return mult_frac (nr_accesses,10000 ,damon_max_nr_accesses (attrs)); } static unsigned int damon_nr_accesses_for_new_attrs(unsigned int nr_accesses,
@@ -1722,7 +1722,7 @@ static unsigned long damon_get_intervals_score(struct damon_ctx *c) } target_access_events = max_access_events * goal_bp /10000 ; target_access_events = target_access_events ? :1 ; -return access_events *10000 / target_access_events; +return mult_frac (access_events,10000 , target_access_events); } static unsigned long damon_feed_loop_next_input(unsigned long last_input,
@@ -2202,7 +2202,7 @@ static __kernel_ulong_t damos_get_node_mem_bp( numerator = i.totalram - i.freeram; else /* DAMOS_QUOTA_NODE_MEM_FREE_BP */ numerator = i.freeram; -return numerator *10000 / i.totalram; +return mult_frac (numerator,10000 , i.totalram); } static unsigned long damos_get_node_memcg_used_bp(
@@ -2235,7 +2235,7 @@ static unsigned long damos_get_node_memcg_used_bp( numerator = used_pages; else /* DAMOS_QUOTA_NODE_MEMCG_FREE_BP */ numerator = i.totalram - used_pages; -return numerator *10000 / i.totalram; +return mult_frac (numerator,10000 , i.totalram); }#else static __kernel_ulong_t damos_get_node_mem_bp(
@@ -2265,8 +2265,8 @@ static unsigned int damos_get_in_active_mem_bp(bool active_ratio)global_node_page_state (NR_LRU_BASE +LRU_INACTIVE_FILE ); total = active + inactive;if (active_ratio) -return active *10000 / total; -return inactive *10000 / total; +return mult_frac (active,10000 , total); +return mult_frac (inactive,10000 , total); }static void damos_set_quota_goal_current_value (struct damos_quota_goal *goal)
@@ -2309,8 +2309,8 @@ static unsigned long damos_quota_score(struct damos_quota *quota)damos_for_each_quota_goal (goal, quota) {damos_set_quota_goal_current_value (goal); highest_score =max (highest_score, - goal->current_value *10000 / - goal->target_value); +mult_frac (goal->current_value,10000 , + goal->target_value)); }return highest_score;
@@ -2340,8 +2340,8 @@ static void damos_set_effective_quota(struct damos_quota *quota)if (quota->ms) {if (quota->total_charged_ns) - throughput =mult_frac (quota->total_charged_sz,1000000 , - quota->total_charged_ns); + throughput =mult_frac (quota->total_charged_sz, +1000000 , quota->total_charged_ns);else throughput =PAGE_SIZE *1024 ; esz =min (throughput * quota->ms, esz);
Signature · 1 line
2.47.3
SeongJae Park
maintainerPATCH 2/7 mm/damon/tests/core-kunit: add a test for damon_is_last_region()
In reply to SeongJae ParkThere was a bug [1] in damon_is_last_region(). Add a kunit test to not reintroduce the bug.
[1] https://lore.kernel.org/[email protected]/
--- mm/damon/tests/core-kunit.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
mm/damon/tests/core-kunit.h +23 -0
@@ -1311,6 +1311,28 @@ static void damon_test_apply_min_nr_regions(struct kunit *test)damon_test_apply_min_nr_regions_for (test,10 ,2 ,10 ,2 ,5 ); } +static void damon_test_is_last_region (struct kunit *test) +{ +struct damon_region *r; +struct damon_target *t; +int i; + + t =damon_new_target (); +if (!t) +kunit_skip (test,"target alloc fail\n" ); + +for (i =0 ; i <4 ; i++) { + r =damon_new_region (i *2 , (i +1 ) *2 ); +if (!r) { +damon_free_target (t); +kunit_skip (test,"region alloc %d fail\n" , i); + } +damon_add_region (r, t); +KUNIT_EXPECT_TRUE (test,damon_is_last_region (r, t)); + } +damon_free_target (t); +} +static struct kunit_case damon_test_cases[] = {KUNIT_CASE (damon_test_target),KUNIT_CASE (damon_test_regions),
@@ -1339,6 +1361,7 @@ static struct kunit_case damon_test_cases[] = {KUNIT_CASE (damon_test_feed_loop_next_input),KUNIT_CASE (damon_test_set_filters_default_reject),KUNIT_CASE (damon_test_apply_min_nr_regions), + KUNIT_CASE(damon_test_is_last_region), {}, };
Signature · 1 line
2.47.3
Re: [PATCH 2/7] mm/damon/tests/core-kunit: add a test for damon_is_last_region()
Quoted 6 lines
There was a bug [1] in
damon_is_last_region(). Add a kunit test to not reintroduce the bug.[1] https://lore.kernel.org/[email protected]/
Signed-off-by SeongJae Park <[email protected]>
Hi SeongJae,
I've been following the previous discussion regarding the bug in damon_is_last_region() where the arguments of list_is_last() were accidentally swapped.
I have verified this patch by running the KUnit tests on my arm64 native environment. The damon_test_is_last_region test case passed as expected, confirming that the fix is robust and the regression is effectively prevented.
--
Best Regards,
wang lian
SeongJae Park
maintainerPATCH 3/7 mm/damon/core: clarify damon_set_attrs() usages
In reply to SeongJae Parkdamon_set_attrs() is called for multiple purposes from multiple places. Calling it in an unsafe context can make DAMON internal state polluted and results in unexpected behaviors. Clarify when it is safe, and where it is being called.
--- mm/damon/core.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
mm/damon/core.c +10 -2
@@ -751,8 +751,16 @@ static bool damon_valid_intervals_goal(struct damon_attrs *attrs)* @ctx: monitoring context * @attrs: monitoring attributes * -* This function should be called while the kdamond is not running, an access -* check results aggregation is not ongoing (e.g., from damon_call(). +* This function updates monitoring results and next monitoring/damos operation +* schedules. Because those are periodically updated by kdamond, this should +* be called from a safe contexts. Such contexts include damon_ctx setup time +* while the kdamond is not yet started, and inside of kdamond_fn(). +* +* In detail, all DAMON API callers directly call this function for initial +* setup of damon_ctx before calling damon_start(). Some of the API callers +* also indirectly call this function via damon_call() -> damon_commit() for +* online parameters updates. Finally, kdamond_fn() itself use this for +* applying auto-tuned monitoring intervals. * * Every time interval is in micro-seconds. *
Signature · 1 line
2.47.3
SeongJae Park
maintainerPATCH 4/7 mm/damon: document non-zero length damon_region assumption
In reply to SeongJae ParkDAMON regions are assumed to always be non-zero length. There was a confusion [1] about it, probably due to lack of the documentation. Document it.
[1] https://lore.kernel.org/[email protected]/
--- include/linux/damon.h | 2 ++ 1 file changed, 2 insertions(+)
include/linux/damon.h +2 -0
@@ -55,6 +55,8 @@ struct damon_size_range {* @list: List head for siblings. * @age: Age of this region. * +* For any use case, @ar should be non-zero positive size. +* * @nr_accesses is reset to zero for every &damon_attrs->aggr_interval and be * increased for every &damon_attrs->sample_interval if an access to the region * during the last sampling interval is found. The update of this field should
Signature · 1 line
2.47.3
SeongJae Park
maintainerPATCH 5/7 Docs/admin-guide/mm/damn/lru_sort: fix intervals autotune parameter name
In reply to SeongJae ParkThe section name should be the same as the parameter name. Fix it.
--- Documentation/admin-guide/mm/damon/lru_sort.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Documentation/admin-guide/mm/damon/lru_sort.rst +2 -2
@@ -91,8 +91,8 @@ increases and decreases the effective level of the quota aiming the LRU Disabled by default. -Auto-tune monitoring intervals ------------------------------- +autotune_monitoring_intervals +----------------------------- If this parameter is set as ``Y``, DAMON_LRU_SORT automatically tunes DAMON's sampling and aggregation intervals. The auto-tuning aims to capture meaningful
Signature · 1 line
2.47.3
SeongJae Park
maintainerPATCH 6/7 Docs/mm/damon/maintainer-profile: use flexible review cadence
In reply to SeongJae ParkThe document mentions the maitainer is working in the usual 9-5 fashion. The maintainer nowadays prefers working in a more flexible way. Update the document to avoid contributors having a wrong time expectation.
--- Documentation/mm/damon/maintainer-profile.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
Documentation/mm/damon/maintainer-profile.rst +4 -4
@@ -63,10 +63,10 @@ management subsystem maintainer. Review cadence -------------- -The DAMON maintainer does the work on the usual work hour (09:00 to 17:00, -Mon-Fri) in PT (Pacific Time). The response to patches will occasionally be -slow. Do not hesitate to send a ping if you have not heard back within a week -of sending a patch. +The DAMON maintainer usually work in a flexible way, except early morning in PT +(Pacific Time). The response to patches will occasionally be slow. Do not +hesitate to send a ping if you have not heard back within a week of sending a +patch. Mailing tool ------------
Signature · 1 line
2.47.3
SeongJae Park
maintainerPATCH 7/7 Docs/mm/damon/index: fix typo: autoamted -> automated
In reply to SeongJae ParkThere is an obvious typo. Fix it (s/autoamted/automated/).
--- Documentation/mm/damon/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/mm/damon/index.rst +1 -1
@@ -12,7 +12,7 @@ DAMON is a Linux kernel subsystem for efficient :ref:`data access monitoring - *light-weight* (for production online usages), - *scalable* (in terms of memory size), - *tunable* (for flexible usages), and - - *autoamted* (for production operation without manual tunings). + - *automated* (for production operation without manual tunings). .. toctree:: :maxdepth: 2
Signature · 1 line
2.47.3
Quoted 6 lines
Yet another batch of misc/minor improvements and fixups. Use
mult_frac()instead of the worse open-coding for rate calculations (patch 1). Add a test for a previously found and fixed bug (patch 2). Improve and update comments and documentations for easier code review and up-to-date information (patches 3-6). Finally, fix an obvious typo (patch 7).
Hi SeongJae,
Thanks for the patches and the CC!
I've reviewed the entire series and conducted functional testing on my arm64 environment (native VM). All 28 KUnit tests passed successfully, including
the newly added damon_test_is_last_region.
--
Best Regards,
wang lian