summaryrefslogtreecommitdiff
path: root/mm/damon/sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/damon/sysfs.c')
-rw-r--r--mm/damon/sysfs.c47
1 files changed, 30 insertions, 17 deletions
diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
index 1a231bde18f9..e27846708b5a 100644
--- a/mm/damon/sysfs.c
+++ b/mm/damon/sysfs.c
@@ -1150,34 +1150,47 @@ destroy_targets_out:
return err;
}
-static int damon_sysfs_update_target(struct damon_target *target,
- struct damon_ctx *ctx,
- struct damon_sysfs_target *sys_target)
+static int damon_sysfs_update_target_pid(struct damon_target *target, int pid)
{
- struct pid *pid;
- struct damon_region *r, *next;
-
- if (!damon_target_has_pid(ctx))
- return 0;
+ struct pid *pid_new;
- pid = find_get_pid(sys_target->pid);
- if (!pid)
+ pid_new = find_get_pid(pid);
+ if (!pid_new)
return -EINVAL;
- /* no change to the target */
- if (pid == target->pid) {
- put_pid(pid);
+ if (pid_new == target->pid) {
+ put_pid(pid_new);
return 0;
}
- /* remove old monitoring results and update the target's pid */
- damon_for_each_region_safe(r, next, target)
- damon_destroy_region(r, target);
put_pid(target->pid);
- target->pid = pid;
+ target->pid = pid_new;
return 0;
}
+static int damon_sysfs_update_target(struct damon_target *target,
+ struct damon_ctx *ctx,
+ struct damon_sysfs_target *sys_target)
+{
+ int err;
+
+ if (damon_target_has_pid(ctx)) {
+ err = damon_sysfs_update_target_pid(target, sys_target->pid);
+ if (err)
+ return err;
+ }
+
+ /*
+ * Do monitoring target region boundary update only if one or more
+ * regions are set by the user. This is for keeping current monitoring
+ * target results and range easier, especially for dynamic monitoring
+ * target regions update ops like 'vaddr'.
+ */
+ if (sys_target->regions->nr)
+ err = damon_sysfs_set_regions(target, sys_target->regions);
+ return err;
+}
+
static int damon_sysfs_set_targets(struct damon_ctx *ctx,
struct damon_sysfs_targets *sysfs_targets)
{