xref: /linux/mm/damon/sysfs-schemes.c (revision 5e2cb28dd7e182dfa641550dfa225913509ad45d)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * DAMON sysfs Interface
4  *
5  * Copyright (c) 2022 SeongJae Park <sj@kernel.org>
6  */
7 
8 #include <linux/slab.h>
9 
10 #include "sysfs-common.h"
11 
12 /*
13  * scheme region directory
14  */
15 
16 struct damon_sysfs_scheme_region {
17 	struct kobject kobj;
18 	struct damon_addr_range ar;
19 	unsigned int nr_accesses;
20 	unsigned int age;
21 	struct list_head list;
22 };
23 
24 static struct damon_sysfs_scheme_region *damon_sysfs_scheme_region_alloc(
25 		struct damon_region *region)
26 {
27 	struct damon_sysfs_scheme_region *sysfs_region = kmalloc(
28 			sizeof(*sysfs_region), GFP_KERNEL);
29 
30 	if (!sysfs_region)
31 		return NULL;
32 	sysfs_region->kobj = (struct kobject){};
33 	sysfs_region->ar = region->ar;
34 	sysfs_region->nr_accesses = region->nr_accesses_bp / 10000;
35 	sysfs_region->age = region->age;
36 	INIT_LIST_HEAD(&sysfs_region->list);
37 	return sysfs_region;
38 }
39 
40 static ssize_t start_show(struct kobject *kobj, struct kobj_attribute *attr,
41 		char *buf)
42 {
43 	struct damon_sysfs_scheme_region *region = container_of(kobj,
44 			struct damon_sysfs_scheme_region, kobj);
45 
46 	return sysfs_emit(buf, "%lu\n", region->ar.start);
47 }
48 
49 static ssize_t end_show(struct kobject *kobj, struct kobj_attribute *attr,
50 		char *buf)
51 {
52 	struct damon_sysfs_scheme_region *region = container_of(kobj,
53 			struct damon_sysfs_scheme_region, kobj);
54 
55 	return sysfs_emit(buf, "%lu\n", region->ar.end);
56 }
57 
58 static ssize_t nr_accesses_show(struct kobject *kobj,
59 		struct kobj_attribute *attr, char *buf)
60 {
61 	struct damon_sysfs_scheme_region *region = container_of(kobj,
62 			struct damon_sysfs_scheme_region, kobj);
63 
64 	return sysfs_emit(buf, "%u\n", region->nr_accesses);
65 }
66 
67 static ssize_t age_show(struct kobject *kobj, struct kobj_attribute *attr,
68 		char *buf)
69 {
70 	struct damon_sysfs_scheme_region *region = container_of(kobj,
71 			struct damon_sysfs_scheme_region, kobj);
72 
73 	return sysfs_emit(buf, "%u\n", region->age);
74 }
75 
76 static void damon_sysfs_scheme_region_release(struct kobject *kobj)
77 {
78 	struct damon_sysfs_scheme_region *region = container_of(kobj,
79 			struct damon_sysfs_scheme_region, kobj);
80 
81 	list_del(&region->list);
82 	kfree(region);
83 }
84 
85 static struct kobj_attribute damon_sysfs_scheme_region_start_attr =
86 		__ATTR_RO_MODE(start, 0400);
87 
88 static struct kobj_attribute damon_sysfs_scheme_region_end_attr =
89 		__ATTR_RO_MODE(end, 0400);
90 
91 static struct kobj_attribute damon_sysfs_scheme_region_nr_accesses_attr =
92 		__ATTR_RO_MODE(nr_accesses, 0400);
93 
94 static struct kobj_attribute damon_sysfs_scheme_region_age_attr =
95 		__ATTR_RO_MODE(age, 0400);
96 
97 static struct attribute *damon_sysfs_scheme_region_attrs[] = {
98 	&damon_sysfs_scheme_region_start_attr.attr,
99 	&damon_sysfs_scheme_region_end_attr.attr,
100 	&damon_sysfs_scheme_region_nr_accesses_attr.attr,
101 	&damon_sysfs_scheme_region_age_attr.attr,
102 	NULL,
103 };
104 ATTRIBUTE_GROUPS(damon_sysfs_scheme_region);
105 
106 static const struct kobj_type damon_sysfs_scheme_region_ktype = {
107 	.release = damon_sysfs_scheme_region_release,
108 	.sysfs_ops = &kobj_sysfs_ops,
109 	.default_groups = damon_sysfs_scheme_region_groups,
110 };
111 
112 /*
113  * scheme regions directory
114  */
115 
116 /*
117  * enum damos_sysfs_regions_upd_status - Represent DAMOS tried regions update
118  *					 status
119  * @DAMOS_TRIED_REGIONS_UPD_IDLE:		Waiting for next request.
120  * @DAMOS_TRIED_REGIONS_UPD_STARTED:		Update started.
121  * @DAMOS_TRIED_REGIONS_UPD_FINISHED:	Update finished.
122  *
123  * Each DAMON-based operation scheme (&struct damos) has its own apply
124  * interval, and we need to expose the scheme tried regions based on only
125  * single snapshot.  For this, we keep the tried regions update status for each
126  * scheme.  The status becomes 'idle' at the beginning.
127  *
128  * Once the tried regions update request is received, the request handling
129  * start function (damon_sysfs_scheme_update_regions_start()) sets the status
130  * of all schemes as 'idle' again, and register ->before_damos_apply() and
131  * ->after_sampling() callbacks.
132  *
133  * Then, the first followup ->before_damos_apply() callback
134  * (damon_sysfs_before_damos_apply()) sets the status 'started'.  The first
135  * ->after_sampling() callback (damon_sysfs_after_sampling()) after the call
136  * is called only after the scheme is completely applied
137  * to the given snapshot.  Hence the callback knows the situation by showing
138  * 'started' status, and sets the status as 'finished'.  Then,
139  * damon_sysfs_before_damos_apply() understands the situation by showing the
140  * 'finished' status and do nothing.
141  *
142  *  Finally, the tried regions request handling finisher function
143  *  (damon_sysfs_schemes_update_regions_stop()) unregisters the callbacks.
144  */
145 enum damos_sysfs_regions_upd_status {
146 	DAMOS_TRIED_REGIONS_UPD_IDLE,
147 	DAMOS_TRIED_REGIONS_UPD_STARTED,
148 	DAMOS_TRIED_REGIONS_UPD_FINISHED,
149 };
150 
151 struct damon_sysfs_scheme_regions {
152 	struct kobject kobj;
153 	struct list_head regions_list;
154 	int nr_regions;
155 	unsigned long total_bytes;
156 	enum damos_sysfs_regions_upd_status upd_status;
157 };
158 
159 static struct damon_sysfs_scheme_regions *
160 damon_sysfs_scheme_regions_alloc(void)
161 {
162 	struct damon_sysfs_scheme_regions *regions = kmalloc(sizeof(*regions),
163 			GFP_KERNEL);
164 
165 	regions->kobj = (struct kobject){};
166 	INIT_LIST_HEAD(&regions->regions_list);
167 	regions->nr_regions = 0;
168 	regions->total_bytes = 0;
169 	regions->upd_status = DAMOS_TRIED_REGIONS_UPD_IDLE;
170 	return regions;
171 }
172 
173 static ssize_t total_bytes_show(struct kobject *kobj,
174 		struct kobj_attribute *attr, char *buf)
175 {
176 	struct damon_sysfs_scheme_regions *regions = container_of(kobj,
177 			struct damon_sysfs_scheme_regions, kobj);
178 
179 	return sysfs_emit(buf, "%lu\n", regions->total_bytes);
180 }
181 
182 static void damon_sysfs_scheme_regions_rm_dirs(
183 		struct damon_sysfs_scheme_regions *regions)
184 {
185 	struct damon_sysfs_scheme_region *r, *next;
186 
187 	list_for_each_entry_safe(r, next, &regions->regions_list, list) {
188 		/* release function deletes it from the list */
189 		kobject_put(&r->kobj);
190 		regions->nr_regions--;
191 	}
192 }
193 
194 static void damon_sysfs_scheme_regions_release(struct kobject *kobj)
195 {
196 	kfree(container_of(kobj, struct damon_sysfs_scheme_regions, kobj));
197 }
198 
199 static struct kobj_attribute damon_sysfs_scheme_regions_total_bytes_attr =
200 		__ATTR_RO_MODE(total_bytes, 0400);
201 
202 static struct attribute *damon_sysfs_scheme_regions_attrs[] = {
203 	&damon_sysfs_scheme_regions_total_bytes_attr.attr,
204 	NULL,
205 };
206 ATTRIBUTE_GROUPS(damon_sysfs_scheme_regions);
207 
208 static const struct kobj_type damon_sysfs_scheme_regions_ktype = {
209 	.release = damon_sysfs_scheme_regions_release,
210 	.sysfs_ops = &kobj_sysfs_ops,
211 	.default_groups = damon_sysfs_scheme_regions_groups,
212 };
213 
214 /*
215  * schemes/stats directory
216  */
217 
218 struct damon_sysfs_stats {
219 	struct kobject kobj;
220 	unsigned long nr_tried;
221 	unsigned long sz_tried;
222 	unsigned long nr_applied;
223 	unsigned long sz_applied;
224 	unsigned long qt_exceeds;
225 };
226 
227 static struct damon_sysfs_stats *damon_sysfs_stats_alloc(void)
228 {
229 	return kzalloc(sizeof(struct damon_sysfs_stats), GFP_KERNEL);
230 }
231 
232 static ssize_t nr_tried_show(struct kobject *kobj, struct kobj_attribute *attr,
233 		char *buf)
234 {
235 	struct damon_sysfs_stats *stats = container_of(kobj,
236 			struct damon_sysfs_stats, kobj);
237 
238 	return sysfs_emit(buf, "%lu\n", stats->nr_tried);
239 }
240 
241 static ssize_t sz_tried_show(struct kobject *kobj, struct kobj_attribute *attr,
242 		char *buf)
243 {
244 	struct damon_sysfs_stats *stats = container_of(kobj,
245 			struct damon_sysfs_stats, kobj);
246 
247 	return sysfs_emit(buf, "%lu\n", stats->sz_tried);
248 }
249 
250 static ssize_t nr_applied_show(struct kobject *kobj,
251 		struct kobj_attribute *attr, char *buf)
252 {
253 	struct damon_sysfs_stats *stats = container_of(kobj,
254 			struct damon_sysfs_stats, kobj);
255 
256 	return sysfs_emit(buf, "%lu\n", stats->nr_applied);
257 }
258 
259 static ssize_t sz_applied_show(struct kobject *kobj,
260 		struct kobj_attribute *attr, char *buf)
261 {
262 	struct damon_sysfs_stats *stats = container_of(kobj,
263 			struct damon_sysfs_stats, kobj);
264 
265 	return sysfs_emit(buf, "%lu\n", stats->sz_applied);
266 }
267 
268 static ssize_t qt_exceeds_show(struct kobject *kobj,
269 		struct kobj_attribute *attr, char *buf)
270 {
271 	struct damon_sysfs_stats *stats = container_of(kobj,
272 			struct damon_sysfs_stats, kobj);
273 
274 	return sysfs_emit(buf, "%lu\n", stats->qt_exceeds);
275 }
276 
277 static void damon_sysfs_stats_release(struct kobject *kobj)
278 {
279 	kfree(container_of(kobj, struct damon_sysfs_stats, kobj));
280 }
281 
282 static struct kobj_attribute damon_sysfs_stats_nr_tried_attr =
283 		__ATTR_RO_MODE(nr_tried, 0400);
284 
285 static struct kobj_attribute damon_sysfs_stats_sz_tried_attr =
286 		__ATTR_RO_MODE(sz_tried, 0400);
287 
288 static struct kobj_attribute damon_sysfs_stats_nr_applied_attr =
289 		__ATTR_RO_MODE(nr_applied, 0400);
290 
291 static struct kobj_attribute damon_sysfs_stats_sz_applied_attr =
292 		__ATTR_RO_MODE(sz_applied, 0400);
293 
294 static struct kobj_attribute damon_sysfs_stats_qt_exceeds_attr =
295 		__ATTR_RO_MODE(qt_exceeds, 0400);
296 
297 static struct attribute *damon_sysfs_stats_attrs[] = {
298 	&damon_sysfs_stats_nr_tried_attr.attr,
299 	&damon_sysfs_stats_sz_tried_attr.attr,
300 	&damon_sysfs_stats_nr_applied_attr.attr,
301 	&damon_sysfs_stats_sz_applied_attr.attr,
302 	&damon_sysfs_stats_qt_exceeds_attr.attr,
303 	NULL,
304 };
305 ATTRIBUTE_GROUPS(damon_sysfs_stats);
306 
307 static const struct kobj_type damon_sysfs_stats_ktype = {
308 	.release = damon_sysfs_stats_release,
309 	.sysfs_ops = &kobj_sysfs_ops,
310 	.default_groups = damon_sysfs_stats_groups,
311 };
312 
313 /*
314  * filter directory
315  */
316 
317 struct damon_sysfs_scheme_filter {
318 	struct kobject kobj;
319 	enum damos_filter_type type;
320 	bool matching;
321 	char *memcg_path;
322 	struct damon_addr_range addr_range;
323 	int target_idx;
324 };
325 
326 static struct damon_sysfs_scheme_filter *damon_sysfs_scheme_filter_alloc(void)
327 {
328 	return kzalloc(sizeof(struct damon_sysfs_scheme_filter), GFP_KERNEL);
329 }
330 
331 /* Should match with enum damos_filter_type */
332 static const char * const damon_sysfs_scheme_filter_type_strs[] = {
333 	"anon",
334 	"memcg",
335 	"addr",
336 	"target",
337 };
338 
339 static ssize_t type_show(struct kobject *kobj,
340 		struct kobj_attribute *attr, char *buf)
341 {
342 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
343 			struct damon_sysfs_scheme_filter, kobj);
344 
345 	return sysfs_emit(buf, "%s\n",
346 			damon_sysfs_scheme_filter_type_strs[filter->type]);
347 }
348 
349 static ssize_t type_store(struct kobject *kobj,
350 		struct kobj_attribute *attr, const char *buf, size_t count)
351 {
352 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
353 			struct damon_sysfs_scheme_filter, kobj);
354 	enum damos_filter_type type;
355 	ssize_t ret = -EINVAL;
356 
357 	for (type = 0; type < NR_DAMOS_FILTER_TYPES; type++) {
358 		if (sysfs_streq(buf, damon_sysfs_scheme_filter_type_strs[
359 					type])) {
360 			filter->type = type;
361 			ret = count;
362 			break;
363 		}
364 	}
365 	return ret;
366 }
367 
368 static ssize_t matching_show(struct kobject *kobj,
369 		struct kobj_attribute *attr, char *buf)
370 {
371 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
372 			struct damon_sysfs_scheme_filter, kobj);
373 
374 	return sysfs_emit(buf, "%c\n", filter->matching ? 'Y' : 'N');
375 }
376 
377 static ssize_t matching_store(struct kobject *kobj,
378 		struct kobj_attribute *attr, const char *buf, size_t count)
379 {
380 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
381 			struct damon_sysfs_scheme_filter, kobj);
382 	bool matching;
383 	int err = kstrtobool(buf, &matching);
384 
385 	if (err)
386 		return err;
387 
388 	filter->matching = matching;
389 	return count;
390 }
391 
392 static ssize_t memcg_path_show(struct kobject *kobj,
393 		struct kobj_attribute *attr, char *buf)
394 {
395 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
396 			struct damon_sysfs_scheme_filter, kobj);
397 
398 	return sysfs_emit(buf, "%s\n",
399 			filter->memcg_path ? filter->memcg_path : "");
400 }
401 
402 static ssize_t memcg_path_store(struct kobject *kobj,
403 		struct kobj_attribute *attr, const char *buf, size_t count)
404 {
405 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
406 			struct damon_sysfs_scheme_filter, kobj);
407 	char *path = kmalloc(sizeof(*path) * (count + 1), GFP_KERNEL);
408 
409 	if (!path)
410 		return -ENOMEM;
411 
412 	strscpy(path, buf, count + 1);
413 	filter->memcg_path = path;
414 	return count;
415 }
416 
417 static ssize_t addr_start_show(struct kobject *kobj,
418 		struct kobj_attribute *attr, char *buf)
419 {
420 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
421 			struct damon_sysfs_scheme_filter, kobj);
422 
423 	return sysfs_emit(buf, "%lu\n", filter->addr_range.start);
424 }
425 
426 static ssize_t addr_start_store(struct kobject *kobj,
427 		struct kobj_attribute *attr, const char *buf, size_t count)
428 {
429 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
430 			struct damon_sysfs_scheme_filter, kobj);
431 	int err = kstrtoul(buf, 0, &filter->addr_range.start);
432 
433 	return err ? err : count;
434 }
435 
436 static ssize_t addr_end_show(struct kobject *kobj,
437 		struct kobj_attribute *attr, char *buf)
438 {
439 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
440 			struct damon_sysfs_scheme_filter, kobj);
441 
442 	return sysfs_emit(buf, "%lu\n", filter->addr_range.end);
443 }
444 
445 static ssize_t addr_end_store(struct kobject *kobj,
446 		struct kobj_attribute *attr, const char *buf, size_t count)
447 {
448 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
449 			struct damon_sysfs_scheme_filter, kobj);
450 	int err = kstrtoul(buf, 0, &filter->addr_range.end);
451 
452 	return err ? err : count;
453 }
454 
455 static ssize_t damon_target_idx_show(struct kobject *kobj,
456 		struct kobj_attribute *attr, char *buf)
457 {
458 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
459 			struct damon_sysfs_scheme_filter, kobj);
460 
461 	return sysfs_emit(buf, "%d\n", filter->target_idx);
462 }
463 
464 static ssize_t damon_target_idx_store(struct kobject *kobj,
465 		struct kobj_attribute *attr, const char *buf, size_t count)
466 {
467 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
468 			struct damon_sysfs_scheme_filter, kobj);
469 	int err = kstrtoint(buf, 0, &filter->target_idx);
470 
471 	return err ? err : count;
472 }
473 
474 static void damon_sysfs_scheme_filter_release(struct kobject *kobj)
475 {
476 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
477 			struct damon_sysfs_scheme_filter, kobj);
478 
479 	kfree(filter->memcg_path);
480 	kfree(filter);
481 }
482 
483 static struct kobj_attribute damon_sysfs_scheme_filter_type_attr =
484 		__ATTR_RW_MODE(type, 0600);
485 
486 static struct kobj_attribute damon_sysfs_scheme_filter_matching_attr =
487 		__ATTR_RW_MODE(matching, 0600);
488 
489 static struct kobj_attribute damon_sysfs_scheme_filter_memcg_path_attr =
490 		__ATTR_RW_MODE(memcg_path, 0600);
491 
492 static struct kobj_attribute damon_sysfs_scheme_filter_addr_start_attr =
493 		__ATTR_RW_MODE(addr_start, 0600);
494 
495 static struct kobj_attribute damon_sysfs_scheme_filter_addr_end_attr =
496 		__ATTR_RW_MODE(addr_end, 0600);
497 
498 static struct kobj_attribute damon_sysfs_scheme_filter_damon_target_idx_attr =
499 		__ATTR_RW_MODE(damon_target_idx, 0600);
500 
501 static struct attribute *damon_sysfs_scheme_filter_attrs[] = {
502 	&damon_sysfs_scheme_filter_type_attr.attr,
503 	&damon_sysfs_scheme_filter_matching_attr.attr,
504 	&damon_sysfs_scheme_filter_memcg_path_attr.attr,
505 	&damon_sysfs_scheme_filter_addr_start_attr.attr,
506 	&damon_sysfs_scheme_filter_addr_end_attr.attr,
507 	&damon_sysfs_scheme_filter_damon_target_idx_attr.attr,
508 	NULL,
509 };
510 ATTRIBUTE_GROUPS(damon_sysfs_scheme_filter);
511 
512 static const struct kobj_type damon_sysfs_scheme_filter_ktype = {
513 	.release = damon_sysfs_scheme_filter_release,
514 	.sysfs_ops = &kobj_sysfs_ops,
515 	.default_groups = damon_sysfs_scheme_filter_groups,
516 };
517 
518 /*
519  * filters directory
520  */
521 
522 struct damon_sysfs_scheme_filters {
523 	struct kobject kobj;
524 	struct damon_sysfs_scheme_filter **filters_arr;
525 	int nr;
526 };
527 
528 static struct damon_sysfs_scheme_filters *
529 damon_sysfs_scheme_filters_alloc(void)
530 {
531 	return kzalloc(sizeof(struct damon_sysfs_scheme_filters), GFP_KERNEL);
532 }
533 
534 static void damon_sysfs_scheme_filters_rm_dirs(
535 		struct damon_sysfs_scheme_filters *filters)
536 {
537 	struct damon_sysfs_scheme_filter **filters_arr = filters->filters_arr;
538 	int i;
539 
540 	for (i = 0; i < filters->nr; i++)
541 		kobject_put(&filters_arr[i]->kobj);
542 	filters->nr = 0;
543 	kfree(filters_arr);
544 	filters->filters_arr = NULL;
545 }
546 
547 static int damon_sysfs_scheme_filters_add_dirs(
548 		struct damon_sysfs_scheme_filters *filters, int nr_filters)
549 {
550 	struct damon_sysfs_scheme_filter **filters_arr, *filter;
551 	int err, i;
552 
553 	damon_sysfs_scheme_filters_rm_dirs(filters);
554 	if (!nr_filters)
555 		return 0;
556 
557 	filters_arr = kmalloc_array(nr_filters, sizeof(*filters_arr),
558 			GFP_KERNEL | __GFP_NOWARN);
559 	if (!filters_arr)
560 		return -ENOMEM;
561 	filters->filters_arr = filters_arr;
562 
563 	for (i = 0; i < nr_filters; i++) {
564 		filter = damon_sysfs_scheme_filter_alloc();
565 		if (!filter) {
566 			damon_sysfs_scheme_filters_rm_dirs(filters);
567 			return -ENOMEM;
568 		}
569 
570 		err = kobject_init_and_add(&filter->kobj,
571 				&damon_sysfs_scheme_filter_ktype,
572 				&filters->kobj, "%d", i);
573 		if (err) {
574 			kobject_put(&filter->kobj);
575 			damon_sysfs_scheme_filters_rm_dirs(filters);
576 			return err;
577 		}
578 
579 		filters_arr[i] = filter;
580 		filters->nr++;
581 	}
582 	return 0;
583 }
584 
585 static ssize_t nr_filters_show(struct kobject *kobj,
586 		struct kobj_attribute *attr, char *buf)
587 {
588 	struct damon_sysfs_scheme_filters *filters = container_of(kobj,
589 			struct damon_sysfs_scheme_filters, kobj);
590 
591 	return sysfs_emit(buf, "%d\n", filters->nr);
592 }
593 
594 static ssize_t nr_filters_store(struct kobject *kobj,
595 		struct kobj_attribute *attr, const char *buf, size_t count)
596 {
597 	struct damon_sysfs_scheme_filters *filters;
598 	int nr, err = kstrtoint(buf, 0, &nr);
599 
600 	if (err)
601 		return err;
602 	if (nr < 0)
603 		return -EINVAL;
604 
605 	filters = container_of(kobj, struct damon_sysfs_scheme_filters, kobj);
606 
607 	if (!mutex_trylock(&damon_sysfs_lock))
608 		return -EBUSY;
609 	err = damon_sysfs_scheme_filters_add_dirs(filters, nr);
610 	mutex_unlock(&damon_sysfs_lock);
611 	if (err)
612 		return err;
613 
614 	return count;
615 }
616 
617 static void damon_sysfs_scheme_filters_release(struct kobject *kobj)
618 {
619 	kfree(container_of(kobj, struct damon_sysfs_scheme_filters, kobj));
620 }
621 
622 static struct kobj_attribute damon_sysfs_scheme_filters_nr_attr =
623 		__ATTR_RW_MODE(nr_filters, 0600);
624 
625 static struct attribute *damon_sysfs_scheme_filters_attrs[] = {
626 	&damon_sysfs_scheme_filters_nr_attr.attr,
627 	NULL,
628 };
629 ATTRIBUTE_GROUPS(damon_sysfs_scheme_filters);
630 
631 static const struct kobj_type damon_sysfs_scheme_filters_ktype = {
632 	.release = damon_sysfs_scheme_filters_release,
633 	.sysfs_ops = &kobj_sysfs_ops,
634 	.default_groups = damon_sysfs_scheme_filters_groups,
635 };
636 
637 /*
638  * watermarks directory
639  */
640 
641 struct damon_sysfs_watermarks {
642 	struct kobject kobj;
643 	enum damos_wmark_metric metric;
644 	unsigned long interval_us;
645 	unsigned long high;
646 	unsigned long mid;
647 	unsigned long low;
648 };
649 
650 static struct damon_sysfs_watermarks *damon_sysfs_watermarks_alloc(
651 		enum damos_wmark_metric metric, unsigned long interval_us,
652 		unsigned long high, unsigned long mid, unsigned long low)
653 {
654 	struct damon_sysfs_watermarks *watermarks = kmalloc(
655 			sizeof(*watermarks), GFP_KERNEL);
656 
657 	if (!watermarks)
658 		return NULL;
659 	watermarks->kobj = (struct kobject){};
660 	watermarks->metric = metric;
661 	watermarks->interval_us = interval_us;
662 	watermarks->high = high;
663 	watermarks->mid = mid;
664 	watermarks->low = low;
665 	return watermarks;
666 }
667 
668 /* Should match with enum damos_wmark_metric */
669 static const char * const damon_sysfs_wmark_metric_strs[] = {
670 	"none",
671 	"free_mem_rate",
672 };
673 
674 static ssize_t metric_show(struct kobject *kobj, struct kobj_attribute *attr,
675 		char *buf)
676 {
677 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
678 			struct damon_sysfs_watermarks, kobj);
679 
680 	return sysfs_emit(buf, "%s\n",
681 			damon_sysfs_wmark_metric_strs[watermarks->metric]);
682 }
683 
684 static ssize_t metric_store(struct kobject *kobj, struct kobj_attribute *attr,
685 		const char *buf, size_t count)
686 {
687 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
688 			struct damon_sysfs_watermarks, kobj);
689 	enum damos_wmark_metric metric;
690 
691 	for (metric = 0; metric < NR_DAMOS_WMARK_METRICS; metric++) {
692 		if (sysfs_streq(buf, damon_sysfs_wmark_metric_strs[metric])) {
693 			watermarks->metric = metric;
694 			return count;
695 		}
696 	}
697 	return -EINVAL;
698 }
699 
700 static ssize_t interval_us_show(struct kobject *kobj,
701 		struct kobj_attribute *attr, char *buf)
702 {
703 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
704 			struct damon_sysfs_watermarks, kobj);
705 
706 	return sysfs_emit(buf, "%lu\n", watermarks->interval_us);
707 }
708 
709 static ssize_t interval_us_store(struct kobject *kobj,
710 		struct kobj_attribute *attr, const char *buf, size_t count)
711 {
712 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
713 			struct damon_sysfs_watermarks, kobj);
714 	int err = kstrtoul(buf, 0, &watermarks->interval_us);
715 
716 	return err ? err : count;
717 }
718 
719 static ssize_t high_show(struct kobject *kobj,
720 		struct kobj_attribute *attr, char *buf)
721 {
722 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
723 			struct damon_sysfs_watermarks, kobj);
724 
725 	return sysfs_emit(buf, "%lu\n", watermarks->high);
726 }
727 
728 static ssize_t high_store(struct kobject *kobj,
729 		struct kobj_attribute *attr, const char *buf, size_t count)
730 {
731 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
732 			struct damon_sysfs_watermarks, kobj);
733 	int err = kstrtoul(buf, 0, &watermarks->high);
734 
735 	return err ? err : count;
736 }
737 
738 static ssize_t mid_show(struct kobject *kobj,
739 		struct kobj_attribute *attr, char *buf)
740 {
741 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
742 			struct damon_sysfs_watermarks, kobj);
743 
744 	return sysfs_emit(buf, "%lu\n", watermarks->mid);
745 }
746 
747 static ssize_t mid_store(struct kobject *kobj,
748 		struct kobj_attribute *attr, const char *buf, size_t count)
749 {
750 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
751 			struct damon_sysfs_watermarks, kobj);
752 	int err = kstrtoul(buf, 0, &watermarks->mid);
753 
754 	return err ? err : count;
755 }
756 
757 static ssize_t low_show(struct kobject *kobj,
758 		struct kobj_attribute *attr, char *buf)
759 {
760 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
761 			struct damon_sysfs_watermarks, kobj);
762 
763 	return sysfs_emit(buf, "%lu\n", watermarks->low);
764 }
765 
766 static ssize_t low_store(struct kobject *kobj,
767 		struct kobj_attribute *attr, const char *buf, size_t count)
768 {
769 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
770 			struct damon_sysfs_watermarks, kobj);
771 	int err = kstrtoul(buf, 0, &watermarks->low);
772 
773 	return err ? err : count;
774 }
775 
776 static void damon_sysfs_watermarks_release(struct kobject *kobj)
777 {
778 	kfree(container_of(kobj, struct damon_sysfs_watermarks, kobj));
779 }
780 
781 static struct kobj_attribute damon_sysfs_watermarks_metric_attr =
782 		__ATTR_RW_MODE(metric, 0600);
783 
784 static struct kobj_attribute damon_sysfs_watermarks_interval_us_attr =
785 		__ATTR_RW_MODE(interval_us, 0600);
786 
787 static struct kobj_attribute damon_sysfs_watermarks_high_attr =
788 		__ATTR_RW_MODE(high, 0600);
789 
790 static struct kobj_attribute damon_sysfs_watermarks_mid_attr =
791 		__ATTR_RW_MODE(mid, 0600);
792 
793 static struct kobj_attribute damon_sysfs_watermarks_low_attr =
794 		__ATTR_RW_MODE(low, 0600);
795 
796 static struct attribute *damon_sysfs_watermarks_attrs[] = {
797 	&damon_sysfs_watermarks_metric_attr.attr,
798 	&damon_sysfs_watermarks_interval_us_attr.attr,
799 	&damon_sysfs_watermarks_high_attr.attr,
800 	&damon_sysfs_watermarks_mid_attr.attr,
801 	&damon_sysfs_watermarks_low_attr.attr,
802 	NULL,
803 };
804 ATTRIBUTE_GROUPS(damon_sysfs_watermarks);
805 
806 static const struct kobj_type damon_sysfs_watermarks_ktype = {
807 	.release = damon_sysfs_watermarks_release,
808 	.sysfs_ops = &kobj_sysfs_ops,
809 	.default_groups = damon_sysfs_watermarks_groups,
810 };
811 
812 /*
813  * scheme/weights directory
814  */
815 
816 struct damon_sysfs_weights {
817 	struct kobject kobj;
818 	unsigned int sz;
819 	unsigned int nr_accesses;
820 	unsigned int age;
821 };
822 
823 static struct damon_sysfs_weights *damon_sysfs_weights_alloc(unsigned int sz,
824 		unsigned int nr_accesses, unsigned int age)
825 {
826 	struct damon_sysfs_weights *weights = kmalloc(sizeof(*weights),
827 			GFP_KERNEL);
828 
829 	if (!weights)
830 		return NULL;
831 	weights->kobj = (struct kobject){};
832 	weights->sz = sz;
833 	weights->nr_accesses = nr_accesses;
834 	weights->age = age;
835 	return weights;
836 }
837 
838 static ssize_t sz_permil_show(struct kobject *kobj,
839 		struct kobj_attribute *attr, char *buf)
840 {
841 	struct damon_sysfs_weights *weights = container_of(kobj,
842 			struct damon_sysfs_weights, kobj);
843 
844 	return sysfs_emit(buf, "%u\n", weights->sz);
845 }
846 
847 static ssize_t sz_permil_store(struct kobject *kobj,
848 		struct kobj_attribute *attr, const char *buf, size_t count)
849 {
850 	struct damon_sysfs_weights *weights = container_of(kobj,
851 			struct damon_sysfs_weights, kobj);
852 	int err = kstrtouint(buf, 0, &weights->sz);
853 
854 	return err ? err : count;
855 }
856 
857 static ssize_t nr_accesses_permil_show(struct kobject *kobj,
858 		struct kobj_attribute *attr, char *buf)
859 {
860 	struct damon_sysfs_weights *weights = container_of(kobj,
861 			struct damon_sysfs_weights, kobj);
862 
863 	return sysfs_emit(buf, "%u\n", weights->nr_accesses);
864 }
865 
866 static ssize_t nr_accesses_permil_store(struct kobject *kobj,
867 		struct kobj_attribute *attr, const char *buf, size_t count)
868 {
869 	struct damon_sysfs_weights *weights = container_of(kobj,
870 			struct damon_sysfs_weights, kobj);
871 	int err = kstrtouint(buf, 0, &weights->nr_accesses);
872 
873 	return err ? err : count;
874 }
875 
876 static ssize_t age_permil_show(struct kobject *kobj,
877 		struct kobj_attribute *attr, char *buf)
878 {
879 	struct damon_sysfs_weights *weights = container_of(kobj,
880 			struct damon_sysfs_weights, kobj);
881 
882 	return sysfs_emit(buf, "%u\n", weights->age);
883 }
884 
885 static ssize_t age_permil_store(struct kobject *kobj,
886 		struct kobj_attribute *attr, const char *buf, size_t count)
887 {
888 	struct damon_sysfs_weights *weights = container_of(kobj,
889 			struct damon_sysfs_weights, kobj);
890 	int err = kstrtouint(buf, 0, &weights->age);
891 
892 	return err ? err : count;
893 }
894 
895 static void damon_sysfs_weights_release(struct kobject *kobj)
896 {
897 	kfree(container_of(kobj, struct damon_sysfs_weights, kobj));
898 }
899 
900 static struct kobj_attribute damon_sysfs_weights_sz_attr =
901 		__ATTR_RW_MODE(sz_permil, 0600);
902 
903 static struct kobj_attribute damon_sysfs_weights_nr_accesses_attr =
904 		__ATTR_RW_MODE(nr_accesses_permil, 0600);
905 
906 static struct kobj_attribute damon_sysfs_weights_age_attr =
907 		__ATTR_RW_MODE(age_permil, 0600);
908 
909 static struct attribute *damon_sysfs_weights_attrs[] = {
910 	&damon_sysfs_weights_sz_attr.attr,
911 	&damon_sysfs_weights_nr_accesses_attr.attr,
912 	&damon_sysfs_weights_age_attr.attr,
913 	NULL,
914 };
915 ATTRIBUTE_GROUPS(damon_sysfs_weights);
916 
917 static const struct kobj_type damon_sysfs_weights_ktype = {
918 	.release = damon_sysfs_weights_release,
919 	.sysfs_ops = &kobj_sysfs_ops,
920 	.default_groups = damon_sysfs_weights_groups,
921 };
922 
923 /*
924  * quotas directory
925  */
926 
927 struct damon_sysfs_quotas {
928 	struct kobject kobj;
929 	struct damon_sysfs_weights *weights;
930 	unsigned long ms;
931 	unsigned long sz;
932 	unsigned long reset_interval_ms;
933 };
934 
935 static struct damon_sysfs_quotas *damon_sysfs_quotas_alloc(void)
936 {
937 	return kzalloc(sizeof(struct damon_sysfs_quotas), GFP_KERNEL);
938 }
939 
940 static int damon_sysfs_quotas_add_dirs(struct damon_sysfs_quotas *quotas)
941 {
942 	struct damon_sysfs_weights *weights;
943 	int err;
944 
945 	weights = damon_sysfs_weights_alloc(0, 0, 0);
946 	if (!weights)
947 		return -ENOMEM;
948 
949 	err = kobject_init_and_add(&weights->kobj, &damon_sysfs_weights_ktype,
950 			&quotas->kobj, "weights");
951 	if (err)
952 		kobject_put(&weights->kobj);
953 	else
954 		quotas->weights = weights;
955 	return err;
956 }
957 
958 static void damon_sysfs_quotas_rm_dirs(struct damon_sysfs_quotas *quotas)
959 {
960 	kobject_put(&quotas->weights->kobj);
961 }
962 
963 static ssize_t ms_show(struct kobject *kobj, struct kobj_attribute *attr,
964 		char *buf)
965 {
966 	struct damon_sysfs_quotas *quotas = container_of(kobj,
967 			struct damon_sysfs_quotas, kobj);
968 
969 	return sysfs_emit(buf, "%lu\n", quotas->ms);
970 }
971 
972 static ssize_t ms_store(struct kobject *kobj, struct kobj_attribute *attr,
973 		const char *buf, size_t count)
974 {
975 	struct damon_sysfs_quotas *quotas = container_of(kobj,
976 			struct damon_sysfs_quotas, kobj);
977 	int err = kstrtoul(buf, 0, &quotas->ms);
978 
979 	if (err)
980 		return -EINVAL;
981 	return count;
982 }
983 
984 static ssize_t bytes_show(struct kobject *kobj, struct kobj_attribute *attr,
985 		char *buf)
986 {
987 	struct damon_sysfs_quotas *quotas = container_of(kobj,
988 			struct damon_sysfs_quotas, kobj);
989 
990 	return sysfs_emit(buf, "%lu\n", quotas->sz);
991 }
992 
993 static ssize_t bytes_store(struct kobject *kobj,
994 		struct kobj_attribute *attr, const char *buf, size_t count)
995 {
996 	struct damon_sysfs_quotas *quotas = container_of(kobj,
997 			struct damon_sysfs_quotas, kobj);
998 	int err = kstrtoul(buf, 0, &quotas->sz);
999 
1000 	if (err)
1001 		return -EINVAL;
1002 	return count;
1003 }
1004 
1005 static ssize_t reset_interval_ms_show(struct kobject *kobj,
1006 		struct kobj_attribute *attr, char *buf)
1007 {
1008 	struct damon_sysfs_quotas *quotas = container_of(kobj,
1009 			struct damon_sysfs_quotas, kobj);
1010 
1011 	return sysfs_emit(buf, "%lu\n", quotas->reset_interval_ms);
1012 }
1013 
1014 static ssize_t reset_interval_ms_store(struct kobject *kobj,
1015 		struct kobj_attribute *attr, const char *buf, size_t count)
1016 {
1017 	struct damon_sysfs_quotas *quotas = container_of(kobj,
1018 			struct damon_sysfs_quotas, kobj);
1019 	int err = kstrtoul(buf, 0, &quotas->reset_interval_ms);
1020 
1021 	if (err)
1022 		return -EINVAL;
1023 	return count;
1024 }
1025 
1026 static void damon_sysfs_quotas_release(struct kobject *kobj)
1027 {
1028 	kfree(container_of(kobj, struct damon_sysfs_quotas, kobj));
1029 }
1030 
1031 static struct kobj_attribute damon_sysfs_quotas_ms_attr =
1032 		__ATTR_RW_MODE(ms, 0600);
1033 
1034 static struct kobj_attribute damon_sysfs_quotas_sz_attr =
1035 		__ATTR_RW_MODE(bytes, 0600);
1036 
1037 static struct kobj_attribute damon_sysfs_quotas_reset_interval_ms_attr =
1038 		__ATTR_RW_MODE(reset_interval_ms, 0600);
1039 
1040 static struct attribute *damon_sysfs_quotas_attrs[] = {
1041 	&damon_sysfs_quotas_ms_attr.attr,
1042 	&damon_sysfs_quotas_sz_attr.attr,
1043 	&damon_sysfs_quotas_reset_interval_ms_attr.attr,
1044 	NULL,
1045 };
1046 ATTRIBUTE_GROUPS(damon_sysfs_quotas);
1047 
1048 static const struct kobj_type damon_sysfs_quotas_ktype = {
1049 	.release = damon_sysfs_quotas_release,
1050 	.sysfs_ops = &kobj_sysfs_ops,
1051 	.default_groups = damon_sysfs_quotas_groups,
1052 };
1053 
1054 /*
1055  * access_pattern directory
1056  */
1057 
1058 struct damon_sysfs_access_pattern {
1059 	struct kobject kobj;
1060 	struct damon_sysfs_ul_range *sz;
1061 	struct damon_sysfs_ul_range *nr_accesses;
1062 	struct damon_sysfs_ul_range *age;
1063 };
1064 
1065 static
1066 struct damon_sysfs_access_pattern *damon_sysfs_access_pattern_alloc(void)
1067 {
1068 	struct damon_sysfs_access_pattern *access_pattern =
1069 		kmalloc(sizeof(*access_pattern), GFP_KERNEL);
1070 
1071 	if (!access_pattern)
1072 		return NULL;
1073 	access_pattern->kobj = (struct kobject){};
1074 	return access_pattern;
1075 }
1076 
1077 static int damon_sysfs_access_pattern_add_range_dir(
1078 		struct damon_sysfs_access_pattern *access_pattern,
1079 		struct damon_sysfs_ul_range **range_dir_ptr,
1080 		char *name)
1081 {
1082 	struct damon_sysfs_ul_range *range = damon_sysfs_ul_range_alloc(0, 0);
1083 	int err;
1084 
1085 	if (!range)
1086 		return -ENOMEM;
1087 	err = kobject_init_and_add(&range->kobj, &damon_sysfs_ul_range_ktype,
1088 			&access_pattern->kobj, name);
1089 	if (err)
1090 		kobject_put(&range->kobj);
1091 	else
1092 		*range_dir_ptr = range;
1093 	return err;
1094 }
1095 
1096 static int damon_sysfs_access_pattern_add_dirs(
1097 		struct damon_sysfs_access_pattern *access_pattern)
1098 {
1099 	int err;
1100 
1101 	err = damon_sysfs_access_pattern_add_range_dir(access_pattern,
1102 			&access_pattern->sz, "sz");
1103 	if (err)
1104 		goto put_sz_out;
1105 
1106 	err = damon_sysfs_access_pattern_add_range_dir(access_pattern,
1107 			&access_pattern->nr_accesses, "nr_accesses");
1108 	if (err)
1109 		goto put_nr_accesses_sz_out;
1110 
1111 	err = damon_sysfs_access_pattern_add_range_dir(access_pattern,
1112 			&access_pattern->age, "age");
1113 	if (err)
1114 		goto put_age_nr_accesses_sz_out;
1115 	return 0;
1116 
1117 put_age_nr_accesses_sz_out:
1118 	kobject_put(&access_pattern->age->kobj);
1119 	access_pattern->age = NULL;
1120 put_nr_accesses_sz_out:
1121 	kobject_put(&access_pattern->nr_accesses->kobj);
1122 	access_pattern->nr_accesses = NULL;
1123 put_sz_out:
1124 	kobject_put(&access_pattern->sz->kobj);
1125 	access_pattern->sz = NULL;
1126 	return err;
1127 }
1128 
1129 static void damon_sysfs_access_pattern_rm_dirs(
1130 		struct damon_sysfs_access_pattern *access_pattern)
1131 {
1132 	kobject_put(&access_pattern->sz->kobj);
1133 	kobject_put(&access_pattern->nr_accesses->kobj);
1134 	kobject_put(&access_pattern->age->kobj);
1135 }
1136 
1137 static void damon_sysfs_access_pattern_release(struct kobject *kobj)
1138 {
1139 	kfree(container_of(kobj, struct damon_sysfs_access_pattern, kobj));
1140 }
1141 
1142 static struct attribute *damon_sysfs_access_pattern_attrs[] = {
1143 	NULL,
1144 };
1145 ATTRIBUTE_GROUPS(damon_sysfs_access_pattern);
1146 
1147 static const struct kobj_type damon_sysfs_access_pattern_ktype = {
1148 	.release = damon_sysfs_access_pattern_release,
1149 	.sysfs_ops = &kobj_sysfs_ops,
1150 	.default_groups = damon_sysfs_access_pattern_groups,
1151 };
1152 
1153 /*
1154  * scheme directory
1155  */
1156 
1157 struct damon_sysfs_scheme {
1158 	struct kobject kobj;
1159 	enum damos_action action;
1160 	struct damon_sysfs_access_pattern *access_pattern;
1161 	unsigned long apply_interval_us;
1162 	struct damon_sysfs_quotas *quotas;
1163 	struct damon_sysfs_watermarks *watermarks;
1164 	struct damon_sysfs_scheme_filters *filters;
1165 	struct damon_sysfs_stats *stats;
1166 	struct damon_sysfs_scheme_regions *tried_regions;
1167 };
1168 
1169 /* This should match with enum damos_action */
1170 static const char * const damon_sysfs_damos_action_strs[] = {
1171 	"willneed",
1172 	"cold",
1173 	"pageout",
1174 	"hugepage",
1175 	"nohugepage",
1176 	"lru_prio",
1177 	"lru_deprio",
1178 	"stat",
1179 };
1180 
1181 static struct damon_sysfs_scheme *damon_sysfs_scheme_alloc(
1182 		enum damos_action action, unsigned long apply_interval_us)
1183 {
1184 	struct damon_sysfs_scheme *scheme = kmalloc(sizeof(*scheme),
1185 				GFP_KERNEL);
1186 
1187 	if (!scheme)
1188 		return NULL;
1189 	scheme->kobj = (struct kobject){};
1190 	scheme->action = action;
1191 	scheme->apply_interval_us = apply_interval_us;
1192 	return scheme;
1193 }
1194 
1195 static int damon_sysfs_scheme_set_access_pattern(
1196 		struct damon_sysfs_scheme *scheme)
1197 {
1198 	struct damon_sysfs_access_pattern *access_pattern;
1199 	int err;
1200 
1201 	access_pattern = damon_sysfs_access_pattern_alloc();
1202 	if (!access_pattern)
1203 		return -ENOMEM;
1204 	err = kobject_init_and_add(&access_pattern->kobj,
1205 			&damon_sysfs_access_pattern_ktype, &scheme->kobj,
1206 			"access_pattern");
1207 	if (err)
1208 		goto out;
1209 	err = damon_sysfs_access_pattern_add_dirs(access_pattern);
1210 	if (err)
1211 		goto out;
1212 	scheme->access_pattern = access_pattern;
1213 	return 0;
1214 
1215 out:
1216 	kobject_put(&access_pattern->kobj);
1217 	return err;
1218 }
1219 
1220 static int damon_sysfs_scheme_set_quotas(struct damon_sysfs_scheme *scheme)
1221 {
1222 	struct damon_sysfs_quotas *quotas = damon_sysfs_quotas_alloc();
1223 	int err;
1224 
1225 	if (!quotas)
1226 		return -ENOMEM;
1227 	err = kobject_init_and_add(&quotas->kobj, &damon_sysfs_quotas_ktype,
1228 			&scheme->kobj, "quotas");
1229 	if (err)
1230 		goto out;
1231 	err = damon_sysfs_quotas_add_dirs(quotas);
1232 	if (err)
1233 		goto out;
1234 	scheme->quotas = quotas;
1235 	return 0;
1236 
1237 out:
1238 	kobject_put(&quotas->kobj);
1239 	return err;
1240 }
1241 
1242 static int damon_sysfs_scheme_set_watermarks(struct damon_sysfs_scheme *scheme)
1243 {
1244 	struct damon_sysfs_watermarks *watermarks =
1245 		damon_sysfs_watermarks_alloc(DAMOS_WMARK_NONE, 0, 0, 0, 0);
1246 	int err;
1247 
1248 	if (!watermarks)
1249 		return -ENOMEM;
1250 	err = kobject_init_and_add(&watermarks->kobj,
1251 			&damon_sysfs_watermarks_ktype, &scheme->kobj,
1252 			"watermarks");
1253 	if (err)
1254 		kobject_put(&watermarks->kobj);
1255 	else
1256 		scheme->watermarks = watermarks;
1257 	return err;
1258 }
1259 
1260 static int damon_sysfs_scheme_set_filters(struct damon_sysfs_scheme *scheme)
1261 {
1262 	struct damon_sysfs_scheme_filters *filters =
1263 		damon_sysfs_scheme_filters_alloc();
1264 	int err;
1265 
1266 	if (!filters)
1267 		return -ENOMEM;
1268 	err = kobject_init_and_add(&filters->kobj,
1269 			&damon_sysfs_scheme_filters_ktype, &scheme->kobj,
1270 			"filters");
1271 	if (err)
1272 		kobject_put(&filters->kobj);
1273 	else
1274 		scheme->filters = filters;
1275 	return err;
1276 }
1277 
1278 static int damon_sysfs_scheme_set_stats(struct damon_sysfs_scheme *scheme)
1279 {
1280 	struct damon_sysfs_stats *stats = damon_sysfs_stats_alloc();
1281 	int err;
1282 
1283 	if (!stats)
1284 		return -ENOMEM;
1285 	err = kobject_init_and_add(&stats->kobj, &damon_sysfs_stats_ktype,
1286 			&scheme->kobj, "stats");
1287 	if (err)
1288 		kobject_put(&stats->kobj);
1289 	else
1290 		scheme->stats = stats;
1291 	return err;
1292 }
1293 
1294 static int damon_sysfs_scheme_set_tried_regions(
1295 		struct damon_sysfs_scheme *scheme)
1296 {
1297 	struct damon_sysfs_scheme_regions *tried_regions =
1298 		damon_sysfs_scheme_regions_alloc();
1299 	int err;
1300 
1301 	if (!tried_regions)
1302 		return -ENOMEM;
1303 	err = kobject_init_and_add(&tried_regions->kobj,
1304 			&damon_sysfs_scheme_regions_ktype, &scheme->kobj,
1305 			"tried_regions");
1306 	if (err)
1307 		kobject_put(&tried_regions->kobj);
1308 	else
1309 		scheme->tried_regions = tried_regions;
1310 	return err;
1311 }
1312 
1313 static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme)
1314 {
1315 	int err;
1316 
1317 	err = damon_sysfs_scheme_set_access_pattern(scheme);
1318 	if (err)
1319 		return err;
1320 	err = damon_sysfs_scheme_set_quotas(scheme);
1321 	if (err)
1322 		goto put_access_pattern_out;
1323 	err = damon_sysfs_scheme_set_watermarks(scheme);
1324 	if (err)
1325 		goto put_quotas_access_pattern_out;
1326 	err = damon_sysfs_scheme_set_filters(scheme);
1327 	if (err)
1328 		goto put_watermarks_quotas_access_pattern_out;
1329 	err = damon_sysfs_scheme_set_stats(scheme);
1330 	if (err)
1331 		goto put_filters_watermarks_quotas_access_pattern_out;
1332 	err = damon_sysfs_scheme_set_tried_regions(scheme);
1333 	if (err)
1334 		goto put_tried_regions_out;
1335 	return 0;
1336 
1337 put_tried_regions_out:
1338 	kobject_put(&scheme->tried_regions->kobj);
1339 	scheme->tried_regions = NULL;
1340 put_filters_watermarks_quotas_access_pattern_out:
1341 	kobject_put(&scheme->filters->kobj);
1342 	scheme->filters = NULL;
1343 put_watermarks_quotas_access_pattern_out:
1344 	kobject_put(&scheme->watermarks->kobj);
1345 	scheme->watermarks = NULL;
1346 put_quotas_access_pattern_out:
1347 	kobject_put(&scheme->quotas->kobj);
1348 	scheme->quotas = NULL;
1349 put_access_pattern_out:
1350 	kobject_put(&scheme->access_pattern->kobj);
1351 	scheme->access_pattern = NULL;
1352 	return err;
1353 }
1354 
1355 static void damon_sysfs_scheme_rm_dirs(struct damon_sysfs_scheme *scheme)
1356 {
1357 	damon_sysfs_access_pattern_rm_dirs(scheme->access_pattern);
1358 	kobject_put(&scheme->access_pattern->kobj);
1359 	damon_sysfs_quotas_rm_dirs(scheme->quotas);
1360 	kobject_put(&scheme->quotas->kobj);
1361 	kobject_put(&scheme->watermarks->kobj);
1362 	damon_sysfs_scheme_filters_rm_dirs(scheme->filters);
1363 	kobject_put(&scheme->filters->kobj);
1364 	kobject_put(&scheme->stats->kobj);
1365 	damon_sysfs_scheme_regions_rm_dirs(scheme->tried_regions);
1366 	kobject_put(&scheme->tried_regions->kobj);
1367 }
1368 
1369 static ssize_t action_show(struct kobject *kobj, struct kobj_attribute *attr,
1370 		char *buf)
1371 {
1372 	struct damon_sysfs_scheme *scheme = container_of(kobj,
1373 			struct damon_sysfs_scheme, kobj);
1374 
1375 	return sysfs_emit(buf, "%s\n",
1376 			damon_sysfs_damos_action_strs[scheme->action]);
1377 }
1378 
1379 static ssize_t action_store(struct kobject *kobj, struct kobj_attribute *attr,
1380 		const char *buf, size_t count)
1381 {
1382 	struct damon_sysfs_scheme *scheme = container_of(kobj,
1383 			struct damon_sysfs_scheme, kobj);
1384 	enum damos_action action;
1385 
1386 	for (action = 0; action < NR_DAMOS_ACTIONS; action++) {
1387 		if (sysfs_streq(buf, damon_sysfs_damos_action_strs[action])) {
1388 			scheme->action = action;
1389 			return count;
1390 		}
1391 	}
1392 	return -EINVAL;
1393 }
1394 
1395 static ssize_t apply_interval_us_show(struct kobject *kobj,
1396 		struct kobj_attribute *attr, char *buf)
1397 {
1398 	struct damon_sysfs_scheme *scheme = container_of(kobj,
1399 			struct damon_sysfs_scheme, kobj);
1400 
1401 	return sysfs_emit(buf, "%lu\n", scheme->apply_interval_us);
1402 }
1403 
1404 static ssize_t apply_interval_us_store(struct kobject *kobj,
1405 		struct kobj_attribute *attr, const char *buf, size_t count)
1406 {
1407 	struct damon_sysfs_scheme *scheme = container_of(kobj,
1408 			struct damon_sysfs_scheme, kobj);
1409 	int err = kstrtoul(buf, 0, &scheme->apply_interval_us);
1410 
1411 	return err ? err : count;
1412 }
1413 
1414 static void damon_sysfs_scheme_release(struct kobject *kobj)
1415 {
1416 	kfree(container_of(kobj, struct damon_sysfs_scheme, kobj));
1417 }
1418 
1419 static struct kobj_attribute damon_sysfs_scheme_action_attr =
1420 		__ATTR_RW_MODE(action, 0600);
1421 
1422 static struct kobj_attribute damon_sysfs_scheme_apply_interval_us_attr =
1423 		__ATTR_RW_MODE(apply_interval_us, 0600);
1424 
1425 static struct attribute *damon_sysfs_scheme_attrs[] = {
1426 	&damon_sysfs_scheme_action_attr.attr,
1427 	&damon_sysfs_scheme_apply_interval_us_attr.attr,
1428 	NULL,
1429 };
1430 ATTRIBUTE_GROUPS(damon_sysfs_scheme);
1431 
1432 static const struct kobj_type damon_sysfs_scheme_ktype = {
1433 	.release = damon_sysfs_scheme_release,
1434 	.sysfs_ops = &kobj_sysfs_ops,
1435 	.default_groups = damon_sysfs_scheme_groups,
1436 };
1437 
1438 /*
1439  * schemes directory
1440  */
1441 
1442 struct damon_sysfs_schemes *damon_sysfs_schemes_alloc(void)
1443 {
1444 	return kzalloc(sizeof(struct damon_sysfs_schemes), GFP_KERNEL);
1445 }
1446 
1447 void damon_sysfs_schemes_rm_dirs(struct damon_sysfs_schemes *schemes)
1448 {
1449 	struct damon_sysfs_scheme **schemes_arr = schemes->schemes_arr;
1450 	int i;
1451 
1452 	for (i = 0; i < schemes->nr; i++) {
1453 		damon_sysfs_scheme_rm_dirs(schemes_arr[i]);
1454 		kobject_put(&schemes_arr[i]->kobj);
1455 	}
1456 	schemes->nr = 0;
1457 	kfree(schemes_arr);
1458 	schemes->schemes_arr = NULL;
1459 }
1460 
1461 static int damon_sysfs_schemes_add_dirs(struct damon_sysfs_schemes *schemes,
1462 		int nr_schemes)
1463 {
1464 	struct damon_sysfs_scheme **schemes_arr, *scheme;
1465 	int err, i;
1466 
1467 	damon_sysfs_schemes_rm_dirs(schemes);
1468 	if (!nr_schemes)
1469 		return 0;
1470 
1471 	schemes_arr = kmalloc_array(nr_schemes, sizeof(*schemes_arr),
1472 			GFP_KERNEL | __GFP_NOWARN);
1473 	if (!schemes_arr)
1474 		return -ENOMEM;
1475 	schemes->schemes_arr = schemes_arr;
1476 
1477 	for (i = 0; i < nr_schemes; i++) {
1478 		/*
1479 		 * apply_interval_us as 0 means same to aggregation interval
1480 		 * (same to before-apply_interval behavior)
1481 		 */
1482 		scheme = damon_sysfs_scheme_alloc(DAMOS_STAT, 0);
1483 		if (!scheme) {
1484 			damon_sysfs_schemes_rm_dirs(schemes);
1485 			return -ENOMEM;
1486 		}
1487 
1488 		err = kobject_init_and_add(&scheme->kobj,
1489 				&damon_sysfs_scheme_ktype, &schemes->kobj,
1490 				"%d", i);
1491 		if (err)
1492 			goto out;
1493 		err = damon_sysfs_scheme_add_dirs(scheme);
1494 		if (err)
1495 			goto out;
1496 
1497 		schemes_arr[i] = scheme;
1498 		schemes->nr++;
1499 	}
1500 	return 0;
1501 
1502 out:
1503 	damon_sysfs_schemes_rm_dirs(schemes);
1504 	kobject_put(&scheme->kobj);
1505 	return err;
1506 }
1507 
1508 static ssize_t nr_schemes_show(struct kobject *kobj,
1509 		struct kobj_attribute *attr, char *buf)
1510 {
1511 	struct damon_sysfs_schemes *schemes = container_of(kobj,
1512 			struct damon_sysfs_schemes, kobj);
1513 
1514 	return sysfs_emit(buf, "%d\n", schemes->nr);
1515 }
1516 
1517 static ssize_t nr_schemes_store(struct kobject *kobj,
1518 		struct kobj_attribute *attr, const char *buf, size_t count)
1519 {
1520 	struct damon_sysfs_schemes *schemes;
1521 	int nr, err = kstrtoint(buf, 0, &nr);
1522 
1523 	if (err)
1524 		return err;
1525 	if (nr < 0)
1526 		return -EINVAL;
1527 
1528 	schemes = container_of(kobj, struct damon_sysfs_schemes, kobj);
1529 
1530 	if (!mutex_trylock(&damon_sysfs_lock))
1531 		return -EBUSY;
1532 	err = damon_sysfs_schemes_add_dirs(schemes, nr);
1533 	mutex_unlock(&damon_sysfs_lock);
1534 	if (err)
1535 		return err;
1536 	return count;
1537 }
1538 
1539 static void damon_sysfs_schemes_release(struct kobject *kobj)
1540 {
1541 	kfree(container_of(kobj, struct damon_sysfs_schemes, kobj));
1542 }
1543 
1544 static struct kobj_attribute damon_sysfs_schemes_nr_attr =
1545 		__ATTR_RW_MODE(nr_schemes, 0600);
1546 
1547 static struct attribute *damon_sysfs_schemes_attrs[] = {
1548 	&damon_sysfs_schemes_nr_attr.attr,
1549 	NULL,
1550 };
1551 ATTRIBUTE_GROUPS(damon_sysfs_schemes);
1552 
1553 const struct kobj_type damon_sysfs_schemes_ktype = {
1554 	.release = damon_sysfs_schemes_release,
1555 	.sysfs_ops = &kobj_sysfs_ops,
1556 	.default_groups = damon_sysfs_schemes_groups,
1557 };
1558 
1559 static bool damon_sysfs_memcg_path_eq(struct mem_cgroup *memcg,
1560 		char *memcg_path_buf, char *path)
1561 {
1562 #ifdef CONFIG_MEMCG
1563 	cgroup_path(memcg->css.cgroup, memcg_path_buf, PATH_MAX);
1564 	if (sysfs_streq(memcg_path_buf, path))
1565 		return true;
1566 #endif /* CONFIG_MEMCG */
1567 	return false;
1568 }
1569 
1570 static int damon_sysfs_memcg_path_to_id(char *memcg_path, unsigned short *id)
1571 {
1572 	struct mem_cgroup *memcg;
1573 	char *path;
1574 	bool found = false;
1575 
1576 	if (!memcg_path)
1577 		return -EINVAL;
1578 
1579 	path = kmalloc(sizeof(*path) * PATH_MAX, GFP_KERNEL);
1580 	if (!path)
1581 		return -ENOMEM;
1582 
1583 	for (memcg = mem_cgroup_iter(NULL, NULL, NULL); memcg;
1584 			memcg = mem_cgroup_iter(NULL, memcg, NULL)) {
1585 		/* skip removed memcg */
1586 		if (!mem_cgroup_id(memcg))
1587 			continue;
1588 		if (damon_sysfs_memcg_path_eq(memcg, path, memcg_path)) {
1589 			*id = mem_cgroup_id(memcg);
1590 			found = true;
1591 			break;
1592 		}
1593 	}
1594 
1595 	kfree(path);
1596 	return found ? 0 : -EINVAL;
1597 }
1598 
1599 static int damon_sysfs_set_scheme_filters(struct damos *scheme,
1600 		struct damon_sysfs_scheme_filters *sysfs_filters)
1601 {
1602 	int i;
1603 	struct damos_filter *filter, *next;
1604 
1605 	damos_for_each_filter_safe(filter, next, scheme)
1606 		damos_destroy_filter(filter);
1607 
1608 	for (i = 0; i < sysfs_filters->nr; i++) {
1609 		struct damon_sysfs_scheme_filter *sysfs_filter =
1610 			sysfs_filters->filters_arr[i];
1611 		struct damos_filter *filter =
1612 			damos_new_filter(sysfs_filter->type,
1613 					sysfs_filter->matching);
1614 		int err;
1615 
1616 		if (!filter)
1617 			return -ENOMEM;
1618 		if (filter->type == DAMOS_FILTER_TYPE_MEMCG) {
1619 			err = damon_sysfs_memcg_path_to_id(
1620 					sysfs_filter->memcg_path,
1621 					&filter->memcg_id);
1622 			if (err) {
1623 				damos_destroy_filter(filter);
1624 				return err;
1625 			}
1626 		} else if (filter->type == DAMOS_FILTER_TYPE_ADDR) {
1627 			if (sysfs_filter->addr_range.end <
1628 					sysfs_filter->addr_range.start) {
1629 				damos_destroy_filter(filter);
1630 				return -EINVAL;
1631 			}
1632 			filter->addr_range = sysfs_filter->addr_range;
1633 		} else if (filter->type == DAMOS_FILTER_TYPE_TARGET) {
1634 			filter->target_idx = sysfs_filter->target_idx;
1635 		}
1636 
1637 		damos_add_filter(scheme, filter);
1638 	}
1639 	return 0;
1640 }
1641 
1642 static struct damos *damon_sysfs_mk_scheme(
1643 		struct damon_sysfs_scheme *sysfs_scheme)
1644 {
1645 	struct damon_sysfs_access_pattern *access_pattern =
1646 		sysfs_scheme->access_pattern;
1647 	struct damon_sysfs_quotas *sysfs_quotas = sysfs_scheme->quotas;
1648 	struct damon_sysfs_weights *sysfs_weights = sysfs_quotas->weights;
1649 	struct damon_sysfs_watermarks *sysfs_wmarks = sysfs_scheme->watermarks;
1650 	struct damon_sysfs_scheme_filters *sysfs_filters =
1651 		sysfs_scheme->filters;
1652 	struct damos *scheme;
1653 	int err;
1654 
1655 	struct damos_access_pattern pattern = {
1656 		.min_sz_region = access_pattern->sz->min,
1657 		.max_sz_region = access_pattern->sz->max,
1658 		.min_nr_accesses = access_pattern->nr_accesses->min,
1659 		.max_nr_accesses = access_pattern->nr_accesses->max,
1660 		.min_age_region = access_pattern->age->min,
1661 		.max_age_region = access_pattern->age->max,
1662 	};
1663 	struct damos_quota quota = {
1664 		.ms = sysfs_quotas->ms,
1665 		.sz = sysfs_quotas->sz,
1666 		.reset_interval = sysfs_quotas->reset_interval_ms,
1667 		.weight_sz = sysfs_weights->sz,
1668 		.weight_nr_accesses = sysfs_weights->nr_accesses,
1669 		.weight_age = sysfs_weights->age,
1670 	};
1671 	struct damos_watermarks wmarks = {
1672 		.metric = sysfs_wmarks->metric,
1673 		.interval = sysfs_wmarks->interval_us,
1674 		.high = sysfs_wmarks->high,
1675 		.mid = sysfs_wmarks->mid,
1676 		.low = sysfs_wmarks->low,
1677 	};
1678 
1679 	scheme = damon_new_scheme(&pattern, sysfs_scheme->action,
1680 			sysfs_scheme->apply_interval_us, &quota, &wmarks);
1681 	if (!scheme)
1682 		return NULL;
1683 
1684 	err = damon_sysfs_set_scheme_filters(scheme, sysfs_filters);
1685 	if (err) {
1686 		damon_destroy_scheme(scheme);
1687 		return NULL;
1688 	}
1689 	return scheme;
1690 }
1691 
1692 static void damon_sysfs_update_scheme(struct damos *scheme,
1693 		struct damon_sysfs_scheme *sysfs_scheme)
1694 {
1695 	struct damon_sysfs_access_pattern *access_pattern =
1696 		sysfs_scheme->access_pattern;
1697 	struct damon_sysfs_quotas *sysfs_quotas = sysfs_scheme->quotas;
1698 	struct damon_sysfs_weights *sysfs_weights = sysfs_quotas->weights;
1699 	struct damon_sysfs_watermarks *sysfs_wmarks = sysfs_scheme->watermarks;
1700 	int err;
1701 
1702 	scheme->pattern.min_sz_region = access_pattern->sz->min;
1703 	scheme->pattern.max_sz_region = access_pattern->sz->max;
1704 	scheme->pattern.min_nr_accesses = access_pattern->nr_accesses->min;
1705 	scheme->pattern.max_nr_accesses = access_pattern->nr_accesses->max;
1706 	scheme->pattern.min_age_region = access_pattern->age->min;
1707 	scheme->pattern.max_age_region = access_pattern->age->max;
1708 
1709 	scheme->action = sysfs_scheme->action;
1710 	scheme->apply_interval_us = sysfs_scheme->apply_interval_us;
1711 
1712 	scheme->quota.ms = sysfs_quotas->ms;
1713 	scheme->quota.sz = sysfs_quotas->sz;
1714 	scheme->quota.reset_interval = sysfs_quotas->reset_interval_ms;
1715 	scheme->quota.weight_sz = sysfs_weights->sz;
1716 	scheme->quota.weight_nr_accesses = sysfs_weights->nr_accesses;
1717 	scheme->quota.weight_age = sysfs_weights->age;
1718 
1719 	scheme->wmarks.metric = sysfs_wmarks->metric;
1720 	scheme->wmarks.interval = sysfs_wmarks->interval_us;
1721 	scheme->wmarks.high = sysfs_wmarks->high;
1722 	scheme->wmarks.mid = sysfs_wmarks->mid;
1723 	scheme->wmarks.low = sysfs_wmarks->low;
1724 
1725 	err = damon_sysfs_set_scheme_filters(scheme, sysfs_scheme->filters);
1726 	if (err)
1727 		damon_destroy_scheme(scheme);
1728 }
1729 
1730 int damon_sysfs_set_schemes(struct damon_ctx *ctx,
1731 		struct damon_sysfs_schemes *sysfs_schemes)
1732 {
1733 	struct damos *scheme, *next;
1734 	int i = 0;
1735 
1736 	damon_for_each_scheme_safe(scheme, next, ctx) {
1737 		if (i < sysfs_schemes->nr)
1738 			damon_sysfs_update_scheme(scheme,
1739 					sysfs_schemes->schemes_arr[i]);
1740 		else
1741 			damon_destroy_scheme(scheme);
1742 		i++;
1743 	}
1744 
1745 	for (; i < sysfs_schemes->nr; i++) {
1746 		struct damos *scheme, *next;
1747 
1748 		scheme = damon_sysfs_mk_scheme(sysfs_schemes->schemes_arr[i]);
1749 		if (!scheme) {
1750 			damon_for_each_scheme_safe(scheme, next, ctx)
1751 				damon_destroy_scheme(scheme);
1752 			return -ENOMEM;
1753 		}
1754 		damon_add_scheme(ctx, scheme);
1755 	}
1756 	return 0;
1757 }
1758 
1759 void damon_sysfs_schemes_update_stats(
1760 		struct damon_sysfs_schemes *sysfs_schemes,
1761 		struct damon_ctx *ctx)
1762 {
1763 	struct damos *scheme;
1764 	int schemes_idx = 0;
1765 
1766 	damon_for_each_scheme(scheme, ctx) {
1767 		struct damon_sysfs_stats *sysfs_stats;
1768 
1769 		/* user could have removed the scheme sysfs dir */
1770 		if (schemes_idx >= sysfs_schemes->nr)
1771 			break;
1772 
1773 		sysfs_stats = sysfs_schemes->schemes_arr[schemes_idx++]->stats;
1774 		sysfs_stats->nr_tried = scheme->stat.nr_tried;
1775 		sysfs_stats->sz_tried = scheme->stat.sz_tried;
1776 		sysfs_stats->nr_applied = scheme->stat.nr_applied;
1777 		sysfs_stats->sz_applied = scheme->stat.sz_applied;
1778 		sysfs_stats->qt_exceeds = scheme->stat.qt_exceeds;
1779 	}
1780 }
1781 
1782 /*
1783  * damon_sysfs_schemes that need to update its schemes regions dir.  Protected
1784  * by damon_sysfs_lock
1785  */
1786 static struct damon_sysfs_schemes *damon_sysfs_schemes_for_damos_callback;
1787 static int damon_sysfs_schemes_region_idx;
1788 static bool damos_regions_upd_total_bytes_only;
1789 
1790 /*
1791  * DAMON callback that called before damos apply.  While this callback is
1792  * registered, damon_sysfs_lock should be held to ensure the regions
1793  * directories exist.
1794  */
1795 static int damon_sysfs_before_damos_apply(struct damon_ctx *ctx,
1796 		struct damon_target *t, struct damon_region *r,
1797 		struct damos *s)
1798 {
1799 	struct damos *scheme;
1800 	struct damon_sysfs_scheme_regions *sysfs_regions;
1801 	struct damon_sysfs_scheme_region *region;
1802 	struct damon_sysfs_schemes *sysfs_schemes =
1803 		damon_sysfs_schemes_for_damos_callback;
1804 	int schemes_idx = 0;
1805 
1806 	damon_for_each_scheme(scheme, ctx) {
1807 		if (scheme == s)
1808 			break;
1809 		schemes_idx++;
1810 	}
1811 
1812 	/* user could have removed the scheme sysfs dir */
1813 	if (schemes_idx >= sysfs_schemes->nr)
1814 		return 0;
1815 
1816 	sysfs_regions = sysfs_schemes->schemes_arr[schemes_idx]->tried_regions;
1817 	if (sysfs_regions->upd_status == DAMOS_TRIED_REGIONS_UPD_FINISHED)
1818 		return 0;
1819 	if (sysfs_regions->upd_status == DAMOS_TRIED_REGIONS_UPD_IDLE)
1820 		sysfs_regions->upd_status = DAMOS_TRIED_REGIONS_UPD_STARTED;
1821 	sysfs_regions->total_bytes += r->ar.end - r->ar.start;
1822 	if (damos_regions_upd_total_bytes_only)
1823 		return 0;
1824 
1825 	region = damon_sysfs_scheme_region_alloc(r);
1826 	list_add_tail(&region->list, &sysfs_regions->regions_list);
1827 	sysfs_regions->nr_regions++;
1828 	if (kobject_init_and_add(&region->kobj,
1829 				&damon_sysfs_scheme_region_ktype,
1830 				&sysfs_regions->kobj, "%d",
1831 				damon_sysfs_schemes_region_idx++)) {
1832 		kobject_put(&region->kobj);
1833 	}
1834 	return 0;
1835 }
1836 
1837 /*
1838  * DAMON callback that called after each accesses sampling.  While this
1839  * callback is registered, damon_sysfs_lock should be held to ensure the
1840  * regions directories exist.
1841  */
1842 static int damon_sysfs_after_sampling(struct damon_ctx *ctx)
1843 {
1844 	struct damon_sysfs_schemes *sysfs_schemes =
1845 		damon_sysfs_schemes_for_damos_callback;
1846 	struct damon_sysfs_scheme_regions *sysfs_regions;
1847 	int i;
1848 
1849 	for (i = 0; i < sysfs_schemes->nr; i++) {
1850 		sysfs_regions = sysfs_schemes->schemes_arr[i]->tried_regions;
1851 		if (sysfs_regions->upd_status ==
1852 				DAMOS_TRIED_REGIONS_UPD_STARTED)
1853 			sysfs_regions->upd_status =
1854 				DAMOS_TRIED_REGIONS_UPD_FINISHED;
1855 	}
1856 
1857 	return 0;
1858 }
1859 
1860 /* Called from damon_sysfs_cmd_request_callback under damon_sysfs_lock */
1861 int damon_sysfs_schemes_clear_regions(
1862 		struct damon_sysfs_schemes *sysfs_schemes,
1863 		struct damon_ctx *ctx)
1864 {
1865 	struct damos *scheme;
1866 	int schemes_idx = 0;
1867 
1868 	damon_for_each_scheme(scheme, ctx) {
1869 		struct damon_sysfs_scheme *sysfs_scheme;
1870 
1871 		/* user could have removed the scheme sysfs dir */
1872 		if (schemes_idx >= sysfs_schemes->nr)
1873 			break;
1874 
1875 		sysfs_scheme = sysfs_schemes->schemes_arr[schemes_idx++];
1876 		damon_sysfs_scheme_regions_rm_dirs(
1877 				sysfs_scheme->tried_regions);
1878 		sysfs_scheme->tried_regions->total_bytes = 0;
1879 	}
1880 	return 0;
1881 }
1882 
1883 static void damos_tried_regions_init_upd_status(
1884 		struct damon_sysfs_schemes *sysfs_schemes)
1885 {
1886 	int i;
1887 
1888 	for (i = 0; i < sysfs_schemes->nr; i++)
1889 		sysfs_schemes->schemes_arr[i]->tried_regions->upd_status =
1890 			DAMOS_TRIED_REGIONS_UPD_IDLE;
1891 }
1892 
1893 /* Called from damon_sysfs_cmd_request_callback under damon_sysfs_lock */
1894 int damon_sysfs_schemes_update_regions_start(
1895 		struct damon_sysfs_schemes *sysfs_schemes,
1896 		struct damon_ctx *ctx, bool total_bytes_only)
1897 {
1898 	damon_sysfs_schemes_clear_regions(sysfs_schemes, ctx);
1899 	damon_sysfs_schemes_for_damos_callback = sysfs_schemes;
1900 	damos_tried_regions_init_upd_status(sysfs_schemes);
1901 	damos_regions_upd_total_bytes_only = total_bytes_only;
1902 	ctx->callback.before_damos_apply = damon_sysfs_before_damos_apply;
1903 	ctx->callback.after_sampling = damon_sysfs_after_sampling;
1904 	return 0;
1905 }
1906 
1907 bool damos_sysfs_regions_upd_done(void)
1908 {
1909 	struct damon_sysfs_schemes *sysfs_schemes =
1910 		damon_sysfs_schemes_for_damos_callback;
1911 	struct damon_sysfs_scheme_regions *sysfs_regions;
1912 	int i;
1913 
1914 	for (i = 0; i < sysfs_schemes->nr; i++) {
1915 		sysfs_regions = sysfs_schemes->schemes_arr[i]->tried_regions;
1916 		if (sysfs_regions->upd_status !=
1917 				DAMOS_TRIED_REGIONS_UPD_FINISHED)
1918 			return false;
1919 	}
1920 	return true;
1921 }
1922 
1923 /*
1924  * Called from damon_sysfs_cmd_request_callback under damon_sysfs_lock.  Caller
1925  * should unlock damon_sysfs_lock which held before
1926  * damon_sysfs_schemes_update_regions_start()
1927  */
1928 int damon_sysfs_schemes_update_regions_stop(struct damon_ctx *ctx)
1929 {
1930 	damon_sysfs_schemes_for_damos_callback = NULL;
1931 	ctx->callback.before_damos_apply = NULL;
1932 	ctx->callback.after_sampling = NULL;
1933 	damon_sysfs_schemes_region_idx = 0;
1934 	return 0;
1935 }
1936