Another candidate of the subject was "Let users feed and tame DAMOS".
DAMOS Control Difficulty ========================
DAMOS helps users easily implementing effective access pattern aware system operations. However, controlling DAMOS in wild is not that easy. The basic way to control DAMON is specifying the target access pattern. Hence, the user is assumed to know the access pattern of the system and the workloads well. Though some good tools including DAMON can help that, it requires time and resource, and the cost depends on the complexity and the dynamicity of the system and workloads. After all, the access pattern consist of three ranges, namely ranges of access rate, age, and size of the regions. Tuning six parameters is already complex. It is not doable for everyone.
To ease the control, DAMOS allows users to set the upper-limit of the schemes's aggressiveness, namely DAMOS quota. Then DAMOS prioritizes regions to apply the action under the limit based on the action and the access pattern of the regions. For example, use can ask DAMOS to page out up to 100 MiB of memory regions per second. Then DAMOS pages out regions that not accessed for longer time first under the limit. This allows users to set access pattern bit more naively, and focus on only the one parameter, the quota. That is, the number of parameters to tune with special care can be reduced from six to one.
Still, however, the optimal value for the quota depends on the system and the workloads' characteristics, so not that simple. The number of parameters to tune can also increase again if the user needs to run multiple schemes, e.g., collapsing hot pages into THP while splitting cold pages into regular pages.
In short, the existing approach asks users to find the perfect or adapted tuning and instruct DAMOS how to work. It requires users to be deligent. That's not a virtue of human, but the machine.
Aim-oriented Feedback-driven DAMOS Quota Auto Tuning ====================================================
Most users would start using DAMOS since there is something they want to achieve with DAMOS. Having such goal metrics like SLO is common. Hence, a better approach would be letting users inform DAMOS what they aim to achieve, and how well DAMOS is doing that. Then DAMOS can somehow make it. In detail, users provide feedback for each DAMOS scheme. DAMOS then tune the quota of each scheme based on the users' feedback and the current quota values.
This patchset implements the idea.
Implementation --------------
The core logic implementation is in the first patch. In short, it uses below simple feedback loop algorithm to get next aggressiveness from the current aggressiveness and the feedback (target_core and current_score) for the current aggressiveness.
f(n, target_score, current_score) = max(f(n - 1) * ((target_score - current_score) / target_score + 1), 1)
Note that this algorithm assumes the aggressiveness and the score are positively proportional. Making it true is the feedback provider's responsibility.
Test Results ------------
To show if this provides the expected benefit, we extend the performance tests of damon-tests suite to support virtual address space-based proactive reclamation scheme that aims 0.5% last 10 seconds some memory PSI. The test suite runs PARSEC3 and SPLASH-2X workloads with the scheme and measure the runtime, the RSS, and the PSI for memory (some). We do same with the same scheme but not having the goal, and yet another variant of it that the target access patterns of the scheme is tuned for each workload, in a offline-tuning approach named DAMOOS[1].
The results that normalized to the output that made without any scheme are as below. The PSI for original run (without any scheme) was zero. To avoid divide-by-zero, we normalize the value to that of Not-tuned scheme's result.
xx Not-tuned Offline-tuned Online-tuned RSS 0.622688178226118 0.787950678944904 0.740093483278979 runtime 1.11767826657912 1.0564674983585 1.0910833880499 PSI 1 0.727521443794069 0.308498846350299
The not-tuned scheme acheives about 38.7% memory saving but incur about 11.7% runtime slowdown. The offline-tuned scheme achieves about 22.2% memory saving with about 5.5% runtiem slowdown. It also achieves about 28.2% PSI saving. The online-tuned scheme achieves about 26% memory saving with about 9.1% runtime slowdown. It also achieves about 69.1% PSI saving. Given the online-tuned version is using this RFC level implementation and the goal (0.5% last-10 secs memory PSI) was made after only a few experiments within a day, I think this results show some potential of this feedback-driven auto tuning approach.
The test code is available[2], so you can reproduce on your system.
[1] https://www.amazon.science/publications/daos-data-access-aware-operating-sys... [2] https://github.com/damonitor/damon-tests/commit/3f884e61193f0166b8724554b6d0...
Patches Sequence ================
The first four patches implement the core logic and user interfaces for the auto tuning. The first patch implements the core logic for the auto tuning, and the API for DAMOS users in the kernel space. The second patch implements basic file operations of DAMON sysfs directories and files that will be used for setting the goals and providing the feedback. The third patch connects the quota goals files inputs to the DAMOS core logic. Finally the fourth patch implements a dedicated DAMOS sysfs command for efficiently committing the quota goals feedback.
Two patches for simple test of the logic and interfaces follow. The fifth patch implements the core logic unit test. The sixth patch implements a selftest for the DAMON Sysfs interface for the goals.
Finally, two patches for documentation follows. The seventh patch documents the design of the feature. The final eighth patch updates the usage document for the features.
SeongJae Park (8): mm/damon/core: implement goal-oriented feedback-driven quota auto-tuning mm/damon/sysfs-schemes: implement scheme quota goals directory mm/damon/sysfs-schemes: commit damos quota goals user input to DAMOS quota auto-tuning mm/damon/sysfs-schemes: implement a command for scheme quota goals only commit mm/damon/core-test: add a unit test for the feedback loop algorithm selftests/damon: test quota goals directory Docs/mm/damon/design: Document DAMOS quota auto tuning Docs/admin-guide/mm/damon/usage: update for quota goals
Documentation/admin-guide/mm/damon/usage.rst | 25 +- Documentation/mm/damon/design.rst | 11 + include/linux/damon.h | 19 ++ mm/damon/core-test.h | 32 +++ mm/damon/core.c | 65 ++++- mm/damon/sysfs-common.h | 3 + mm/damon/sysfs-schemes.c | 272 ++++++++++++++++++- mm/damon/sysfs.c | 27 ++ tools/testing/selftests/damon/sysfs.sh | 27 ++ 9 files changed, 463 insertions(+), 18 deletions(-)
base-commit: 4f26b84c39fbc6b03208674681bfde06e0bce25a
Implement a simple kunit test for testing the behavior of the core logic of the goal-oriented feedback-driven DAMOS quota auto-tuning.
Signed-off-by: SeongJae Park sj@kernel.org --- mm/damon/core-test.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
diff --git a/mm/damon/core-test.h b/mm/damon/core-test.h index f405d79dc623..c2b8cb25a195 100644 --- a/mm/damon/core-test.h +++ b/mm/damon/core-test.h @@ -447,6 +447,37 @@ static void damos_test_filter_out(struct kunit *test) damos_free_filter(f); }
+static void damon_test_feed_loop_next_input(struct kunit *test) +{ + unsigned long last_input = 900000, current_score = 200; + + /* + * If current score is lower than the goal, which is always 10,000 + * (read the comment on damon_feed_loop_next_input()'s comment), next + * input should be higher than the last input. + */ + KUNIT_EXPECT_GT(test, + damon_feed_loop_next_input(last_input, current_score), + last_input); + + /* + * If current score is higher than the goal, next input should be lower + * than the last input. + */ + current_score = 250000000; + KUNIT_EXPECT_LT(test, + damon_feed_loop_next_input(last_input, current_score), + last_input); + + /* + * The next input depends on the distance between the current score and + * the goal + */ + KUNIT_EXPECT_GT(test, + damon_feed_loop_next_input(last_input, 200), + damon_feed_loop_next_input(last_input, 2000)); +} + static struct kunit_case damon_test_cases[] = { KUNIT_CASE(damon_test_target), KUNIT_CASE(damon_test_regions), @@ -463,6 +494,7 @@ static struct kunit_case damon_test_cases[] = { KUNIT_CASE(damon_test_moving_sum), KUNIT_CASE(damos_test_new_filter), KUNIT_CASE(damos_test_filter_out), + KUNIT_CASE(damon_test_feed_loop_next_input), {}, };
Add DAMON selftests for testing creation/existence of quota goals directories and files, and simple valid input writes.
Signed-off-by: SeongJae Park sj@kernel.org --- tools/testing/selftests/damon/sysfs.sh | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/tools/testing/selftests/damon/sysfs.sh b/tools/testing/selftests/damon/sysfs.sh index 56f0230a8b92..e9a976d296e2 100755 --- a/tools/testing/selftests/damon/sysfs.sh +++ b/tools/testing/selftests/damon/sysfs.sh @@ -150,6 +150,32 @@ test_weights() ensure_file "$weights_dir/age_permil" "exist" "600" }
+test_goal() +{ + goal_dir=$1 + ensure_dir "$goal_dir" "exist" + ensure_file "$goal_dir/target_value" "exist" "600" + ensure_file "$goal_dir/current_value" "exist" "600" +} + +test_goals() +{ + goals_dir=$1 + ensure_dir "$goals_dir" "exist" + ensure_file "$goals_dir/nr_goals" "exist" "600" + + ensure_write_succ "$goals_dir/nr_goals" "1" "valid input" + test_goal "$goals_dir/0" + + ensure_write_succ "$goals_dir/nr_goals" "2" "valid input" + test_goal "$goals_dir/0" + test_goal "$goals_dir/1" + + ensure_write_succ "$goals_dir/nr_goals" "0" "valid input" + ensure_dir "$goals_dir/0" "not_exist" + ensure_dir "$goals_dir/1" "not_exist" +} + test_quotas() { quotas_dir=$1 @@ -158,6 +184,7 @@ test_quotas() ensure_file "$quotas_dir/bytes" "exist" 600 ensure_file "$quotas_dir/reset_interval_ms" "exist" 600 test_weights "$quotas_dir/weights" + test_goals "$quotas_dir/goals" }
test_access_pattern()
linux-kselftest-mirror@lists.linaro.org