Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm/damon/core: do non-safe region walk on kdamond_apply_schemes()

kdamond_apply_schemes() is using damon_for_each_region_safe(), which is
safe for deallocation of the region inside the loop. However, the loop
internal logic does not deallocate regions. Hence it is only wasting the
next pointer. Also, it causes a problem.

When an address filter is applied, and there is a region that intersects
with the filter, the filter splits the region on the filter boundary. The
intention is to let DAMOS apply action to only filtered-in address ranges.
However, it is using damon_for_each_region_safe(), which sets the next
region before the execution of the iteration. Hence, the region that
split and now will be next to the previous region, is simply ignored. As
a result, DAMOS applies the action to target regions bit slower than
expected, when the address filter is used. Shouldn't be a big problem but
definitely better to be fixed. damos_skip_charged_region() was working
around the issue using a double pointer hack.

Use damon_for_each_region(), which is safe for this use case. And drop
the work around in damos_skip_charged_region().

Link: https://lkml.kernel.org/r/20260227170623.95384-3-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

SeongJae Park and committed by
Andrew Morton
1745ccbd e7e1a26b

+11 -11
+11 -11
mm/damon/core.c
··· 1717 1717 * This function checks if a given region should be skipped or not for the 1718 1718 * reason. If only the starting part of the region has previously charged, 1719 1719 * this function splits the region into two so that the second one covers the 1720 - * area that not charged in the previous charge widnow and saves the second 1721 - * region in *rp and returns false, so that the caller can apply DAMON action 1722 - * to the second one. 1720 + * area that not charged in the previous charge widnow, and return true. The 1721 + * caller can see the second one on the next iteration of the region walk. 1722 + * Note that this means the caller should use damon_for_each_region() instead 1723 + * of damon_for_each_region_safe(). If damon_for_each_region_safe() is used, 1724 + * the second region will just be ignored. 1723 1725 * 1724 - * Return: true if the region should be entirely skipped, false otherwise. 1726 + * Return: true if the region should be skipped, false otherwise. 1725 1727 */ 1726 1728 static bool damos_skip_charged_region(struct damon_target *t, 1727 - struct damon_region **rp, struct damos *s, 1729 + struct damon_region *r, struct damos *s, 1728 1730 unsigned long min_region_sz) 1729 1731 { 1730 - struct damon_region *r = *rp; 1731 1732 struct damos_quota *quota = &s->quota; 1732 1733 unsigned long sz_to_skip; 1733 1734 ··· 1755 1754 sz_to_skip = min_region_sz; 1756 1755 } 1757 1756 damon_split_region_at(t, r, sz_to_skip); 1758 - r = damon_next_region(r); 1759 - *rp = r; 1757 + return true; 1760 1758 } 1761 1759 quota->charge_target_from = NULL; 1762 1760 quota->charge_addr_from = 0; ··· 2014 2014 if (quota->esz && quota->charged_sz >= quota->esz) 2015 2015 continue; 2016 2016 2017 - if (damos_skip_charged_region(t, &r, s, c->min_region_sz)) 2017 + if (damos_skip_charged_region(t, r, s, c->min_region_sz)) 2018 2018 continue; 2019 2019 2020 2020 if (s->max_nr_snapshots && ··· 2357 2357 static void kdamond_apply_schemes(struct damon_ctx *c) 2358 2358 { 2359 2359 struct damon_target *t; 2360 - struct damon_region *r, *next_r; 2360 + struct damon_region *r; 2361 2361 struct damos *s; 2362 2362 unsigned long sample_interval = c->attrs.sample_interval ? 2363 2363 c->attrs.sample_interval : 1; ··· 2383 2383 if (c->ops.target_valid && c->ops.target_valid(t) == false) 2384 2384 continue; 2385 2385 2386 - damon_for_each_region_safe(r, next_r, t) 2386 + damon_for_each_region(r, t) 2387 2387 damon_do_apply_schemes(c, t, r); 2388 2388 } 2389 2389