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