Skip to content

Commit 13d0599

Browse files
sjp38akpm00
authored andcommitted
mm/damon/lru_sort: fix quota status loss due to online tunings
For online parameters change, DAMON_LRU_SORT creates new schemes based on latest values of the parameters and replaces the old schemes with the new one. When creating it, the internal status of the quotas of the old schemes is not preserved. As a result, charging of the quota starts from zero after the online tuning. The data that collected to estimate the throughput of the scheme's action is also reset, and therefore the estimation should start from the scratch again. Because the throughput estimation is being used to convert the time quota to the effective size quota, this could result in temporal time quota inaccuracy. It would be recovered over time, though. In short, the quota accuracy could be temporarily degraded after online parameters update. Fix the problem by checking the case and copying the internal fields for the status. Link: https://lkml.kernel.org/r/20240216194025.9207-3-sj@kernel.org Fixes: 40e983c ("mm/damon: introduce DAMON-based LRU-lists Sorting") Signed-off-by: SeongJae Park <sj@kernel.org> Cc: <stable@vger.kernel.org> [6.0+] Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent 1b0ca4e commit 13d0599

File tree

1 file changed

+36
-7
lines changed

1 file changed

+36
-7
lines changed

mm/damon/lru_sort.c

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -185,28 +185,57 @@ static struct damos *damon_lru_sort_new_cold_scheme(unsigned int cold_thres)
185185
return damon_lru_sort_new_scheme(&pattern, DAMOS_LRU_DEPRIO);
186186
}
187187

188+
static void damon_lru_sort_copy_quota_status(struct damos_quota *dst,
189+
struct damos_quota *src)
190+
{
191+
dst->total_charged_sz = src->total_charged_sz;
192+
dst->total_charged_ns = src->total_charged_ns;
193+
dst->charged_sz = src->charged_sz;
194+
dst->charged_from = src->charged_from;
195+
dst->charge_target_from = src->charge_target_from;
196+
dst->charge_addr_from = src->charge_addr_from;
197+
}
198+
188199
static int damon_lru_sort_apply_parameters(void)
189200
{
190-
struct damos *scheme;
201+
struct damos *scheme, *hot_scheme, *cold_scheme;
202+
struct damos *old_hot_scheme = NULL, *old_cold_scheme = NULL;
191203
unsigned int hot_thres, cold_thres;
192204
int err = 0;
193205

194206
err = damon_set_attrs(ctx, &damon_lru_sort_mon_attrs);
195207
if (err)
196208
return err;
197209

210+
damon_for_each_scheme(scheme, ctx) {
211+
if (!old_hot_scheme) {
212+
old_hot_scheme = scheme;
213+
continue;
214+
}
215+
old_cold_scheme = scheme;
216+
}
217+
198218
hot_thres = damon_max_nr_accesses(&damon_lru_sort_mon_attrs) *
199219
hot_thres_access_freq / 1000;
200-
scheme = damon_lru_sort_new_hot_scheme(hot_thres);
201-
if (!scheme)
220+
hot_scheme = damon_lru_sort_new_hot_scheme(hot_thres);
221+
if (!hot_scheme)
202222
return -ENOMEM;
203-
damon_set_schemes(ctx, &scheme, 1);
223+
if (old_hot_scheme)
224+
damon_lru_sort_copy_quota_status(&hot_scheme->quota,
225+
&old_hot_scheme->quota);
204226

205227
cold_thres = cold_min_age / damon_lru_sort_mon_attrs.aggr_interval;
206-
scheme = damon_lru_sort_new_cold_scheme(cold_thres);
207-
if (!scheme)
228+
cold_scheme = damon_lru_sort_new_cold_scheme(cold_thres);
229+
if (!cold_scheme) {
230+
damon_destroy_scheme(hot_scheme);
208231
return -ENOMEM;
209-
damon_add_scheme(ctx, scheme);
232+
}
233+
if (old_cold_scheme)
234+
damon_lru_sort_copy_quota_status(&cold_scheme->quota,
235+
&old_cold_scheme->quota);
236+
237+
damon_set_schemes(ctx, &hot_scheme, 1);
238+
damon_add_scheme(ctx, cold_scheme);
210239

211240
return damon_set_region_biggest_system_ram_default(target,
212241
&monitor_region_start,

0 commit comments

Comments
 (0)