[PATCH 2/2] mm/damon: skip deactivated schemes in watermark checks and add fallback sleep
Liew Rui Yan <[email protected]>
| Newsgroups | dev.linux.lists.damon,org.kvack.linux-mm |
|---|---|
| Message-ID | <[email protected]> |
According to DAMOS design documentation, a scheme is deactivated when nr_snapshots reaches max_nr_snapshots. However, the previous kdamond_wait_activation() still checked the schemes which nr_snapshots reached max_nr_snapshots. This caused an issue - when all schemes were deactivated due to max_nr_snapshots, but their watermarks were still satisfied, damos_wmark_wait_us() would return 0, causing kdamond_wait_activation() to return 0 (activated). The main loop would then continue without sleeping, leading to unnecessary overhead since all schemes would be skipped in damon_do_apply_schemes(). To fix this: - Add a damos_is_deactivated() helper that checks both wmarks.activated and max_nr_snapshots conditions. - Replace the wmarks.activated-only checks with damos_is_deactivated() in both damon_do_apply_schemes() and kdamond_apply_schemes(). - In kdamond_wait_activation(), skip deactivated schemes when calculating the minimum wait time. - When no active schemes remain, sleep for sample_interval as a fallback (consistent with pause behavior) instead of returning 0. Signed-off-by: Liew Rui Yan <[email protected]> --- mm/damon/core.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/mm/damon/core.c b/mm/damon/core.c index 7230483e771f..57d1a21a8a0a 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -2633,6 +2633,17 @@ static void damos_apply_scheme(struct damon_ctx *c, struct damon_target *t, damos_update_stat(s, sz, sz_applied, sz_ops_filter_passed); } +static bool damos_is_deactivated(struct damos *s) +{ + if (!s->wmarks.activated) + return true; + if (s->max_nr_snapshots && + s->max_nr_snapshots <= s->stat.nr_snapshots) + return true; + + return false; +} + static void damon_do_apply_schemes(struct damon_ctx *c, struct damon_target *t, struct damon_region *r) @@ -2645,7 +2656,7 @@ static void damon_do_apply_schemes(struct damon_ctx *c, if (time_before(c->passed_sample_intervals, s->next_apply_sis)) continue; - if (!s->wmarks.activated) + if (damos_is_deactivated(s)) continue; /* Check the quota */ @@ -2655,10 +2666,6 @@ static void damon_do_apply_schemes(struct damon_ctx *c, if (damos_skip_charged_region(t, r, s, c->min_region_sz)) continue; - if (s->max_nr_snapshots && - s->max_nr_snapshots <= s->stat.nr_snapshots) - continue; - if (damos_valid_target(c, r, s)) damos_apply_scheme(c, t, r, s); @@ -3220,7 +3227,7 @@ static void kdamond_apply_schemes(struct damon_ctx *c) if (time_before(c->passed_sample_intervals, s->next_apply_sis)) continue; - if (!s->wmarks.activated) + if (damos_is_deactivated(s)) continue; has_schemes_to_apply = true; @@ -3704,16 +3711,23 @@ static int kdamond_wait_activation(struct damon_ctx *ctx) while (!kdamond_need_stop(ctx)) { damon_for_each_scheme(s, ctx) { + if (s->max_nr_snapshots && + s->max_nr_snapshots <= s->stat.nr_snapshots) + continue; + wait_time = damos_wmark_wait_us(s); if (!init_wait_time || wait_time < min_wait_time) { init_wait_time = true; min_wait_time = wait_time; } } - if (!min_wait_time) + if (!min_wait_time && init_wait_time) return 0; - kdamond_usleep(min_wait_time); + if (min_wait_time) + kdamond_usleep(min_wait_time); + else + kdamond_usleep(ctx->attrs.sample_interval); kdamond_call(ctx, false); if (ctx->maybe_corrupted) -- 2.55.0