summaryrefslogtreecommitdiff
path: root/mm/damon/sysfs-schemes.c
diff options
context:
space:
mode:
authorSeongJae Park <sj@kernel.org>2025-01-03 09:43:59 -0800
committerAndrew Morton <akpm@linux-foundation.org>2025-01-25 20:22:26 -0800
commit66178e4ec30a67777f3795dc59a891b106cdb4db (patch)
treecd611c56aea19974b76fd28e4bcba8872b600893 /mm/damon/sysfs-schemes.c
parentcce0b334c3108b49b0d550c387cde949b6788f22 (diff)
mm/damon/sysfs: use damos_walk() for update_schemes_tried_{bytes,regions}
DAMON sysfs interface uses damon_callback with its own complicated synchronization facility to handle update_schemes_tried_bytes and update_schemes_tried_regions commands. But damos_walk() can support the use case without the additional synchronizations. Convert the code to use damos_walk() instead. Link: https://lkml.kernel.org/r/20250103174400.54890-10-sj@kernel.org Signed-off-by: SeongJae Park <sj@kernel.org> Cc: Jonathan Corbet <corbet@lwn.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'mm/damon/sysfs-schemes.c')
-rw-r--r--mm/damon/sysfs-schemes.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c
index c57ab47686ff..1d8ad637051a 100644
--- a/mm/damon/sysfs-schemes.c
+++ b/mm/damon/sysfs-schemes.c
@@ -2183,6 +2183,54 @@ static int damon_sysfs_before_damos_apply(struct damon_ctx *ctx,
return 0;
}
+/**
+ * damos_sysfs_populate_region_dir() - Populate a schemes tried region dir.
+ * @sysfs_schemes: Schemes directory to populate regions directory.
+ * @ctx: Corresponding DAMON context.
+ * @t: DAMON target of @r.
+ * @r: DAMON region to populate the directory for.
+ * @s: Corresponding scheme.
+ * @total_bytes_only: Whether the request is for bytes update only.
+ *
+ * Called from DAMOS walk callback while holding damon_sysfs_lock.
+ */
+void damos_sysfs_populate_region_dir(struct damon_sysfs_schemes *sysfs_schemes,
+ struct damon_ctx *ctx, struct damon_target *t,
+ struct damon_region *r, struct damos *s, bool total_bytes_only)
+{
+ struct damos *scheme;
+ struct damon_sysfs_scheme_regions *sysfs_regions;
+ struct damon_sysfs_scheme_region *region;
+ int schemes_idx = 0;
+
+ damon_for_each_scheme(scheme, ctx) {
+ if (scheme == s)
+ break;
+ schemes_idx++;
+ }
+
+ /* user could have removed the scheme sysfs dir */
+ if (schemes_idx >= sysfs_schemes->nr)
+ return;
+
+ sysfs_regions = sysfs_schemes->schemes_arr[schemes_idx]->tried_regions;
+ sysfs_regions->total_bytes += r->ar.end - r->ar.start;
+ if (total_bytes_only)
+ return;
+
+ region = damon_sysfs_scheme_region_alloc(r);
+ if (!region)
+ return;
+ list_add_tail(&region->list, &sysfs_regions->regions_list);
+ sysfs_regions->nr_regions++;
+ if (kobject_init_and_add(&region->kobj,
+ &damon_sysfs_scheme_region_ktype,
+ &sysfs_regions->kobj, "%d",
+ sysfs_regions->nr_regions++)) {
+ kobject_put(&region->kobj);
+ }
+}
+
/*
* DAMON callback that called after each accesses sampling. While this
* callback is registered, damon_sysfs_lock should be held to ensure the