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