xref: /linux/mm/damon/sysfs-schemes.c (revision e9a19cc85d4821a441f4b2d4756ae01e12f17393)
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 #include <linux/numa.h>
10 
11 #include "sysfs-common.h"
12 
13 /*
14  * scheme region directory
15  */
16 
17 struct damon_sysfs_scheme_region {
18 	struct kobject kobj;
19 	struct damon_addr_range ar;
20 	unsigned int nr_accesses;
21 	unsigned int age;
22 	unsigned long sz_filter_passed;
23 	struct list_head list;
24 };
25 
26 static struct damon_sysfs_scheme_region *damon_sysfs_scheme_region_alloc(
27 		struct damon_region *region)
28 {
29 	struct damon_sysfs_scheme_region *sysfs_region = kmalloc_obj(*sysfs_region);
30 
31 	if (!sysfs_region)
32 		return NULL;
33 	sysfs_region->kobj = (struct kobject){};
34 	sysfs_region->ar = region->ar;
35 	sysfs_region->nr_accesses = region->nr_accesses_bp / 10000;
36 	sysfs_region->age = region->age;
37 	INIT_LIST_HEAD(&sysfs_region->list);
38 	return sysfs_region;
39 }
40 
41 static ssize_t start_show(struct kobject *kobj, struct kobj_attribute *attr,
42 		char *buf)
43 {
44 	struct damon_sysfs_scheme_region *region = container_of(kobj,
45 			struct damon_sysfs_scheme_region, kobj);
46 
47 	return sysfs_emit(buf, "%lu\n", region->ar.start);
48 }
49 
50 static ssize_t end_show(struct kobject *kobj, struct kobj_attribute *attr,
51 		char *buf)
52 {
53 	struct damon_sysfs_scheme_region *region = container_of(kobj,
54 			struct damon_sysfs_scheme_region, kobj);
55 
56 	return sysfs_emit(buf, "%lu\n", region->ar.end);
57 }
58 
59 static ssize_t nr_accesses_show(struct kobject *kobj,
60 		struct kobj_attribute *attr, char *buf)
61 {
62 	struct damon_sysfs_scheme_region *region = container_of(kobj,
63 			struct damon_sysfs_scheme_region, kobj);
64 
65 	return sysfs_emit(buf, "%u\n", region->nr_accesses);
66 }
67 
68 static ssize_t age_show(struct kobject *kobj, struct kobj_attribute *attr,
69 		char *buf)
70 {
71 	struct damon_sysfs_scheme_region *region = container_of(kobj,
72 			struct damon_sysfs_scheme_region, kobj);
73 
74 	return sysfs_emit(buf, "%u\n", region->age);
75 }
76 
77 static ssize_t sz_filter_passed_show(struct kobject *kobj,
78 		struct kobj_attribute *attr, char *buf)
79 {
80 	struct damon_sysfs_scheme_region *region = container_of(kobj,
81 			struct damon_sysfs_scheme_region, kobj);
82 
83 	return sysfs_emit(buf, "%lu\n", region->sz_filter_passed);
84 }
85 
86 static void damon_sysfs_scheme_region_release(struct kobject *kobj)
87 {
88 	struct damon_sysfs_scheme_region *region = container_of(kobj,
89 			struct damon_sysfs_scheme_region, kobj);
90 
91 	list_del(&region->list);
92 	kfree(region);
93 }
94 
95 static struct kobj_attribute damon_sysfs_scheme_region_start_attr =
96 		__ATTR_RO_MODE(start, 0400);
97 
98 static struct kobj_attribute damon_sysfs_scheme_region_end_attr =
99 		__ATTR_RO_MODE(end, 0400);
100 
101 static struct kobj_attribute damon_sysfs_scheme_region_nr_accesses_attr =
102 		__ATTR_RO_MODE(nr_accesses, 0400);
103 
104 static struct kobj_attribute damon_sysfs_scheme_region_age_attr =
105 		__ATTR_RO_MODE(age, 0400);
106 
107 static struct kobj_attribute damon_sysfs_scheme_region_sz_filter_passed_attr =
108 		__ATTR_RO_MODE(sz_filter_passed, 0400);
109 
110 static struct attribute *damon_sysfs_scheme_region_attrs[] = {
111 	&damon_sysfs_scheme_region_start_attr.attr,
112 	&damon_sysfs_scheme_region_end_attr.attr,
113 	&damon_sysfs_scheme_region_nr_accesses_attr.attr,
114 	&damon_sysfs_scheme_region_age_attr.attr,
115 	&damon_sysfs_scheme_region_sz_filter_passed_attr.attr,
116 	NULL,
117 };
118 ATTRIBUTE_GROUPS(damon_sysfs_scheme_region);
119 
120 static const struct kobj_type damon_sysfs_scheme_region_ktype = {
121 	.release = damon_sysfs_scheme_region_release,
122 	.sysfs_ops = &kobj_sysfs_ops,
123 	.default_groups = damon_sysfs_scheme_region_groups,
124 };
125 
126 /*
127  * scheme regions directory
128  */
129 
130 struct damon_sysfs_scheme_regions {
131 	struct kobject kobj;
132 	struct list_head regions_list;
133 	int nr_regions;
134 	unsigned long total_bytes;
135 };
136 
137 static struct damon_sysfs_scheme_regions *
138 damon_sysfs_scheme_regions_alloc(void)
139 {
140 	struct damon_sysfs_scheme_regions *regions = kmalloc_obj(*regions);
141 
142 	if (!regions)
143 		return NULL;
144 
145 	regions->kobj = (struct kobject){};
146 	INIT_LIST_HEAD(&regions->regions_list);
147 	regions->nr_regions = 0;
148 	regions->total_bytes = 0;
149 	return regions;
150 }
151 
152 static ssize_t total_bytes_show(struct kobject *kobj,
153 		struct kobj_attribute *attr, char *buf)
154 {
155 	struct damon_sysfs_scheme_regions *regions = container_of(kobj,
156 			struct damon_sysfs_scheme_regions, kobj);
157 
158 	return sysfs_emit(buf, "%lu\n", regions->total_bytes);
159 }
160 
161 static void damon_sysfs_scheme_regions_rm_dirs(
162 		struct damon_sysfs_scheme_regions *regions)
163 {
164 	struct damon_sysfs_scheme_region *r, *next;
165 
166 	list_for_each_entry_safe(r, next, &regions->regions_list, list) {
167 		/* release function deletes it from the list */
168 		kobject_put(&r->kobj);
169 		regions->nr_regions--;
170 	}
171 }
172 
173 static void damon_sysfs_scheme_regions_release(struct kobject *kobj)
174 {
175 	kfree(container_of(kobj, struct damon_sysfs_scheme_regions, kobj));
176 }
177 
178 static struct kobj_attribute damon_sysfs_scheme_regions_total_bytes_attr =
179 		__ATTR_RO_MODE(total_bytes, 0400);
180 
181 static struct attribute *damon_sysfs_scheme_regions_attrs[] = {
182 	&damon_sysfs_scheme_regions_total_bytes_attr.attr,
183 	NULL,
184 };
185 ATTRIBUTE_GROUPS(damon_sysfs_scheme_regions);
186 
187 static const struct kobj_type damon_sysfs_scheme_regions_ktype = {
188 	.release = damon_sysfs_scheme_regions_release,
189 	.sysfs_ops = &kobj_sysfs_ops,
190 	.default_groups = damon_sysfs_scheme_regions_groups,
191 };
192 
193 /*
194  * schemes/stats directory
195  */
196 
197 struct damon_sysfs_stats {
198 	struct kobject kobj;
199 	unsigned long nr_tried;
200 	unsigned long sz_tried;
201 	unsigned long nr_applied;
202 	unsigned long sz_applied;
203 	unsigned long sz_ops_filter_passed;
204 	unsigned long qt_exceeds;
205 	unsigned long nr_snapshots;
206 	unsigned long max_nr_snapshots;
207 };
208 
209 static struct damon_sysfs_stats *damon_sysfs_stats_alloc(void)
210 {
211 	return kzalloc_obj(struct damon_sysfs_stats);
212 }
213 
214 static ssize_t nr_tried_show(struct kobject *kobj, struct kobj_attribute *attr,
215 		char *buf)
216 {
217 	struct damon_sysfs_stats *stats = container_of(kobj,
218 			struct damon_sysfs_stats, kobj);
219 
220 	return sysfs_emit(buf, "%lu\n", stats->nr_tried);
221 }
222 
223 static ssize_t sz_tried_show(struct kobject *kobj, struct kobj_attribute *attr,
224 		char *buf)
225 {
226 	struct damon_sysfs_stats *stats = container_of(kobj,
227 			struct damon_sysfs_stats, kobj);
228 
229 	return sysfs_emit(buf, "%lu\n", stats->sz_tried);
230 }
231 
232 static ssize_t nr_applied_show(struct kobject *kobj,
233 		struct kobj_attribute *attr, char *buf)
234 {
235 	struct damon_sysfs_stats *stats = container_of(kobj,
236 			struct damon_sysfs_stats, kobj);
237 
238 	return sysfs_emit(buf, "%lu\n", stats->nr_applied);
239 }
240 
241 static ssize_t sz_applied_show(struct kobject *kobj,
242 		struct kobj_attribute *attr, char *buf)
243 {
244 	struct damon_sysfs_stats *stats = container_of(kobj,
245 			struct damon_sysfs_stats, kobj);
246 
247 	return sysfs_emit(buf, "%lu\n", stats->sz_applied);
248 }
249 
250 static ssize_t sz_ops_filter_passed_show(struct kobject *kobj,
251 		struct kobj_attribute *attr, char *buf)
252 {
253 	struct damon_sysfs_stats *stats = container_of(kobj,
254 			struct damon_sysfs_stats, kobj);
255 
256 	return sysfs_emit(buf, "%lu\n", stats->sz_ops_filter_passed);
257 }
258 
259 static ssize_t qt_exceeds_show(struct kobject *kobj,
260 		struct kobj_attribute *attr, char *buf)
261 {
262 	struct damon_sysfs_stats *stats = container_of(kobj,
263 			struct damon_sysfs_stats, kobj);
264 
265 	return sysfs_emit(buf, "%lu\n", stats->qt_exceeds);
266 }
267 
268 static ssize_t nr_snapshots_show(struct kobject *kobj,
269 		struct kobj_attribute *attr, char *buf)
270 {
271 	struct damon_sysfs_stats *stats = container_of(kobj,
272 			struct damon_sysfs_stats, kobj);
273 
274 	return sysfs_emit(buf, "%lu\n", stats->nr_snapshots);
275 }
276 
277 static ssize_t max_nr_snapshots_show(struct kobject *kobj,
278 		struct kobj_attribute *attr, char *buf)
279 {
280 	struct damon_sysfs_stats *stats = container_of(kobj,
281 			struct damon_sysfs_stats, kobj);
282 
283 	return sysfs_emit(buf, "%lu\n", stats->max_nr_snapshots);
284 }
285 
286 static ssize_t max_nr_snapshots_store(struct kobject *kobj,
287 		struct kobj_attribute *attr, const char *buf, size_t count)
288 {
289 	struct damon_sysfs_stats *stats = container_of(kobj,
290 			struct damon_sysfs_stats, kobj);
291 	unsigned long max_nr_snapshots, err = kstrtoul(buf, 0, &max_nr_snapshots);
292 
293 	if (err)
294 		return err;
295 	stats->max_nr_snapshots = max_nr_snapshots;
296 	return count;
297 }
298 
299 static void damon_sysfs_stats_release(struct kobject *kobj)
300 {
301 	kfree(container_of(kobj, struct damon_sysfs_stats, kobj));
302 }
303 
304 static struct kobj_attribute damon_sysfs_stats_nr_tried_attr =
305 		__ATTR_RO_MODE(nr_tried, 0400);
306 
307 static struct kobj_attribute damon_sysfs_stats_sz_tried_attr =
308 		__ATTR_RO_MODE(sz_tried, 0400);
309 
310 static struct kobj_attribute damon_sysfs_stats_nr_applied_attr =
311 		__ATTR_RO_MODE(nr_applied, 0400);
312 
313 static struct kobj_attribute damon_sysfs_stats_sz_applied_attr =
314 		__ATTR_RO_MODE(sz_applied, 0400);
315 
316 static struct kobj_attribute damon_sysfs_stats_sz_ops_filter_passed_attr =
317 		__ATTR_RO_MODE(sz_ops_filter_passed, 0400);
318 
319 static struct kobj_attribute damon_sysfs_stats_qt_exceeds_attr =
320 		__ATTR_RO_MODE(qt_exceeds, 0400);
321 
322 static struct kobj_attribute damon_sysfs_stats_nr_snapshots_attr =
323 		__ATTR_RO_MODE(nr_snapshots, 0400);
324 
325 static struct kobj_attribute damon_sysfs_stats_max_nr_snapshots_attr =
326 		__ATTR_RW_MODE(max_nr_snapshots, 0600);
327 
328 static struct attribute *damon_sysfs_stats_attrs[] = {
329 	&damon_sysfs_stats_nr_tried_attr.attr,
330 	&damon_sysfs_stats_sz_tried_attr.attr,
331 	&damon_sysfs_stats_nr_applied_attr.attr,
332 	&damon_sysfs_stats_sz_applied_attr.attr,
333 	&damon_sysfs_stats_sz_ops_filter_passed_attr.attr,
334 	&damon_sysfs_stats_qt_exceeds_attr.attr,
335 	&damon_sysfs_stats_nr_snapshots_attr.attr,
336 	&damon_sysfs_stats_max_nr_snapshots_attr.attr,
337 	NULL,
338 };
339 ATTRIBUTE_GROUPS(damon_sysfs_stats);
340 
341 static const struct kobj_type damon_sysfs_stats_ktype = {
342 	.release = damon_sysfs_stats_release,
343 	.sysfs_ops = &kobj_sysfs_ops,
344 	.default_groups = damon_sysfs_stats_groups,
345 };
346 
347 /*
348  * filter directory
349  */
350 
351 /*
352  * enum damos_sysfs_filter_handle_layer - Layers handling filters of a dir.
353  */
354 enum damos_sysfs_filter_handle_layer {
355 	DAMOS_SYSFS_FILTER_HANDLE_LAYER_CORE,
356 	DAMOS_SYSFS_FILTER_HANDLE_LAYER_OPS,
357 	DAMOS_SYSFS_FILTER_HANDLE_LAYER_BOTH,
358 };
359 
360 struct damon_sysfs_scheme_filter {
361 	struct kobject kobj;
362 	enum damos_sysfs_filter_handle_layer handle_layer;
363 	enum damos_filter_type type;
364 	bool matching;
365 	bool allow;
366 	char *memcg_path;
367 	struct damon_addr_range addr_range;
368 	struct damon_size_range sz_range;
369 	int target_idx;
370 };
371 
372 static struct damon_sysfs_scheme_filter *damon_sysfs_scheme_filter_alloc(
373 		enum damos_sysfs_filter_handle_layer layer)
374 {
375 	struct damon_sysfs_scheme_filter *filter;
376 
377 	filter = kzalloc_obj(struct damon_sysfs_scheme_filter);
378 	if (filter)
379 		filter->handle_layer = layer;
380 	return filter;
381 }
382 
383 struct damos_sysfs_filter_type_name {
384 	enum damos_filter_type type;
385 	char *name;
386 };
387 
388 static const struct damos_sysfs_filter_type_name
389 damos_sysfs_filter_type_names[] = {
390 	{
391 		.type = DAMOS_FILTER_TYPE_ANON,
392 		.name = "anon",
393 	},
394 	{
395 		.type = DAMOS_FILTER_TYPE_ACTIVE,
396 		.name = "active",
397 	},
398 	{
399 		.type = DAMOS_FILTER_TYPE_MEMCG,
400 		.name = "memcg",
401 	},
402 	{
403 		.type = DAMOS_FILTER_TYPE_YOUNG,
404 		.name = "young",
405 	},
406 	{
407 		.type = DAMOS_FILTER_TYPE_HUGEPAGE_SIZE,
408 		.name = "hugepage_size",
409 	},
410 	{
411 		.type = DAMOS_FILTER_TYPE_UNMAPPED,
412 		.name = "unmapped",
413 	},
414 	{
415 		.type = DAMOS_FILTER_TYPE_ADDR,
416 		.name = "addr",
417 	},
418 	{
419 		.type = DAMOS_FILTER_TYPE_TARGET,
420 		.name = "target",
421 	},
422 };
423 
424 static ssize_t type_show(struct kobject *kobj,
425 		struct kobj_attribute *attr, char *buf)
426 {
427 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
428 			struct damon_sysfs_scheme_filter, kobj);
429 	int i;
430 
431 	for (i = 0; i < ARRAY_SIZE(damos_sysfs_filter_type_names); i++) {
432 		const struct damos_sysfs_filter_type_name *type_name;
433 
434 		type_name = &damos_sysfs_filter_type_names[i];
435 		if (type_name->type == filter->type)
436 			return sysfs_emit(buf, "%s\n", type_name->name);
437 	}
438 	return -EINVAL;
439 }
440 
441 static bool damos_sysfs_scheme_filter_valid_type(
442 		enum damos_sysfs_filter_handle_layer layer,
443 		enum damos_filter_type type)
444 {
445 	switch (layer) {
446 	case DAMOS_SYSFS_FILTER_HANDLE_LAYER_BOTH:
447 		return true;
448 	case DAMOS_SYSFS_FILTER_HANDLE_LAYER_CORE:
449 		return !damos_filter_for_ops(type);
450 	case DAMOS_SYSFS_FILTER_HANDLE_LAYER_OPS:
451 		return damos_filter_for_ops(type);
452 	default:
453 		break;
454 	}
455 	return false;
456 }
457 
458 static ssize_t type_store(struct kobject *kobj,
459 		struct kobj_attribute *attr, const char *buf, size_t count)
460 {
461 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
462 			struct damon_sysfs_scheme_filter, kobj);
463 	ssize_t ret = -EINVAL;
464 	int i;
465 
466 	for (i = 0; i < ARRAY_SIZE(damos_sysfs_filter_type_names); i++) {
467 		const struct damos_sysfs_filter_type_name *type_name;
468 
469 		type_name = &damos_sysfs_filter_type_names[i];
470 		if (sysfs_streq(buf, type_name->name)) {
471 			if (!damos_sysfs_scheme_filter_valid_type(
472 						filter->handle_layer,
473 						type_name->type))
474 				break;
475 			filter->type = type_name->type;
476 			ret = count;
477 			break;
478 		}
479 	}
480 	return ret;
481 }
482 
483 static ssize_t matching_show(struct kobject *kobj,
484 		struct kobj_attribute *attr, char *buf)
485 {
486 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
487 			struct damon_sysfs_scheme_filter, kobj);
488 
489 	return sysfs_emit(buf, "%c\n", filter->matching ? 'Y' : 'N');
490 }
491 
492 static ssize_t matching_store(struct kobject *kobj,
493 		struct kobj_attribute *attr, const char *buf, size_t count)
494 {
495 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
496 			struct damon_sysfs_scheme_filter, kobj);
497 	bool matching;
498 	int err = kstrtobool(buf, &matching);
499 
500 	if (err)
501 		return err;
502 
503 	filter->matching = matching;
504 	return count;
505 }
506 
507 static ssize_t allow_show(struct kobject *kobj,
508 		struct kobj_attribute *attr, char *buf)
509 {
510 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
511 			struct damon_sysfs_scheme_filter, kobj);
512 
513 	return sysfs_emit(buf, "%c\n", filter->allow ? 'Y' : 'N');
514 }
515 
516 static ssize_t allow_store(struct kobject *kobj,
517 		struct kobj_attribute *attr, const char *buf, size_t count)
518 {
519 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
520 			struct damon_sysfs_scheme_filter, kobj);
521 	bool allow;
522 	int err = kstrtobool(buf, &allow);
523 
524 	if (err)
525 		return err;
526 
527 	filter->allow = allow;
528 	return count;
529 }
530 
531 static ssize_t memcg_path_show(struct kobject *kobj,
532 		struct kobj_attribute *attr, char *buf)
533 {
534 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
535 			struct damon_sysfs_scheme_filter, kobj);
536 
537 	return sysfs_emit(buf, "%s\n",
538 			filter->memcg_path ? filter->memcg_path : "");
539 }
540 
541 static ssize_t memcg_path_store(struct kobject *kobj,
542 		struct kobj_attribute *attr, const char *buf, size_t count)
543 {
544 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
545 			struct damon_sysfs_scheme_filter, kobj);
546 	char *path = kmalloc_array(size_add(count, 1), sizeof(*path),
547 				   GFP_KERNEL);
548 
549 	if (!path)
550 		return -ENOMEM;
551 
552 	strscpy(path, buf, count + 1);
553 	kfree(filter->memcg_path);
554 	filter->memcg_path = path;
555 	return count;
556 }
557 
558 static ssize_t addr_start_show(struct kobject *kobj,
559 		struct kobj_attribute *attr, char *buf)
560 {
561 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
562 			struct damon_sysfs_scheme_filter, kobj);
563 
564 	return sysfs_emit(buf, "%lu\n", filter->addr_range.start);
565 }
566 
567 static ssize_t addr_start_store(struct kobject *kobj,
568 		struct kobj_attribute *attr, const char *buf, size_t count)
569 {
570 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
571 			struct damon_sysfs_scheme_filter, kobj);
572 	int err = kstrtoul(buf, 0, &filter->addr_range.start);
573 
574 	return err ? err : count;
575 }
576 
577 static ssize_t addr_end_show(struct kobject *kobj,
578 		struct kobj_attribute *attr, char *buf)
579 {
580 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
581 			struct damon_sysfs_scheme_filter, kobj);
582 
583 	return sysfs_emit(buf, "%lu\n", filter->addr_range.end);
584 }
585 
586 static ssize_t addr_end_store(struct kobject *kobj,
587 		struct kobj_attribute *attr, const char *buf, size_t count)
588 {
589 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
590 			struct damon_sysfs_scheme_filter, kobj);
591 	int err = kstrtoul(buf, 0, &filter->addr_range.end);
592 
593 	return err ? err : count;
594 }
595 
596 static ssize_t min_show(struct kobject *kobj,
597 		struct kobj_attribute *attr, char *buf)
598 {
599 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
600 			struct damon_sysfs_scheme_filter, kobj);
601 
602 	return sysfs_emit(buf, "%lu\n", filter->sz_range.min);
603 }
604 
605 static ssize_t min_store(struct kobject *kobj,
606 		struct kobj_attribute *attr, const char *buf, size_t count)
607 {
608 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
609 			struct damon_sysfs_scheme_filter, kobj);
610 	int err = kstrtoul(buf, 0, &filter->sz_range.min);
611 
612 	return err ? err : count;
613 }
614 
615 static ssize_t max_show(struct kobject *kobj,
616 		struct kobj_attribute *attr, char *buf)
617 {
618 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
619 			struct damon_sysfs_scheme_filter, kobj);
620 
621 	return sysfs_emit(buf, "%lu\n", filter->sz_range.max);
622 }
623 
624 static ssize_t max_store(struct kobject *kobj,
625 		struct kobj_attribute *attr, const char *buf, size_t count)
626 {
627 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
628 			struct damon_sysfs_scheme_filter, kobj);
629 	int err = kstrtoul(buf, 0, &filter->sz_range.max);
630 
631 	return err ? err : count;
632 }
633 
634 static ssize_t damon_target_idx_show(struct kobject *kobj,
635 		struct kobj_attribute *attr, char *buf)
636 {
637 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
638 			struct damon_sysfs_scheme_filter, kobj);
639 
640 	return sysfs_emit(buf, "%d\n", filter->target_idx);
641 }
642 
643 static ssize_t damon_target_idx_store(struct kobject *kobj,
644 		struct kobj_attribute *attr, const char *buf, size_t count)
645 {
646 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
647 			struct damon_sysfs_scheme_filter, kobj);
648 	int err = kstrtoint(buf, 0, &filter->target_idx);
649 
650 	return err ? err : count;
651 }
652 
653 static void damon_sysfs_scheme_filter_release(struct kobject *kobj)
654 {
655 	struct damon_sysfs_scheme_filter *filter = container_of(kobj,
656 			struct damon_sysfs_scheme_filter, kobj);
657 
658 	kfree(filter->memcg_path);
659 	kfree(filter);
660 }
661 
662 static struct kobj_attribute damon_sysfs_scheme_filter_type_attr =
663 		__ATTR_RW_MODE(type, 0600);
664 
665 static struct kobj_attribute damon_sysfs_scheme_filter_matching_attr =
666 		__ATTR_RW_MODE(matching, 0600);
667 
668 static struct kobj_attribute damon_sysfs_scheme_filter_allow_attr =
669 		__ATTR_RW_MODE(allow, 0600);
670 
671 static struct kobj_attribute damon_sysfs_scheme_filter_memcg_path_attr =
672 		__ATTR_RW_MODE(memcg_path, 0600);
673 
674 static struct kobj_attribute damon_sysfs_scheme_filter_addr_start_attr =
675 		__ATTR_RW_MODE(addr_start, 0600);
676 
677 static struct kobj_attribute damon_sysfs_scheme_filter_addr_end_attr =
678 		__ATTR_RW_MODE(addr_end, 0600);
679 
680 static struct kobj_attribute damon_sysfs_scheme_filter_min_attr =
681 		__ATTR_RW_MODE(min, 0600);
682 
683 static struct kobj_attribute damon_sysfs_scheme_filter_max_attr =
684 		__ATTR_RW_MODE(max, 0600);
685 
686 static struct kobj_attribute damon_sysfs_scheme_filter_damon_target_idx_attr =
687 		__ATTR_RW_MODE(damon_target_idx, 0600);
688 
689 static struct attribute *damon_sysfs_scheme_filter_attrs[] = {
690 	&damon_sysfs_scheme_filter_type_attr.attr,
691 	&damon_sysfs_scheme_filter_matching_attr.attr,
692 	&damon_sysfs_scheme_filter_allow_attr.attr,
693 	&damon_sysfs_scheme_filter_memcg_path_attr.attr,
694 	&damon_sysfs_scheme_filter_addr_start_attr.attr,
695 	&damon_sysfs_scheme_filter_addr_end_attr.attr,
696 	&damon_sysfs_scheme_filter_min_attr.attr,
697 	&damon_sysfs_scheme_filter_max_attr.attr,
698 	&damon_sysfs_scheme_filter_damon_target_idx_attr.attr,
699 	NULL,
700 };
701 ATTRIBUTE_GROUPS(damon_sysfs_scheme_filter);
702 
703 static const struct kobj_type damon_sysfs_scheme_filter_ktype = {
704 	.release = damon_sysfs_scheme_filter_release,
705 	.sysfs_ops = &kobj_sysfs_ops,
706 	.default_groups = damon_sysfs_scheme_filter_groups,
707 };
708 
709 /*
710  * filters directory
711  */
712 
713 struct damon_sysfs_scheme_filters {
714 	struct kobject kobj;
715 	enum damos_sysfs_filter_handle_layer handle_layer;
716 	struct damon_sysfs_scheme_filter **filters_arr;
717 	int nr;
718 };
719 
720 static struct damon_sysfs_scheme_filters *
721 damon_sysfs_scheme_filters_alloc(enum damos_sysfs_filter_handle_layer layer)
722 {
723 	struct damon_sysfs_scheme_filters *filters;
724 
725 	filters = kzalloc_obj(struct damon_sysfs_scheme_filters);
726 	if (filters)
727 		filters->handle_layer = layer;
728 	return filters;
729 }
730 
731 static void damon_sysfs_scheme_filters_rm_dirs(
732 		struct damon_sysfs_scheme_filters *filters)
733 {
734 	struct damon_sysfs_scheme_filter **filters_arr = filters->filters_arr;
735 	int i;
736 
737 	for (i = 0; i < filters->nr; i++)
738 		kobject_put(&filters_arr[i]->kobj);
739 	filters->nr = 0;
740 	kfree(filters_arr);
741 	filters->filters_arr = NULL;
742 }
743 
744 static int damon_sysfs_scheme_filters_add_dirs(
745 		struct damon_sysfs_scheme_filters *filters, int nr_filters)
746 {
747 	struct damon_sysfs_scheme_filter **filters_arr, *filter;
748 	int err, i;
749 
750 	damon_sysfs_scheme_filters_rm_dirs(filters);
751 	if (!nr_filters)
752 		return 0;
753 
754 	filters_arr = kmalloc_objs(*filters_arr, nr_filters,
755 				   GFP_KERNEL | __GFP_NOWARN);
756 	if (!filters_arr)
757 		return -ENOMEM;
758 	filters->filters_arr = filters_arr;
759 
760 	for (i = 0; i < nr_filters; i++) {
761 		filter = damon_sysfs_scheme_filter_alloc(
762 				filters->handle_layer);
763 		if (!filter) {
764 			damon_sysfs_scheme_filters_rm_dirs(filters);
765 			return -ENOMEM;
766 		}
767 
768 		err = kobject_init_and_add(&filter->kobj,
769 				&damon_sysfs_scheme_filter_ktype,
770 				&filters->kobj, "%d", i);
771 		if (err) {
772 			kobject_put(&filter->kobj);
773 			damon_sysfs_scheme_filters_rm_dirs(filters);
774 			return err;
775 		}
776 
777 		filters_arr[i] = filter;
778 		filters->nr++;
779 	}
780 	return 0;
781 }
782 
783 static ssize_t nr_filters_show(struct kobject *kobj,
784 		struct kobj_attribute *attr, char *buf)
785 {
786 	struct damon_sysfs_scheme_filters *filters = container_of(kobj,
787 			struct damon_sysfs_scheme_filters, kobj);
788 
789 	return sysfs_emit(buf, "%d\n", filters->nr);
790 }
791 
792 static ssize_t nr_filters_store(struct kobject *kobj,
793 		struct kobj_attribute *attr, const char *buf, size_t count)
794 {
795 	struct damon_sysfs_scheme_filters *filters;
796 	int nr, err = kstrtoint(buf, 0, &nr);
797 
798 	if (err)
799 		return err;
800 	if (nr < 0)
801 		return -EINVAL;
802 
803 	filters = container_of(kobj, struct damon_sysfs_scheme_filters, kobj);
804 
805 	if (!mutex_trylock(&damon_sysfs_lock))
806 		return -EBUSY;
807 	err = damon_sysfs_scheme_filters_add_dirs(filters, nr);
808 	mutex_unlock(&damon_sysfs_lock);
809 	if (err)
810 		return err;
811 
812 	return count;
813 }
814 
815 static void damon_sysfs_scheme_filters_release(struct kobject *kobj)
816 {
817 	kfree(container_of(kobj, struct damon_sysfs_scheme_filters, kobj));
818 }
819 
820 static struct kobj_attribute damon_sysfs_scheme_filters_nr_attr =
821 		__ATTR_RW_MODE(nr_filters, 0600);
822 
823 static struct attribute *damon_sysfs_scheme_filters_attrs[] = {
824 	&damon_sysfs_scheme_filters_nr_attr.attr,
825 	NULL,
826 };
827 ATTRIBUTE_GROUPS(damon_sysfs_scheme_filters);
828 
829 static const struct kobj_type damon_sysfs_scheme_filters_ktype = {
830 	.release = damon_sysfs_scheme_filters_release,
831 	.sysfs_ops = &kobj_sysfs_ops,
832 	.default_groups = damon_sysfs_scheme_filters_groups,
833 };
834 
835 /*
836  * watermarks directory
837  */
838 
839 struct damon_sysfs_watermarks {
840 	struct kobject kobj;
841 	enum damos_wmark_metric metric;
842 	unsigned long interval_us;
843 	unsigned long high;
844 	unsigned long mid;
845 	unsigned long low;
846 };
847 
848 static struct damon_sysfs_watermarks *damon_sysfs_watermarks_alloc(
849 		enum damos_wmark_metric metric, unsigned long interval_us,
850 		unsigned long high, unsigned long mid, unsigned long low)
851 {
852 	struct damon_sysfs_watermarks *watermarks = kmalloc_obj(*watermarks);
853 
854 	if (!watermarks)
855 		return NULL;
856 	watermarks->kobj = (struct kobject){};
857 	watermarks->metric = metric;
858 	watermarks->interval_us = interval_us;
859 	watermarks->high = high;
860 	watermarks->mid = mid;
861 	watermarks->low = low;
862 	return watermarks;
863 }
864 
865 struct damos_sysfs_wmark_metric_name {
866 	enum damos_wmark_metric metric;
867 	char *name;
868 };
869 
870 static const struct damos_sysfs_wmark_metric_name
871 damos_sysfs_wmark_metric_names[] = {
872 	{
873 		.metric = DAMOS_WMARK_NONE,
874 		.name = "none",
875 	},
876 	{
877 		.metric = DAMOS_WMARK_FREE_MEM_RATE,
878 		.name = "free_mem_rate",
879 	},
880 };
881 
882 static ssize_t metric_show(struct kobject *kobj, struct kobj_attribute *attr,
883 		char *buf)
884 {
885 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
886 			struct damon_sysfs_watermarks, kobj);
887 	int i;
888 
889 	for (i = 0; i < ARRAY_SIZE(damos_sysfs_wmark_metric_names); i++) {
890 		const struct damos_sysfs_wmark_metric_name *metric_name;
891 
892 		metric_name = &damos_sysfs_wmark_metric_names[i];
893 		if (metric_name->metric == watermarks->metric)
894 			return sysfs_emit(buf, "%s\n", metric_name->name);
895 	}
896 	return -EINVAL;
897 }
898 
899 static ssize_t metric_store(struct kobject *kobj, struct kobj_attribute *attr,
900 		const char *buf, size_t count)
901 {
902 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
903 			struct damon_sysfs_watermarks, kobj);
904 	int i;
905 
906 	for (i = 0; i < ARRAY_SIZE(damos_sysfs_wmark_metric_names); i++) {
907 		const struct damos_sysfs_wmark_metric_name *metric_name;
908 
909 		metric_name = &damos_sysfs_wmark_metric_names[i];
910 		if (sysfs_streq(buf, metric_name->name)) {
911 			watermarks->metric = metric_name->metric;
912 			return count;
913 		}
914 	}
915 	return -EINVAL;
916 }
917 
918 static ssize_t interval_us_show(struct kobject *kobj,
919 		struct kobj_attribute *attr, char *buf)
920 {
921 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
922 			struct damon_sysfs_watermarks, kobj);
923 
924 	return sysfs_emit(buf, "%lu\n", watermarks->interval_us);
925 }
926 
927 static ssize_t interval_us_store(struct kobject *kobj,
928 		struct kobj_attribute *attr, const char *buf, size_t count)
929 {
930 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
931 			struct damon_sysfs_watermarks, kobj);
932 	int err = kstrtoul(buf, 0, &watermarks->interval_us);
933 
934 	return err ? err : count;
935 }
936 
937 static ssize_t high_show(struct kobject *kobj,
938 		struct kobj_attribute *attr, char *buf)
939 {
940 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
941 			struct damon_sysfs_watermarks, kobj);
942 
943 	return sysfs_emit(buf, "%lu\n", watermarks->high);
944 }
945 
946 static ssize_t high_store(struct kobject *kobj,
947 		struct kobj_attribute *attr, const char *buf, size_t count)
948 {
949 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
950 			struct damon_sysfs_watermarks, kobj);
951 	int err = kstrtoul(buf, 0, &watermarks->high);
952 
953 	return err ? err : count;
954 }
955 
956 static ssize_t mid_show(struct kobject *kobj,
957 		struct kobj_attribute *attr, char *buf)
958 {
959 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
960 			struct damon_sysfs_watermarks, kobj);
961 
962 	return sysfs_emit(buf, "%lu\n", watermarks->mid);
963 }
964 
965 static ssize_t mid_store(struct kobject *kobj,
966 		struct kobj_attribute *attr, const char *buf, size_t count)
967 {
968 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
969 			struct damon_sysfs_watermarks, kobj);
970 	int err = kstrtoul(buf, 0, &watermarks->mid);
971 
972 	return err ? err : count;
973 }
974 
975 static ssize_t low_show(struct kobject *kobj,
976 		struct kobj_attribute *attr, char *buf)
977 {
978 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
979 			struct damon_sysfs_watermarks, kobj);
980 
981 	return sysfs_emit(buf, "%lu\n", watermarks->low);
982 }
983 
984 static ssize_t low_store(struct kobject *kobj,
985 		struct kobj_attribute *attr, const char *buf, size_t count)
986 {
987 	struct damon_sysfs_watermarks *watermarks = container_of(kobj,
988 			struct damon_sysfs_watermarks, kobj);
989 	int err = kstrtoul(buf, 0, &watermarks->low);
990 
991 	return err ? err : count;
992 }
993 
994 static void damon_sysfs_watermarks_release(struct kobject *kobj)
995 {
996 	kfree(container_of(kobj, struct damon_sysfs_watermarks, kobj));
997 }
998 
999 static struct kobj_attribute damon_sysfs_watermarks_metric_attr =
1000 		__ATTR_RW_MODE(metric, 0600);
1001 
1002 static struct kobj_attribute damon_sysfs_watermarks_interval_us_attr =
1003 		__ATTR_RW_MODE(interval_us, 0600);
1004 
1005 static struct kobj_attribute damon_sysfs_watermarks_high_attr =
1006 		__ATTR_RW_MODE(high, 0600);
1007 
1008 static struct kobj_attribute damon_sysfs_watermarks_mid_attr =
1009 		__ATTR_RW_MODE(mid, 0600);
1010 
1011 static struct kobj_attribute damon_sysfs_watermarks_low_attr =
1012 		__ATTR_RW_MODE(low, 0600);
1013 
1014 static struct attribute *damon_sysfs_watermarks_attrs[] = {
1015 	&damon_sysfs_watermarks_metric_attr.attr,
1016 	&damon_sysfs_watermarks_interval_us_attr.attr,
1017 	&damon_sysfs_watermarks_high_attr.attr,
1018 	&damon_sysfs_watermarks_mid_attr.attr,
1019 	&damon_sysfs_watermarks_low_attr.attr,
1020 	NULL,
1021 };
1022 ATTRIBUTE_GROUPS(damon_sysfs_watermarks);
1023 
1024 static const struct kobj_type damon_sysfs_watermarks_ktype = {
1025 	.release = damon_sysfs_watermarks_release,
1026 	.sysfs_ops = &kobj_sysfs_ops,
1027 	.default_groups = damon_sysfs_watermarks_groups,
1028 };
1029 
1030 /*
1031  * quota goal directory
1032  */
1033 
1034 struct damos_sysfs_quota_goal {
1035 	struct kobject kobj;
1036 	enum damos_quota_goal_metric metric;
1037 	unsigned long target_value;
1038 	unsigned long current_value;
1039 	int nid;
1040 	char *path;
1041 };
1042 
1043 static struct damos_sysfs_quota_goal *damos_sysfs_quota_goal_alloc(void)
1044 {
1045 	return kzalloc_obj(struct damos_sysfs_quota_goal);
1046 }
1047 
1048 struct damos_sysfs_qgoal_metric_name {
1049 	enum damos_quota_goal_metric metric;
1050 	char *name;
1051 };
1052 
1053 static
1054 struct damos_sysfs_qgoal_metric_name damos_sysfs_qgoal_metric_names[] = {
1055 	{
1056 		.metric = DAMOS_QUOTA_USER_INPUT,
1057 		.name = "user_input",
1058 	},
1059 	{
1060 		.metric = DAMOS_QUOTA_SOME_MEM_PSI_US,
1061 		.name = "some_mem_psi_us",
1062 	},
1063 	{
1064 		.metric = DAMOS_QUOTA_NODE_MEM_USED_BP,
1065 		.name = "node_mem_used_bp",
1066 	},
1067 	{
1068 		.metric = DAMOS_QUOTA_NODE_MEM_FREE_BP,
1069 		.name = "node_mem_free_bp",
1070 	},
1071 	{
1072 		.metric = DAMOS_QUOTA_NODE_MEMCG_USED_BP,
1073 		.name = "node_memcg_used_bp",
1074 	},
1075 	{
1076 		.metric = DAMOS_QUOTA_NODE_MEMCG_FREE_BP,
1077 		.name = "node_memcg_free_bp",
1078 	},
1079 	{
1080 		.metric = DAMOS_QUOTA_ACTIVE_MEM_BP,
1081 		.name = "active_mem_bp",
1082 	},
1083 	{
1084 		.metric = DAMOS_QUOTA_INACTIVE_MEM_BP,
1085 		.name = "inactive_mem_bp",
1086 	},
1087 };
1088 
1089 static ssize_t target_metric_show(struct kobject *kobj,
1090 		struct kobj_attribute *attr, char *buf)
1091 {
1092 	struct damos_sysfs_quota_goal *goal = container_of(kobj,
1093 			struct damos_sysfs_quota_goal, kobj);
1094 	int i;
1095 
1096 	for (i = 0; i < ARRAY_SIZE(damos_sysfs_qgoal_metric_names); i++) {
1097 		struct damos_sysfs_qgoal_metric_name *metric_name;
1098 
1099 		metric_name = &damos_sysfs_qgoal_metric_names[i];
1100 		if (metric_name->metric == goal->metric)
1101 			return sysfs_emit(buf, "%s\n", metric_name->name);
1102 	}
1103 	return -EINVAL;
1104 }
1105 
1106 static ssize_t target_metric_store(struct kobject *kobj,
1107 		struct kobj_attribute *attr, const char *buf, size_t count)
1108 {
1109 	struct damos_sysfs_quota_goal *goal = container_of(kobj,
1110 			struct damos_sysfs_quota_goal, kobj);
1111 	int i;
1112 
1113 	for (i = 0; i < ARRAY_SIZE(damos_sysfs_qgoal_metric_names); i++) {
1114 		struct damos_sysfs_qgoal_metric_name *metric_name;
1115 
1116 		metric_name = &damos_sysfs_qgoal_metric_names[i];
1117 		if (sysfs_streq(buf, metric_name->name)) {
1118 			goal->metric = metric_name->metric;
1119 			return count;
1120 		}
1121 	}
1122 	return -EINVAL;
1123 }
1124 
1125 static ssize_t target_value_show(struct kobject *kobj,
1126 		struct kobj_attribute *attr, char *buf)
1127 {
1128 	struct damos_sysfs_quota_goal *goal = container_of(kobj, struct
1129 			damos_sysfs_quota_goal, kobj);
1130 
1131 	return sysfs_emit(buf, "%lu\n", goal->target_value);
1132 }
1133 
1134 static ssize_t target_value_store(struct kobject *kobj,
1135 		struct kobj_attribute *attr, const char *buf, size_t count)
1136 {
1137 	struct damos_sysfs_quota_goal *goal = container_of(kobj, struct
1138 			damos_sysfs_quota_goal, kobj);
1139 	int err = kstrtoul(buf, 0, &goal->target_value);
1140 
1141 	return err ? err : count;
1142 }
1143 
1144 static ssize_t current_value_show(struct kobject *kobj,
1145 		struct kobj_attribute *attr, char *buf)
1146 {
1147 	struct damos_sysfs_quota_goal *goal = container_of(kobj, struct
1148 			damos_sysfs_quota_goal, kobj);
1149 
1150 	return sysfs_emit(buf, "%lu\n", goal->current_value);
1151 }
1152 
1153 static ssize_t current_value_store(struct kobject *kobj,
1154 		struct kobj_attribute *attr, const char *buf, size_t count)
1155 {
1156 	struct damos_sysfs_quota_goal *goal = container_of(kobj, struct
1157 			damos_sysfs_quota_goal, kobj);
1158 	int err = kstrtoul(buf, 0, &goal->current_value);
1159 
1160 	/* feed callback should check existence of this file and read value */
1161 	return err ? err : count;
1162 }
1163 
1164 static ssize_t nid_show(struct kobject *kobj,
1165 		struct kobj_attribute *attr, char *buf)
1166 {
1167 	struct damos_sysfs_quota_goal *goal = container_of(kobj, struct
1168 			damos_sysfs_quota_goal, kobj);
1169 
1170 
1171 	return sysfs_emit(buf, "%d\n", goal->nid);
1172 }
1173 
1174 static ssize_t nid_store(struct kobject *kobj,
1175 		struct kobj_attribute *attr, const char *buf, size_t count)
1176 {
1177 	struct damos_sysfs_quota_goal *goal = container_of(kobj, struct
1178 			damos_sysfs_quota_goal, kobj);
1179 	int err = kstrtoint(buf, 0, &goal->nid);
1180 
1181 	/* feed callback should check existence of this file and read value */
1182 	return err ? err : count;
1183 }
1184 
1185 static ssize_t path_show(struct kobject *kobj,
1186 		struct kobj_attribute *attr, char *buf)
1187 {
1188 	struct damos_sysfs_quota_goal *goal = container_of(kobj,
1189 			struct damos_sysfs_quota_goal, kobj);
1190 
1191 	return sysfs_emit(buf, "%s\n", goal->path ? goal->path : "");
1192 }
1193 
1194 static ssize_t path_store(struct kobject *kobj,
1195 		struct kobj_attribute *attr, const char *buf, size_t count)
1196 {
1197 	struct damos_sysfs_quota_goal *goal = container_of(kobj,
1198 			struct damos_sysfs_quota_goal, kobj);
1199 	char *path = kmalloc_array(size_add(count, 1), sizeof(*path),
1200 				   GFP_KERNEL);
1201 
1202 	if (!path)
1203 		return -ENOMEM;
1204 
1205 	strscpy(path, buf, count + 1);
1206 	kfree(goal->path);
1207 	goal->path = path;
1208 	return count;
1209 }
1210 
1211 static void damos_sysfs_quota_goal_release(struct kobject *kobj)
1212 {
1213 	struct damos_sysfs_quota_goal *goal = container_of(kobj,
1214 			struct damos_sysfs_quota_goal, kobj);
1215 
1216 	kfree(goal->path);
1217 	kfree(goal);
1218 }
1219 
1220 static struct kobj_attribute damos_sysfs_quota_goal_target_metric_attr =
1221 		__ATTR_RW_MODE(target_metric, 0600);
1222 
1223 static struct kobj_attribute damos_sysfs_quota_goal_target_value_attr =
1224 		__ATTR_RW_MODE(target_value, 0600);
1225 
1226 static struct kobj_attribute damos_sysfs_quota_goal_current_value_attr =
1227 		__ATTR_RW_MODE(current_value, 0600);
1228 
1229 static struct kobj_attribute damos_sysfs_quota_goal_nid_attr =
1230 		__ATTR_RW_MODE(nid, 0600);
1231 
1232 static struct kobj_attribute damos_sysfs_quota_goal_path_attr =
1233 		__ATTR_RW_MODE(path, 0600);
1234 
1235 static struct attribute *damos_sysfs_quota_goal_attrs[] = {
1236 	&damos_sysfs_quota_goal_target_metric_attr.attr,
1237 	&damos_sysfs_quota_goal_target_value_attr.attr,
1238 	&damos_sysfs_quota_goal_current_value_attr.attr,
1239 	&damos_sysfs_quota_goal_nid_attr.attr,
1240 	&damos_sysfs_quota_goal_path_attr.attr,
1241 	NULL,
1242 };
1243 ATTRIBUTE_GROUPS(damos_sysfs_quota_goal);
1244 
1245 static const struct kobj_type damos_sysfs_quota_goal_ktype = {
1246 	.release = damos_sysfs_quota_goal_release,
1247 	.sysfs_ops = &kobj_sysfs_ops,
1248 	.default_groups = damos_sysfs_quota_goal_groups,
1249 };
1250 
1251 /*
1252  * quota goals directory
1253  */
1254 
1255 struct damos_sysfs_quota_goals {
1256 	struct kobject kobj;
1257 	struct damos_sysfs_quota_goal **goals_arr;	/* counted by nr */
1258 	int nr;
1259 };
1260 
1261 static struct damos_sysfs_quota_goals *damos_sysfs_quota_goals_alloc(void)
1262 {
1263 	return kzalloc_obj(struct damos_sysfs_quota_goals);
1264 }
1265 
1266 static void damos_sysfs_quota_goals_rm_dirs(
1267 		struct damos_sysfs_quota_goals *goals)
1268 {
1269 	struct damos_sysfs_quota_goal **goals_arr = goals->goals_arr;
1270 	int i;
1271 
1272 	for (i = 0; i < goals->nr; i++)
1273 		kobject_put(&goals_arr[i]->kobj);
1274 	goals->nr = 0;
1275 	kfree(goals_arr);
1276 	goals->goals_arr = NULL;
1277 }
1278 
1279 static int damos_sysfs_quota_goals_add_dirs(
1280 		struct damos_sysfs_quota_goals *goals, int nr_goals)
1281 {
1282 	struct damos_sysfs_quota_goal **goals_arr, *goal;
1283 	int err, i;
1284 
1285 	damos_sysfs_quota_goals_rm_dirs(goals);
1286 	if (!nr_goals)
1287 		return 0;
1288 
1289 	goals_arr = kmalloc_objs(*goals_arr, nr_goals,
1290 				 GFP_KERNEL | __GFP_NOWARN);
1291 	if (!goals_arr)
1292 		return -ENOMEM;
1293 	goals->goals_arr = goals_arr;
1294 
1295 	for (i = 0; i < nr_goals; i++) {
1296 		goal = damos_sysfs_quota_goal_alloc();
1297 		if (!goal) {
1298 			damos_sysfs_quota_goals_rm_dirs(goals);
1299 			return -ENOMEM;
1300 		}
1301 
1302 		err = kobject_init_and_add(&goal->kobj,
1303 				&damos_sysfs_quota_goal_ktype, &goals->kobj,
1304 				"%d", i);
1305 		if (err) {
1306 			kobject_put(&goal->kobj);
1307 			damos_sysfs_quota_goals_rm_dirs(goals);
1308 			return err;
1309 		}
1310 
1311 		goals_arr[i] = goal;
1312 		goals->nr++;
1313 	}
1314 	return 0;
1315 }
1316 
1317 static ssize_t nr_goals_show(struct kobject *kobj,
1318 		struct kobj_attribute *attr, char *buf)
1319 {
1320 	struct damos_sysfs_quota_goals *goals = container_of(kobj,
1321 			struct damos_sysfs_quota_goals, kobj);
1322 
1323 	return sysfs_emit(buf, "%d\n", goals->nr);
1324 }
1325 
1326 static ssize_t nr_goals_store(struct kobject *kobj,
1327 		struct kobj_attribute *attr, const char *buf, size_t count)
1328 {
1329 	struct damos_sysfs_quota_goals *goals;
1330 	int nr, err = kstrtoint(buf, 0, &nr);
1331 
1332 	if (err)
1333 		return err;
1334 	if (nr < 0)
1335 		return -EINVAL;
1336 
1337 	goals = container_of(kobj, struct damos_sysfs_quota_goals, kobj);
1338 
1339 	if (!mutex_trylock(&damon_sysfs_lock))
1340 		return -EBUSY;
1341 	err = damos_sysfs_quota_goals_add_dirs(goals, nr);
1342 	mutex_unlock(&damon_sysfs_lock);
1343 	if (err)
1344 		return err;
1345 
1346 	return count;
1347 }
1348 
1349 static void damos_sysfs_quota_goals_release(struct kobject *kobj)
1350 {
1351 	kfree(container_of(kobj, struct damos_sysfs_quota_goals, kobj));
1352 }
1353 
1354 static struct kobj_attribute damos_sysfs_quota_goals_nr_attr =
1355 		__ATTR_RW_MODE(nr_goals, 0600);
1356 
1357 static struct attribute *damos_sysfs_quota_goals_attrs[] = {
1358 	&damos_sysfs_quota_goals_nr_attr.attr,
1359 	NULL,
1360 };
1361 ATTRIBUTE_GROUPS(damos_sysfs_quota_goals);
1362 
1363 static const struct kobj_type damos_sysfs_quota_goals_ktype = {
1364 	.release = damos_sysfs_quota_goals_release,
1365 	.sysfs_ops = &kobj_sysfs_ops,
1366 	.default_groups = damos_sysfs_quota_goals_groups,
1367 };
1368 
1369 /*
1370  * scheme/weights directory
1371  */
1372 
1373 struct damon_sysfs_weights {
1374 	struct kobject kobj;
1375 	unsigned int sz;
1376 	unsigned int nr_accesses;
1377 	unsigned int age;
1378 };
1379 
1380 static struct damon_sysfs_weights *damon_sysfs_weights_alloc(unsigned int sz,
1381 		unsigned int nr_accesses, unsigned int age)
1382 {
1383 	struct damon_sysfs_weights *weights = kmalloc_obj(*weights);
1384 
1385 	if (!weights)
1386 		return NULL;
1387 	weights->kobj = (struct kobject){};
1388 	weights->sz = sz;
1389 	weights->nr_accesses = nr_accesses;
1390 	weights->age = age;
1391 	return weights;
1392 }
1393 
1394 static ssize_t sz_permil_show(struct kobject *kobj,
1395 		struct kobj_attribute *attr, char *buf)
1396 {
1397 	struct damon_sysfs_weights *weights = container_of(kobj,
1398 			struct damon_sysfs_weights, kobj);
1399 
1400 	return sysfs_emit(buf, "%u\n", weights->sz);
1401 }
1402 
1403 static ssize_t sz_permil_store(struct kobject *kobj,
1404 		struct kobj_attribute *attr, const char *buf, size_t count)
1405 {
1406 	struct damon_sysfs_weights *weights = container_of(kobj,
1407 			struct damon_sysfs_weights, kobj);
1408 	int err = kstrtouint(buf, 0, &weights->sz);
1409 
1410 	return err ? err : count;
1411 }
1412 
1413 static ssize_t nr_accesses_permil_show(struct kobject *kobj,
1414 		struct kobj_attribute *attr, char *buf)
1415 {
1416 	struct damon_sysfs_weights *weights = container_of(kobj,
1417 			struct damon_sysfs_weights, kobj);
1418 
1419 	return sysfs_emit(buf, "%u\n", weights->nr_accesses);
1420 }
1421 
1422 static ssize_t nr_accesses_permil_store(struct kobject *kobj,
1423 		struct kobj_attribute *attr, const char *buf, size_t count)
1424 {
1425 	struct damon_sysfs_weights *weights = container_of(kobj,
1426 			struct damon_sysfs_weights, kobj);
1427 	int err = kstrtouint(buf, 0, &weights->nr_accesses);
1428 
1429 	return err ? err : count;
1430 }
1431 
1432 static ssize_t age_permil_show(struct kobject *kobj,
1433 		struct kobj_attribute *attr, char *buf)
1434 {
1435 	struct damon_sysfs_weights *weights = container_of(kobj,
1436 			struct damon_sysfs_weights, kobj);
1437 
1438 	return sysfs_emit(buf, "%u\n", weights->age);
1439 }
1440 
1441 static ssize_t age_permil_store(struct kobject *kobj,
1442 		struct kobj_attribute *attr, const char *buf, size_t count)
1443 {
1444 	struct damon_sysfs_weights *weights = container_of(kobj,
1445 			struct damon_sysfs_weights, kobj);
1446 	int err = kstrtouint(buf, 0, &weights->age);
1447 
1448 	return err ? err : count;
1449 }
1450 
1451 static void damon_sysfs_weights_release(struct kobject *kobj)
1452 {
1453 	kfree(container_of(kobj, struct damon_sysfs_weights, kobj));
1454 }
1455 
1456 static struct kobj_attribute damon_sysfs_weights_sz_attr =
1457 		__ATTR_RW_MODE(sz_permil, 0600);
1458 
1459 static struct kobj_attribute damon_sysfs_weights_nr_accesses_attr =
1460 		__ATTR_RW_MODE(nr_accesses_permil, 0600);
1461 
1462 static struct kobj_attribute damon_sysfs_weights_age_attr =
1463 		__ATTR_RW_MODE(age_permil, 0600);
1464 
1465 static struct attribute *damon_sysfs_weights_attrs[] = {
1466 	&damon_sysfs_weights_sz_attr.attr,
1467 	&damon_sysfs_weights_nr_accesses_attr.attr,
1468 	&damon_sysfs_weights_age_attr.attr,
1469 	NULL,
1470 };
1471 ATTRIBUTE_GROUPS(damon_sysfs_weights);
1472 
1473 static const struct kobj_type damon_sysfs_weights_ktype = {
1474 	.release = damon_sysfs_weights_release,
1475 	.sysfs_ops = &kobj_sysfs_ops,
1476 	.default_groups = damon_sysfs_weights_groups,
1477 };
1478 
1479 /*
1480  * quotas directory
1481  */
1482 
1483 struct damon_sysfs_quotas {
1484 	struct kobject kobj;
1485 	struct damon_sysfs_weights *weights;
1486 	struct damos_sysfs_quota_goals *goals;
1487 	unsigned long ms;
1488 	unsigned long sz;
1489 	unsigned long reset_interval_ms;
1490 	unsigned long effective_sz;	/* Effective size quota in bytes */
1491 	enum damos_quota_goal_tuner goal_tuner;
1492 };
1493 
1494 static struct damon_sysfs_quotas *damon_sysfs_quotas_alloc(void)
1495 {
1496 	return kzalloc_obj(struct damon_sysfs_quotas);
1497 }
1498 
1499 static int damon_sysfs_quotas_add_dirs(struct damon_sysfs_quotas *quotas)
1500 {
1501 	struct damon_sysfs_weights *weights;
1502 	struct damos_sysfs_quota_goals *goals;
1503 	int err;
1504 
1505 	weights = damon_sysfs_weights_alloc(0, 0, 0);
1506 	if (!weights)
1507 		return -ENOMEM;
1508 
1509 	err = kobject_init_and_add(&weights->kobj, &damon_sysfs_weights_ktype,
1510 			&quotas->kobj, "weights");
1511 	if (err) {
1512 		kobject_put(&weights->kobj);
1513 		return err;
1514 	}
1515 	quotas->weights = weights;
1516 
1517 	goals = damos_sysfs_quota_goals_alloc();
1518 	if (!goals) {
1519 		kobject_put(&weights->kobj);
1520 		return -ENOMEM;
1521 	}
1522 	err = kobject_init_and_add(&goals->kobj,
1523 			&damos_sysfs_quota_goals_ktype, &quotas->kobj,
1524 			"goals");
1525 	if (err) {
1526 		kobject_put(&weights->kobj);
1527 		kobject_put(&goals->kobj);
1528 	} else {
1529 		quotas->goals = goals;
1530 	}
1531 
1532 	return err;
1533 }
1534 
1535 static void damon_sysfs_quotas_rm_dirs(struct damon_sysfs_quotas *quotas)
1536 {
1537 	kobject_put(&quotas->weights->kobj);
1538 	damos_sysfs_quota_goals_rm_dirs(quotas->goals);
1539 	kobject_put(&quotas->goals->kobj);
1540 }
1541 
1542 static ssize_t ms_show(struct kobject *kobj, struct kobj_attribute *attr,
1543 		char *buf)
1544 {
1545 	struct damon_sysfs_quotas *quotas = container_of(kobj,
1546 			struct damon_sysfs_quotas, kobj);
1547 
1548 	return sysfs_emit(buf, "%lu\n", quotas->ms);
1549 }
1550 
1551 static ssize_t ms_store(struct kobject *kobj, struct kobj_attribute *attr,
1552 		const char *buf, size_t count)
1553 {
1554 	struct damon_sysfs_quotas *quotas = container_of(kobj,
1555 			struct damon_sysfs_quotas, kobj);
1556 	int err = kstrtoul(buf, 0, &quotas->ms);
1557 
1558 	if (err)
1559 		return -EINVAL;
1560 	return count;
1561 }
1562 
1563 static ssize_t bytes_show(struct kobject *kobj, struct kobj_attribute *attr,
1564 		char *buf)
1565 {
1566 	struct damon_sysfs_quotas *quotas = container_of(kobj,
1567 			struct damon_sysfs_quotas, kobj);
1568 
1569 	return sysfs_emit(buf, "%lu\n", quotas->sz);
1570 }
1571 
1572 static ssize_t bytes_store(struct kobject *kobj,
1573 		struct kobj_attribute *attr, const char *buf, size_t count)
1574 {
1575 	struct damon_sysfs_quotas *quotas = container_of(kobj,
1576 			struct damon_sysfs_quotas, kobj);
1577 	int err = kstrtoul(buf, 0, &quotas->sz);
1578 
1579 	if (err)
1580 		return -EINVAL;
1581 	return count;
1582 }
1583 
1584 static ssize_t reset_interval_ms_show(struct kobject *kobj,
1585 		struct kobj_attribute *attr, char *buf)
1586 {
1587 	struct damon_sysfs_quotas *quotas = container_of(kobj,
1588 			struct damon_sysfs_quotas, kobj);
1589 
1590 	return sysfs_emit(buf, "%lu\n", quotas->reset_interval_ms);
1591 }
1592 
1593 static ssize_t reset_interval_ms_store(struct kobject *kobj,
1594 		struct kobj_attribute *attr, const char *buf, size_t count)
1595 {
1596 	struct damon_sysfs_quotas *quotas = container_of(kobj,
1597 			struct damon_sysfs_quotas, kobj);
1598 	int err = kstrtoul(buf, 0, &quotas->reset_interval_ms);
1599 
1600 	if (err)
1601 		return -EINVAL;
1602 	return count;
1603 }
1604 
1605 static ssize_t effective_bytes_show(struct kobject *kobj,
1606 		struct kobj_attribute *attr, char *buf)
1607 {
1608 	struct damon_sysfs_quotas *quotas = container_of(kobj,
1609 			struct damon_sysfs_quotas, kobj);
1610 
1611 	return sysfs_emit(buf, "%lu\n", quotas->effective_sz);
1612 }
1613 
1614 struct damos_sysfs_qgoal_tuner_name {
1615 	enum damos_quota_goal_tuner tuner;
1616 	char *name;
1617 };
1618 
1619 static struct damos_sysfs_qgoal_tuner_name damos_sysfs_qgoal_tuner_names[] = {
1620 	{
1621 		.tuner = DAMOS_QUOTA_GOAL_TUNER_CONSIST,
1622 		.name = "consist",
1623 	},
1624 	{
1625 		.tuner = DAMOS_QUOTA_GOAL_TUNER_TEMPORAL,
1626 		.name = "temporal",
1627 	},
1628 };
1629 
1630 static ssize_t goal_tuner_show(struct kobject *kobj,
1631 		struct kobj_attribute *attr, char *buf)
1632 {
1633 	struct damon_sysfs_quotas *quotas = container_of(kobj,
1634 			struct damon_sysfs_quotas, kobj);
1635 	int i;
1636 
1637 	for (i = 0; i < ARRAY_SIZE(damos_sysfs_qgoal_tuner_names); i++) {
1638 		struct damos_sysfs_qgoal_tuner_name *tuner_name;
1639 
1640 		tuner_name = &damos_sysfs_qgoal_tuner_names[i];
1641 		if (tuner_name->tuner == quotas->goal_tuner)
1642 			return sysfs_emit(buf, "%s\n", tuner_name->name);
1643 	}
1644 	return -EINVAL;
1645 }
1646 
1647 static ssize_t goal_tuner_store(struct kobject *kobj,
1648 		struct kobj_attribute *attr, const char *buf, size_t count)
1649 {
1650 	struct damon_sysfs_quotas *quotas = container_of(kobj,
1651 			struct damon_sysfs_quotas, kobj);
1652 	int i;
1653 
1654 	for (i = 0; i < ARRAY_SIZE(damos_sysfs_qgoal_tuner_names); i++) {
1655 		struct damos_sysfs_qgoal_tuner_name *tuner_name;
1656 
1657 		tuner_name = &damos_sysfs_qgoal_tuner_names[i];
1658 		if (sysfs_streq(buf, tuner_name->name)) {
1659 			quotas->goal_tuner = tuner_name->tuner;
1660 			return count;
1661 		}
1662 	}
1663 	return -EINVAL;
1664 }
1665 
1666 static void damon_sysfs_quotas_release(struct kobject *kobj)
1667 {
1668 	kfree(container_of(kobj, struct damon_sysfs_quotas, kobj));
1669 }
1670 
1671 static struct kobj_attribute damon_sysfs_quotas_ms_attr =
1672 		__ATTR_RW_MODE(ms, 0600);
1673 
1674 static struct kobj_attribute damon_sysfs_quotas_sz_attr =
1675 		__ATTR_RW_MODE(bytes, 0600);
1676 
1677 static struct kobj_attribute damon_sysfs_quotas_reset_interval_ms_attr =
1678 		__ATTR_RW_MODE(reset_interval_ms, 0600);
1679 
1680 static struct kobj_attribute damon_sysfs_quotas_effective_bytes_attr =
1681 		__ATTR_RO_MODE(effective_bytes, 0400);
1682 
1683 static struct kobj_attribute damon_sysfs_quotas_goal_tuner_attr =
1684 		__ATTR_RW_MODE(goal_tuner, 0600);
1685 
1686 static struct attribute *damon_sysfs_quotas_attrs[] = {
1687 	&damon_sysfs_quotas_ms_attr.attr,
1688 	&damon_sysfs_quotas_sz_attr.attr,
1689 	&damon_sysfs_quotas_reset_interval_ms_attr.attr,
1690 	&damon_sysfs_quotas_effective_bytes_attr.attr,
1691 	&damon_sysfs_quotas_goal_tuner_attr.attr,
1692 	NULL,
1693 };
1694 ATTRIBUTE_GROUPS(damon_sysfs_quotas);
1695 
1696 static const struct kobj_type damon_sysfs_quotas_ktype = {
1697 	.release = damon_sysfs_quotas_release,
1698 	.sysfs_ops = &kobj_sysfs_ops,
1699 	.default_groups = damon_sysfs_quotas_groups,
1700 };
1701 
1702 /*
1703  * access_pattern directory
1704  */
1705 
1706 struct damon_sysfs_access_pattern {
1707 	struct kobject kobj;
1708 	struct damon_sysfs_ul_range *sz;
1709 	struct damon_sysfs_ul_range *nr_accesses;
1710 	struct damon_sysfs_ul_range *age;
1711 };
1712 
1713 static
1714 struct damon_sysfs_access_pattern *damon_sysfs_access_pattern_alloc(void)
1715 {
1716 	struct damon_sysfs_access_pattern *access_pattern = kmalloc_obj(*access_pattern);
1717 
1718 	if (!access_pattern)
1719 		return NULL;
1720 	access_pattern->kobj = (struct kobject){};
1721 	return access_pattern;
1722 }
1723 
1724 static int damon_sysfs_access_pattern_add_range_dir(
1725 		struct damon_sysfs_access_pattern *access_pattern,
1726 		struct damon_sysfs_ul_range **range_dir_ptr,
1727 		char *name)
1728 {
1729 	struct damon_sysfs_ul_range *range = damon_sysfs_ul_range_alloc(0, 0);
1730 	int err;
1731 
1732 	if (!range)
1733 		return -ENOMEM;
1734 	err = kobject_init_and_add(&range->kobj, &damon_sysfs_ul_range_ktype,
1735 			&access_pattern->kobj, "%s", name);
1736 	if (err)
1737 		kobject_put(&range->kobj);
1738 	else
1739 		*range_dir_ptr = range;
1740 	return err;
1741 }
1742 
1743 static int damon_sysfs_access_pattern_add_dirs(
1744 		struct damon_sysfs_access_pattern *access_pattern)
1745 {
1746 	int err;
1747 
1748 	err = damon_sysfs_access_pattern_add_range_dir(access_pattern,
1749 			&access_pattern->sz, "sz");
1750 	if (err)
1751 		goto put_sz_out;
1752 
1753 	err = damon_sysfs_access_pattern_add_range_dir(access_pattern,
1754 			&access_pattern->nr_accesses, "nr_accesses");
1755 	if (err)
1756 		goto put_nr_accesses_sz_out;
1757 
1758 	err = damon_sysfs_access_pattern_add_range_dir(access_pattern,
1759 			&access_pattern->age, "age");
1760 	if (err)
1761 		goto put_age_nr_accesses_sz_out;
1762 	return 0;
1763 
1764 put_age_nr_accesses_sz_out:
1765 	kobject_put(&access_pattern->age->kobj);
1766 	access_pattern->age = NULL;
1767 put_nr_accesses_sz_out:
1768 	kobject_put(&access_pattern->nr_accesses->kobj);
1769 	access_pattern->nr_accesses = NULL;
1770 put_sz_out:
1771 	kobject_put(&access_pattern->sz->kobj);
1772 	access_pattern->sz = NULL;
1773 	return err;
1774 }
1775 
1776 static void damon_sysfs_access_pattern_rm_dirs(
1777 		struct damon_sysfs_access_pattern *access_pattern)
1778 {
1779 	kobject_put(&access_pattern->sz->kobj);
1780 	kobject_put(&access_pattern->nr_accesses->kobj);
1781 	kobject_put(&access_pattern->age->kobj);
1782 }
1783 
1784 static void damon_sysfs_access_pattern_release(struct kobject *kobj)
1785 {
1786 	kfree(container_of(kobj, struct damon_sysfs_access_pattern, kobj));
1787 }
1788 
1789 static struct attribute *damon_sysfs_access_pattern_attrs[] = {
1790 	NULL,
1791 };
1792 ATTRIBUTE_GROUPS(damon_sysfs_access_pattern);
1793 
1794 static const struct kobj_type damon_sysfs_access_pattern_ktype = {
1795 	.release = damon_sysfs_access_pattern_release,
1796 	.sysfs_ops = &kobj_sysfs_ops,
1797 	.default_groups = damon_sysfs_access_pattern_groups,
1798 };
1799 
1800 /*
1801  * dest (action destination) directory
1802  */
1803 
1804 struct damos_sysfs_dest {
1805 	struct kobject kobj;
1806 	unsigned int id;
1807 	unsigned int weight;
1808 };
1809 
1810 static struct damos_sysfs_dest *damos_sysfs_dest_alloc(void)
1811 {
1812 	return kzalloc_obj(struct damos_sysfs_dest);
1813 }
1814 
1815 static ssize_t id_show(
1816 		struct kobject *kobj, struct kobj_attribute *attr, char *buf)
1817 {
1818 	struct damos_sysfs_dest *dest = container_of(kobj,
1819 			struct damos_sysfs_dest, kobj);
1820 
1821 	return sysfs_emit(buf, "%u\n", dest->id);
1822 }
1823 
1824 static ssize_t id_store(struct kobject *kobj,
1825 		struct kobj_attribute *attr, const char *buf, size_t count)
1826 {
1827 	struct damos_sysfs_dest *dest = container_of(kobj,
1828 			struct damos_sysfs_dest, kobj);
1829 	int err = kstrtouint(buf, 0, &dest->id);
1830 
1831 	return err ? err : count;
1832 }
1833 
1834 static ssize_t weight_show(
1835 		struct kobject *kobj, struct kobj_attribute *attr, char *buf)
1836 {
1837 	struct damos_sysfs_dest *dest = container_of(kobj,
1838 			struct damos_sysfs_dest, kobj);
1839 
1840 	return sysfs_emit(buf, "%u\n", dest->weight);
1841 }
1842 
1843 static ssize_t weight_store(struct kobject *kobj,
1844 		struct kobj_attribute *attr, const char *buf, size_t count)
1845 {
1846 	struct damos_sysfs_dest *dest = container_of(kobj,
1847 			struct damos_sysfs_dest, kobj);
1848 	int err = kstrtouint(buf, 0, &dest->weight);
1849 
1850 	return err ? err : count;
1851 }
1852 
1853 static void damos_sysfs_dest_release(struct kobject *kobj)
1854 {
1855 	struct damos_sysfs_dest *dest = container_of(kobj,
1856 			struct damos_sysfs_dest, kobj);
1857 	kfree(dest);
1858 }
1859 
1860 static struct kobj_attribute damos_sysfs_dest_id_attr =
1861 		__ATTR_RW_MODE(id, 0600);
1862 
1863 static struct kobj_attribute damos_sysfs_dest_weight_attr =
1864 		__ATTR_RW_MODE(weight, 0600);
1865 
1866 static struct attribute *damos_sysfs_dest_attrs[] = {
1867 	&damos_sysfs_dest_id_attr.attr,
1868 	&damos_sysfs_dest_weight_attr.attr,
1869 	NULL,
1870 };
1871 ATTRIBUTE_GROUPS(damos_sysfs_dest);
1872 
1873 static const struct kobj_type damos_sysfs_dest_ktype = {
1874 	.release = damos_sysfs_dest_release,
1875 	.sysfs_ops = &kobj_sysfs_ops,
1876 	.default_groups = damos_sysfs_dest_groups,
1877 };
1878 
1879 /*
1880  * dests (action destinations) directory
1881  */
1882 
1883 struct damos_sysfs_dests {
1884 	struct kobject kobj;
1885 	struct damos_sysfs_dest **dests_arr;
1886 	int nr;
1887 };
1888 
1889 static struct damos_sysfs_dests *
1890 damos_sysfs_dests_alloc(void)
1891 {
1892 	return kzalloc_obj(struct damos_sysfs_dests);
1893 }
1894 
1895 static void damos_sysfs_dests_rm_dirs(
1896 		struct damos_sysfs_dests *dests)
1897 {
1898 	struct damos_sysfs_dest **dests_arr = dests->dests_arr;
1899 	int i;
1900 
1901 	for (i = 0; i < dests->nr; i++)
1902 		kobject_put(&dests_arr[i]->kobj);
1903 	dests->nr = 0;
1904 	kfree(dests_arr);
1905 	dests->dests_arr = NULL;
1906 }
1907 
1908 static int damos_sysfs_dests_add_dirs(
1909 		struct damos_sysfs_dests *dests, int nr_dests)
1910 {
1911 	struct damos_sysfs_dest **dests_arr, *dest;
1912 	int err, i;
1913 
1914 	damos_sysfs_dests_rm_dirs(dests);
1915 	if (!nr_dests)
1916 		return 0;
1917 
1918 	dests_arr = kmalloc_objs(*dests_arr, nr_dests,
1919 				 GFP_KERNEL | __GFP_NOWARN);
1920 	if (!dests_arr)
1921 		return -ENOMEM;
1922 	dests->dests_arr = dests_arr;
1923 
1924 	for (i = 0; i < nr_dests; i++) {
1925 		dest = damos_sysfs_dest_alloc();
1926 		if (!dest) {
1927 			damos_sysfs_dests_rm_dirs(dests);
1928 			return -ENOMEM;
1929 		}
1930 
1931 		err = kobject_init_and_add(&dest->kobj,
1932 				&damos_sysfs_dest_ktype,
1933 				&dests->kobj, "%d", i);
1934 		if (err) {
1935 			kobject_put(&dest->kobj);
1936 			damos_sysfs_dests_rm_dirs(dests);
1937 			return err;
1938 		}
1939 
1940 		dests_arr[i] = dest;
1941 		dests->nr++;
1942 	}
1943 	return 0;
1944 }
1945 
1946 static ssize_t nr_dests_show(struct kobject *kobj,
1947 		struct kobj_attribute *attr, char *buf)
1948 {
1949 	struct damos_sysfs_dests *dests = container_of(kobj,
1950 			struct damos_sysfs_dests, kobj);
1951 
1952 	return sysfs_emit(buf, "%d\n", dests->nr);
1953 }
1954 
1955 static ssize_t nr_dests_store(struct kobject *kobj,
1956 		struct kobj_attribute *attr, const char *buf, size_t count)
1957 {
1958 	struct damos_sysfs_dests *dests;
1959 	int nr, err = kstrtoint(buf, 0, &nr);
1960 
1961 	if (err)
1962 		return err;
1963 	if (nr < 0)
1964 		return -EINVAL;
1965 
1966 	dests = container_of(kobj, struct damos_sysfs_dests, kobj);
1967 
1968 	if (!mutex_trylock(&damon_sysfs_lock))
1969 		return -EBUSY;
1970 	err = damos_sysfs_dests_add_dirs(dests, nr);
1971 	mutex_unlock(&damon_sysfs_lock);
1972 	if (err)
1973 		return err;
1974 
1975 	return count;
1976 }
1977 
1978 static void damos_sysfs_dests_release(struct kobject *kobj)
1979 {
1980 	kfree(container_of(kobj, struct damos_sysfs_dests, kobj));
1981 }
1982 
1983 static struct kobj_attribute damos_sysfs_dests_nr_attr =
1984 		__ATTR_RW_MODE(nr_dests, 0600);
1985 
1986 static struct attribute *damos_sysfs_dests_attrs[] = {
1987 	&damos_sysfs_dests_nr_attr.attr,
1988 	NULL,
1989 };
1990 ATTRIBUTE_GROUPS(damos_sysfs_dests);
1991 
1992 static const struct kobj_type damos_sysfs_dests_ktype = {
1993 	.release = damos_sysfs_dests_release,
1994 	.sysfs_ops = &kobj_sysfs_ops,
1995 	.default_groups = damos_sysfs_dests_groups,
1996 };
1997 
1998 /*
1999  * scheme directory
2000  */
2001 
2002 struct damon_sysfs_scheme {
2003 	struct kobject kobj;
2004 	enum damos_action action;
2005 	struct damon_sysfs_access_pattern *access_pattern;
2006 	unsigned long apply_interval_us;
2007 	struct damon_sysfs_quotas *quotas;
2008 	struct damon_sysfs_watermarks *watermarks;
2009 	struct damon_sysfs_scheme_filters *core_filters;
2010 	struct damon_sysfs_scheme_filters *ops_filters;
2011 	struct damon_sysfs_scheme_filters *filters;
2012 	struct damon_sysfs_stats *stats;
2013 	struct damon_sysfs_scheme_regions *tried_regions;
2014 	int target_nid;
2015 	struct damos_sysfs_dests *dests;
2016 };
2017 
2018 struct damos_sysfs_action_name {
2019 	enum damos_action action;
2020 	char *name;
2021 };
2022 
2023 static struct damos_sysfs_action_name damos_sysfs_action_names[] = {
2024 	{
2025 		.action = DAMOS_WILLNEED,
2026 		.name = "willneed",
2027 	},
2028 	{
2029 		.action = DAMOS_COLD,
2030 		.name = "cold",
2031 	},
2032 	{
2033 		.action = DAMOS_PAGEOUT,
2034 		.name = "pageout",
2035 	},
2036 	{
2037 		.action = DAMOS_HUGEPAGE,
2038 		.name = "hugepage",
2039 	},
2040 	{
2041 		.action = DAMOS_NOHUGEPAGE,
2042 		.name = "nohugepage",
2043 	},
2044 	{
2045 		.action = DAMOS_LRU_PRIO,
2046 		.name = "lru_prio",
2047 	},
2048 	{
2049 		.action = DAMOS_LRU_DEPRIO,
2050 		.name = "lru_deprio",
2051 	},
2052 	{
2053 		.action = DAMOS_MIGRATE_HOT,
2054 		.name = "migrate_hot",
2055 	},
2056 	{
2057 		.action = DAMOS_MIGRATE_COLD,
2058 		.name = "migrate_cold",
2059 	},
2060 	{
2061 		.action = DAMOS_STAT,
2062 		.name = "stat",
2063 	},
2064 };
2065 
2066 static struct damon_sysfs_scheme *damon_sysfs_scheme_alloc(
2067 		enum damos_action action, unsigned long apply_interval_us)
2068 {
2069 	struct damon_sysfs_scheme *scheme = kmalloc_obj(*scheme);
2070 
2071 	if (!scheme)
2072 		return NULL;
2073 	scheme->kobj = (struct kobject){};
2074 	scheme->action = action;
2075 	scheme->apply_interval_us = apply_interval_us;
2076 	scheme->target_nid = NUMA_NO_NODE;
2077 	return scheme;
2078 }
2079 
2080 static int damon_sysfs_scheme_set_access_pattern(
2081 		struct damon_sysfs_scheme *scheme)
2082 {
2083 	struct damon_sysfs_access_pattern *access_pattern;
2084 	int err;
2085 
2086 	access_pattern = damon_sysfs_access_pattern_alloc();
2087 	if (!access_pattern)
2088 		return -ENOMEM;
2089 	err = kobject_init_and_add(&access_pattern->kobj,
2090 			&damon_sysfs_access_pattern_ktype, &scheme->kobj,
2091 			"access_pattern");
2092 	if (err)
2093 		goto out;
2094 	err = damon_sysfs_access_pattern_add_dirs(access_pattern);
2095 	if (err)
2096 		goto out;
2097 	scheme->access_pattern = access_pattern;
2098 	return 0;
2099 
2100 out:
2101 	kobject_put(&access_pattern->kobj);
2102 	return err;
2103 }
2104 
2105 static int damos_sysfs_set_dests(struct damon_sysfs_scheme *scheme)
2106 {
2107 	struct damos_sysfs_dests *dests = damos_sysfs_dests_alloc();
2108 	int err;
2109 
2110 	if (!dests)
2111 		return -ENOMEM;
2112 	err = kobject_init_and_add(&dests->kobj, &damos_sysfs_dests_ktype,
2113 			&scheme->kobj, "dests");
2114 	if (err)
2115 		kobject_put(&dests->kobj);
2116 	else
2117 		scheme->dests = dests;
2118 	return err;
2119 }
2120 
2121 static int damon_sysfs_scheme_set_quotas(struct damon_sysfs_scheme *scheme)
2122 {
2123 	struct damon_sysfs_quotas *quotas = damon_sysfs_quotas_alloc();
2124 	int err;
2125 
2126 	if (!quotas)
2127 		return -ENOMEM;
2128 	err = kobject_init_and_add(&quotas->kobj, &damon_sysfs_quotas_ktype,
2129 			&scheme->kobj, "quotas");
2130 	if (err)
2131 		goto out;
2132 	err = damon_sysfs_quotas_add_dirs(quotas);
2133 	if (err)
2134 		goto out;
2135 	scheme->quotas = quotas;
2136 	return 0;
2137 
2138 out:
2139 	kobject_put(&quotas->kobj);
2140 	return err;
2141 }
2142 
2143 static int damon_sysfs_scheme_set_watermarks(struct damon_sysfs_scheme *scheme)
2144 {
2145 	struct damon_sysfs_watermarks *watermarks =
2146 		damon_sysfs_watermarks_alloc(DAMOS_WMARK_NONE, 0, 0, 0, 0);
2147 	int err;
2148 
2149 	if (!watermarks)
2150 		return -ENOMEM;
2151 	err = kobject_init_and_add(&watermarks->kobj,
2152 			&damon_sysfs_watermarks_ktype, &scheme->kobj,
2153 			"watermarks");
2154 	if (err)
2155 		kobject_put(&watermarks->kobj);
2156 	else
2157 		scheme->watermarks = watermarks;
2158 	return err;
2159 }
2160 
2161 static int damon_sysfs_scheme_set_filters(struct damon_sysfs_scheme *scheme,
2162 		enum damos_sysfs_filter_handle_layer layer, const char *name,
2163 		struct damon_sysfs_scheme_filters **filters_ptr)
2164 {
2165 	struct damon_sysfs_scheme_filters *filters =
2166 		damon_sysfs_scheme_filters_alloc(layer);
2167 	int err;
2168 
2169 	if (!filters)
2170 		return -ENOMEM;
2171 	err = kobject_init_and_add(&filters->kobj,
2172 			&damon_sysfs_scheme_filters_ktype, &scheme->kobj,
2173 			"%s", name);
2174 	if (err)
2175 		kobject_put(&filters->kobj);
2176 	else
2177 		*filters_ptr = filters;
2178 	return err;
2179 }
2180 
2181 static int damos_sysfs_set_filter_dirs(struct damon_sysfs_scheme *scheme)
2182 {
2183 	int err;
2184 
2185 	err = damon_sysfs_scheme_set_filters(scheme,
2186 			DAMOS_SYSFS_FILTER_HANDLE_LAYER_BOTH, "filters",
2187 			&scheme->filters);
2188 	if (err)
2189 		return err;
2190 	err = damon_sysfs_scheme_set_filters(scheme,
2191 			DAMOS_SYSFS_FILTER_HANDLE_LAYER_CORE, "core_filters",
2192 			&scheme->core_filters);
2193 	if (err)
2194 		goto put_filters_out;
2195 	err = damon_sysfs_scheme_set_filters(scheme,
2196 			DAMOS_SYSFS_FILTER_HANDLE_LAYER_OPS, "ops_filters",
2197 			&scheme->ops_filters);
2198 	if (err)
2199 		goto put_core_filters_out;
2200 	return 0;
2201 
2202 put_core_filters_out:
2203 	kobject_put(&scheme->core_filters->kobj);
2204 	scheme->core_filters = NULL;
2205 put_filters_out:
2206 	kobject_put(&scheme->filters->kobj);
2207 	scheme->filters = NULL;
2208 	return err;
2209 }
2210 
2211 static int damon_sysfs_scheme_set_stats(struct damon_sysfs_scheme *scheme)
2212 {
2213 	struct damon_sysfs_stats *stats = damon_sysfs_stats_alloc();
2214 	int err;
2215 
2216 	if (!stats)
2217 		return -ENOMEM;
2218 	err = kobject_init_and_add(&stats->kobj, &damon_sysfs_stats_ktype,
2219 			&scheme->kobj, "stats");
2220 	if (err)
2221 		kobject_put(&stats->kobj);
2222 	else
2223 		scheme->stats = stats;
2224 	return err;
2225 }
2226 
2227 static int damon_sysfs_scheme_set_tried_regions(
2228 		struct damon_sysfs_scheme *scheme)
2229 {
2230 	struct damon_sysfs_scheme_regions *tried_regions =
2231 		damon_sysfs_scheme_regions_alloc();
2232 	int err;
2233 
2234 	if (!tried_regions)
2235 		return -ENOMEM;
2236 	err = kobject_init_and_add(&tried_regions->kobj,
2237 			&damon_sysfs_scheme_regions_ktype, &scheme->kobj,
2238 			"tried_regions");
2239 	if (err)
2240 		kobject_put(&tried_regions->kobj);
2241 	else
2242 		scheme->tried_regions = tried_regions;
2243 	return err;
2244 }
2245 
2246 static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme)
2247 {
2248 	int err;
2249 
2250 	err = damon_sysfs_scheme_set_access_pattern(scheme);
2251 	if (err)
2252 		return err;
2253 	err = damos_sysfs_set_dests(scheme);
2254 	if (err)
2255 		goto rmdir_put_access_pattern_out;
2256 	err = damon_sysfs_scheme_set_quotas(scheme);
2257 	if (err)
2258 		goto put_dests_out;
2259 	err = damon_sysfs_scheme_set_watermarks(scheme);
2260 	if (err)
2261 		goto rmdir_put_quotas_access_pattern_out;
2262 	err = damos_sysfs_set_filter_dirs(scheme);
2263 	if (err)
2264 		goto put_watermarks_quotas_access_pattern_out;
2265 	err = damon_sysfs_scheme_set_stats(scheme);
2266 	if (err)
2267 		goto put_filters_watermarks_quotas_access_pattern_out;
2268 	err = damon_sysfs_scheme_set_tried_regions(scheme);
2269 	if (err)
2270 		goto put_tried_regions_out;
2271 	return 0;
2272 
2273 put_tried_regions_out:
2274 	kobject_put(&scheme->tried_regions->kobj);
2275 	scheme->tried_regions = NULL;
2276 put_filters_watermarks_quotas_access_pattern_out:
2277 	kobject_put(&scheme->ops_filters->kobj);
2278 	scheme->ops_filters = NULL;
2279 	kobject_put(&scheme->core_filters->kobj);
2280 	scheme->core_filters = NULL;
2281 	kobject_put(&scheme->filters->kobj);
2282 	scheme->filters = NULL;
2283 put_watermarks_quotas_access_pattern_out:
2284 	kobject_put(&scheme->watermarks->kobj);
2285 	scheme->watermarks = NULL;
2286 rmdir_put_quotas_access_pattern_out:
2287 	damon_sysfs_quotas_rm_dirs(scheme->quotas);
2288 	kobject_put(&scheme->quotas->kobj);
2289 	scheme->quotas = NULL;
2290 put_dests_out:
2291 	kobject_put(&scheme->dests->kobj);
2292 	scheme->dests = NULL;
2293 rmdir_put_access_pattern_out:
2294 	damon_sysfs_access_pattern_rm_dirs(scheme->access_pattern);
2295 	kobject_put(&scheme->access_pattern->kobj);
2296 	scheme->access_pattern = NULL;
2297 	return err;
2298 }
2299 
2300 static void damon_sysfs_scheme_rm_dirs(struct damon_sysfs_scheme *scheme)
2301 {
2302 	damon_sysfs_access_pattern_rm_dirs(scheme->access_pattern);
2303 	kobject_put(&scheme->access_pattern->kobj);
2304 	damos_sysfs_dests_rm_dirs(scheme->dests);
2305 	kobject_put(&scheme->dests->kobj);
2306 	damon_sysfs_quotas_rm_dirs(scheme->quotas);
2307 	kobject_put(&scheme->quotas->kobj);
2308 	kobject_put(&scheme->watermarks->kobj);
2309 	damon_sysfs_scheme_filters_rm_dirs(scheme->filters);
2310 	kobject_put(&scheme->filters->kobj);
2311 	damon_sysfs_scheme_filters_rm_dirs(scheme->core_filters);
2312 	kobject_put(&scheme->core_filters->kobj);
2313 	damon_sysfs_scheme_filters_rm_dirs(scheme->ops_filters);
2314 	kobject_put(&scheme->ops_filters->kobj);
2315 	kobject_put(&scheme->stats->kobj);
2316 	damon_sysfs_scheme_regions_rm_dirs(scheme->tried_regions);
2317 	kobject_put(&scheme->tried_regions->kobj);
2318 }
2319 
2320 static ssize_t action_show(struct kobject *kobj, struct kobj_attribute *attr,
2321 		char *buf)
2322 {
2323 	struct damon_sysfs_scheme *scheme = container_of(kobj,
2324 			struct damon_sysfs_scheme, kobj);
2325 	int i;
2326 
2327 	for (i = 0; i < ARRAY_SIZE(damos_sysfs_action_names); i++) {
2328 		struct damos_sysfs_action_name *action_name;
2329 
2330 		action_name = &damos_sysfs_action_names[i];
2331 		if (action_name->action == scheme->action)
2332 			return sysfs_emit(buf, "%s\n", action_name->name);
2333 	}
2334 	return -EINVAL;
2335 }
2336 
2337 static ssize_t action_store(struct kobject *kobj, struct kobj_attribute *attr,
2338 		const char *buf, size_t count)
2339 {
2340 	struct damon_sysfs_scheme *scheme = container_of(kobj,
2341 			struct damon_sysfs_scheme, kobj);
2342 	int i;
2343 
2344 	for (i = 0; i < ARRAY_SIZE(damos_sysfs_action_names); i++) {
2345 		struct damos_sysfs_action_name *action_name;
2346 
2347 		action_name = &damos_sysfs_action_names[i];
2348 		if (sysfs_streq(buf, action_name->name)) {
2349 			scheme->action = action_name->action;
2350 			return count;
2351 		}
2352 	}
2353 	return -EINVAL;
2354 }
2355 
2356 static ssize_t apply_interval_us_show(struct kobject *kobj,
2357 		struct kobj_attribute *attr, char *buf)
2358 {
2359 	struct damon_sysfs_scheme *scheme = container_of(kobj,
2360 			struct damon_sysfs_scheme, kobj);
2361 
2362 	return sysfs_emit(buf, "%lu\n", scheme->apply_interval_us);
2363 }
2364 
2365 static ssize_t apply_interval_us_store(struct kobject *kobj,
2366 		struct kobj_attribute *attr, const char *buf, size_t count)
2367 {
2368 	struct damon_sysfs_scheme *scheme = container_of(kobj,
2369 			struct damon_sysfs_scheme, kobj);
2370 	int err = kstrtoul(buf, 0, &scheme->apply_interval_us);
2371 
2372 	return err ? err : count;
2373 }
2374 
2375 static ssize_t target_nid_show(struct kobject *kobj,
2376 		struct kobj_attribute *attr, char *buf)
2377 {
2378 	struct damon_sysfs_scheme *scheme = container_of(kobj,
2379 			struct damon_sysfs_scheme, kobj);
2380 
2381 	return sysfs_emit(buf, "%d\n", scheme->target_nid);
2382 }
2383 
2384 static ssize_t target_nid_store(struct kobject *kobj,
2385 		struct kobj_attribute *attr, const char *buf, size_t count)
2386 {
2387 	struct damon_sysfs_scheme *scheme = container_of(kobj,
2388 			struct damon_sysfs_scheme, kobj);
2389 	int err = 0;
2390 
2391 	err = kstrtoint(buf, 0, &scheme->target_nid);
2392 
2393 	return err ? err : count;
2394 }
2395 
2396 static void damon_sysfs_scheme_release(struct kobject *kobj)
2397 {
2398 	kfree(container_of(kobj, struct damon_sysfs_scheme, kobj));
2399 }
2400 
2401 static struct kobj_attribute damon_sysfs_scheme_action_attr =
2402 		__ATTR_RW_MODE(action, 0600);
2403 
2404 static struct kobj_attribute damon_sysfs_scheme_apply_interval_us_attr =
2405 		__ATTR_RW_MODE(apply_interval_us, 0600);
2406 
2407 static struct kobj_attribute damon_sysfs_scheme_target_nid_attr =
2408 		__ATTR_RW_MODE(target_nid, 0600);
2409 
2410 static struct attribute *damon_sysfs_scheme_attrs[] = {
2411 	&damon_sysfs_scheme_action_attr.attr,
2412 	&damon_sysfs_scheme_apply_interval_us_attr.attr,
2413 	&damon_sysfs_scheme_target_nid_attr.attr,
2414 	NULL,
2415 };
2416 ATTRIBUTE_GROUPS(damon_sysfs_scheme);
2417 
2418 static const struct kobj_type damon_sysfs_scheme_ktype = {
2419 	.release = damon_sysfs_scheme_release,
2420 	.sysfs_ops = &kobj_sysfs_ops,
2421 	.default_groups = damon_sysfs_scheme_groups,
2422 };
2423 
2424 /*
2425  * schemes directory
2426  */
2427 
2428 struct damon_sysfs_schemes *damon_sysfs_schemes_alloc(void)
2429 {
2430 	return kzalloc_obj(struct damon_sysfs_schemes);
2431 }
2432 
2433 void damon_sysfs_schemes_rm_dirs(struct damon_sysfs_schemes *schemes)
2434 {
2435 	struct damon_sysfs_scheme **schemes_arr = schemes->schemes_arr;
2436 	int i;
2437 
2438 	for (i = 0; i < schemes->nr; i++) {
2439 		damon_sysfs_scheme_rm_dirs(schemes_arr[i]);
2440 		kobject_put(&schemes_arr[i]->kobj);
2441 	}
2442 	schemes->nr = 0;
2443 	kfree(schemes_arr);
2444 	schemes->schemes_arr = NULL;
2445 }
2446 
2447 static int damon_sysfs_schemes_add_dirs(struct damon_sysfs_schemes *schemes,
2448 		int nr_schemes)
2449 {
2450 	struct damon_sysfs_scheme **schemes_arr, *scheme;
2451 	int err, i;
2452 
2453 	damon_sysfs_schemes_rm_dirs(schemes);
2454 	if (!nr_schemes)
2455 		return 0;
2456 
2457 	schemes_arr = kmalloc_objs(*schemes_arr, nr_schemes,
2458 				   GFP_KERNEL | __GFP_NOWARN);
2459 	if (!schemes_arr)
2460 		return -ENOMEM;
2461 	schemes->schemes_arr = schemes_arr;
2462 
2463 	for (i = 0; i < nr_schemes; i++) {
2464 		/*
2465 		 * apply_interval_us as 0 means same to aggregation interval
2466 		 * (same to before-apply_interval behavior)
2467 		 */
2468 		scheme = damon_sysfs_scheme_alloc(DAMOS_STAT, 0);
2469 		if (!scheme) {
2470 			damon_sysfs_schemes_rm_dirs(schemes);
2471 			return -ENOMEM;
2472 		}
2473 
2474 		err = kobject_init_and_add(&scheme->kobj,
2475 				&damon_sysfs_scheme_ktype, &schemes->kobj,
2476 				"%d", i);
2477 		if (err)
2478 			goto out;
2479 		err = damon_sysfs_scheme_add_dirs(scheme);
2480 		if (err)
2481 			goto out;
2482 
2483 		schemes_arr[i] = scheme;
2484 		schemes->nr++;
2485 	}
2486 	return 0;
2487 
2488 out:
2489 	damon_sysfs_schemes_rm_dirs(schemes);
2490 	kobject_put(&scheme->kobj);
2491 	return err;
2492 }
2493 
2494 static ssize_t nr_schemes_show(struct kobject *kobj,
2495 		struct kobj_attribute *attr, char *buf)
2496 {
2497 	struct damon_sysfs_schemes *schemes = container_of(kobj,
2498 			struct damon_sysfs_schemes, kobj);
2499 
2500 	return sysfs_emit(buf, "%d\n", schemes->nr);
2501 }
2502 
2503 static ssize_t nr_schemes_store(struct kobject *kobj,
2504 		struct kobj_attribute *attr, const char *buf, size_t count)
2505 {
2506 	struct damon_sysfs_schemes *schemes;
2507 	int nr, err = kstrtoint(buf, 0, &nr);
2508 
2509 	if (err)
2510 		return err;
2511 	if (nr < 0)
2512 		return -EINVAL;
2513 
2514 	schemes = container_of(kobj, struct damon_sysfs_schemes, kobj);
2515 
2516 	if (!mutex_trylock(&damon_sysfs_lock))
2517 		return -EBUSY;
2518 	err = damon_sysfs_schemes_add_dirs(schemes, nr);
2519 	mutex_unlock(&damon_sysfs_lock);
2520 	if (err)
2521 		return err;
2522 	return count;
2523 }
2524 
2525 static void damon_sysfs_schemes_release(struct kobject *kobj)
2526 {
2527 	kfree(container_of(kobj, struct damon_sysfs_schemes, kobj));
2528 }
2529 
2530 static struct kobj_attribute damon_sysfs_schemes_nr_attr =
2531 		__ATTR_RW_MODE(nr_schemes, 0600);
2532 
2533 static struct attribute *damon_sysfs_schemes_attrs[] = {
2534 	&damon_sysfs_schemes_nr_attr.attr,
2535 	NULL,
2536 };
2537 ATTRIBUTE_GROUPS(damon_sysfs_schemes);
2538 
2539 const struct kobj_type damon_sysfs_schemes_ktype = {
2540 	.release = damon_sysfs_schemes_release,
2541 	.sysfs_ops = &kobj_sysfs_ops,
2542 	.default_groups = damon_sysfs_schemes_groups,
2543 };
2544 
2545 static bool damon_sysfs_memcg_path_eq(struct mem_cgroup *memcg,
2546 		char *memcg_path_buf, char *path)
2547 {
2548 #ifdef CONFIG_MEMCG
2549 	cgroup_path(memcg->css.cgroup, memcg_path_buf, PATH_MAX);
2550 	if (sysfs_streq(memcg_path_buf, path))
2551 		return true;
2552 #endif /* CONFIG_MEMCG */
2553 	return false;
2554 }
2555 
2556 static int damon_sysfs_memcg_path_to_id(char *memcg_path, u64 *id)
2557 {
2558 	struct mem_cgroup *memcg;
2559 	char *path;
2560 	bool found = false;
2561 
2562 	if (!memcg_path)
2563 		return -EINVAL;
2564 
2565 	path = kmalloc_array(PATH_MAX, sizeof(*path), GFP_KERNEL);
2566 	if (!path)
2567 		return -ENOMEM;
2568 
2569 	for (memcg = mem_cgroup_iter(NULL, NULL, NULL); memcg;
2570 			memcg = mem_cgroup_iter(NULL, memcg, NULL)) {
2571 		/* skip offlined memcg */
2572 		if (!mem_cgroup_online(memcg))
2573 			continue;
2574 		if (damon_sysfs_memcg_path_eq(memcg, path, memcg_path)) {
2575 			*id = mem_cgroup_id(memcg);
2576 			found = true;
2577 			break;
2578 		}
2579 	}
2580 
2581 	kfree(path);
2582 	return found ? 0 : -EINVAL;
2583 }
2584 
2585 static int damon_sysfs_add_scheme_filters(struct damos *scheme,
2586 		struct damon_sysfs_scheme_filters *sysfs_filters)
2587 {
2588 	int i;
2589 
2590 	for (i = 0; i < sysfs_filters->nr; i++) {
2591 		struct damon_sysfs_scheme_filter *sysfs_filter =
2592 			sysfs_filters->filters_arr[i];
2593 		struct damos_filter *filter =
2594 			damos_new_filter(sysfs_filter->type,
2595 					sysfs_filter->matching,
2596 					sysfs_filter->allow);
2597 		int err;
2598 
2599 		if (!filter)
2600 			return -ENOMEM;
2601 		if (filter->type == DAMOS_FILTER_TYPE_MEMCG) {
2602 			err = damon_sysfs_memcg_path_to_id(
2603 					sysfs_filter->memcg_path,
2604 					&filter->memcg_id);
2605 			if (err) {
2606 				damos_destroy_filter(filter);
2607 				return err;
2608 			}
2609 		} else if (filter->type == DAMOS_FILTER_TYPE_ADDR) {
2610 			if (sysfs_filter->addr_range.end <
2611 					sysfs_filter->addr_range.start) {
2612 				damos_destroy_filter(filter);
2613 				return -EINVAL;
2614 			}
2615 			filter->addr_range = sysfs_filter->addr_range;
2616 		} else if (filter->type == DAMOS_FILTER_TYPE_TARGET) {
2617 			filter->target_idx = sysfs_filter->target_idx;
2618 		} else if (filter->type == DAMOS_FILTER_TYPE_HUGEPAGE_SIZE) {
2619 			if (sysfs_filter->sz_range.min >
2620 					sysfs_filter->sz_range.max) {
2621 				damos_destroy_filter(filter);
2622 				return -EINVAL;
2623 			}
2624 			filter->sz_range = sysfs_filter->sz_range;
2625 		}
2626 
2627 		damos_add_filter(scheme, filter);
2628 	}
2629 	return 0;
2630 }
2631 
2632 static int damos_sysfs_add_quota_score(
2633 		struct damos_sysfs_quota_goals *sysfs_goals,
2634 		struct damos_quota *quota)
2635 {
2636 	struct damos_quota_goal *goal;
2637 	int i, err;
2638 
2639 	for (i = 0; i < sysfs_goals->nr; i++) {
2640 		struct damos_sysfs_quota_goal *sysfs_goal =
2641 			sysfs_goals->goals_arr[i];
2642 
2643 		if (!sysfs_goal->target_value)
2644 			continue;
2645 
2646 		goal = damos_new_quota_goal(sysfs_goal->metric,
2647 				sysfs_goal->target_value);
2648 		if (!goal)
2649 			return -ENOMEM;
2650 		switch (sysfs_goal->metric) {
2651 		case DAMOS_QUOTA_USER_INPUT:
2652 			goal->current_value = sysfs_goal->current_value;
2653 			break;
2654 		case DAMOS_QUOTA_NODE_MEM_USED_BP:
2655 		case DAMOS_QUOTA_NODE_MEM_FREE_BP:
2656 			goal->nid = sysfs_goal->nid;
2657 			break;
2658 		case DAMOS_QUOTA_NODE_MEMCG_USED_BP:
2659 		case DAMOS_QUOTA_NODE_MEMCG_FREE_BP:
2660 			err = damon_sysfs_memcg_path_to_id(
2661 					sysfs_goal->path, &goal->memcg_id);
2662 			if (err) {
2663 				damos_destroy_quota_goal(goal);
2664 				return err;
2665 			}
2666 			goal->nid = sysfs_goal->nid;
2667 			break;
2668 		default:
2669 			break;
2670 		}
2671 		damos_add_quota_goal(quota, goal);
2672 	}
2673 	return 0;
2674 }
2675 
2676 int damos_sysfs_set_quota_scores(struct damon_sysfs_schemes *sysfs_schemes,
2677 		struct damon_ctx *ctx)
2678 {
2679 	struct damos *scheme;
2680 	struct damos_quota quota = {};
2681 	int i = 0;
2682 
2683 	INIT_LIST_HEAD(&quota.goals);
2684 	damon_for_each_scheme(scheme, ctx) {
2685 		struct damon_sysfs_scheme *sysfs_scheme;
2686 		struct damos_quota_goal *g, *g_next;
2687 		int err;
2688 
2689 		/* user could have removed the scheme sysfs dir */
2690 		if (i >= sysfs_schemes->nr)
2691 			break;
2692 
2693 		sysfs_scheme = sysfs_schemes->schemes_arr[i];
2694 		err = damos_sysfs_add_quota_score(sysfs_scheme->quotas->goals,
2695 				&quota);
2696 		if (err) {
2697 			damos_for_each_quota_goal_safe(g, g_next, &quota)
2698 				damos_destroy_quota_goal(g);
2699 			return err;
2700 		}
2701 		err = damos_commit_quota_goals(&scheme->quota, &quota);
2702 		damos_for_each_quota_goal_safe(g, g_next, &quota)
2703 			damos_destroy_quota_goal(g);
2704 		if (err)
2705 			return err;
2706 		i++;
2707 	}
2708 	return 0;
2709 }
2710 
2711 void damos_sysfs_update_effective_quotas(
2712 		struct damon_sysfs_schemes *sysfs_schemes,
2713 		struct damon_ctx *ctx)
2714 {
2715 	struct damos *scheme;
2716 	int schemes_idx = 0;
2717 
2718 	damon_for_each_scheme(scheme, ctx) {
2719 		struct damon_sysfs_quotas *sysfs_quotas;
2720 
2721 		/* user could have removed the scheme sysfs dir */
2722 		if (schemes_idx >= sysfs_schemes->nr)
2723 			break;
2724 
2725 		sysfs_quotas =
2726 			sysfs_schemes->schemes_arr[schemes_idx++]->quotas;
2727 		sysfs_quotas->effective_sz = scheme->quota.esz;
2728 	}
2729 }
2730 
2731 static int damos_sysfs_add_migrate_dest(struct damos *scheme,
2732 		struct damos_sysfs_dests *sysfs_dests)
2733 {
2734 	struct damos_migrate_dests *dests = &scheme->migrate_dests;
2735 	int i;
2736 
2737 	dests->node_id_arr = kmalloc_objs(*dests->node_id_arr, sysfs_dests->nr);
2738 	if (!dests->node_id_arr)
2739 		return -ENOMEM;
2740 	dests->weight_arr = kmalloc_objs(*dests->weight_arr, sysfs_dests->nr);
2741 	if (!dests->weight_arr)
2742 		/* ->node_id_arr will be freed by scheme destruction */
2743 		return -ENOMEM;
2744 	for (i = 0; i < sysfs_dests->nr; i++) {
2745 		dests->node_id_arr[i] = sysfs_dests->dests_arr[i]->id;
2746 		dests->weight_arr[i] = sysfs_dests->dests_arr[i]->weight;
2747 	}
2748 	dests->nr_dests = sysfs_dests->nr;
2749 	return 0;
2750 }
2751 
2752 static struct damos *damon_sysfs_mk_scheme(
2753 		struct damon_sysfs_scheme *sysfs_scheme)
2754 {
2755 	struct damon_sysfs_access_pattern *access_pattern =
2756 		sysfs_scheme->access_pattern;
2757 	struct damon_sysfs_quotas *sysfs_quotas = sysfs_scheme->quotas;
2758 	struct damon_sysfs_weights *sysfs_weights = sysfs_quotas->weights;
2759 	struct damon_sysfs_watermarks *sysfs_wmarks = sysfs_scheme->watermarks;
2760 	struct damos *scheme;
2761 	int err;
2762 
2763 	struct damos_access_pattern pattern = {
2764 		.min_sz_region = access_pattern->sz->min,
2765 		.max_sz_region = access_pattern->sz->max,
2766 		.min_nr_accesses = access_pattern->nr_accesses->min,
2767 		.max_nr_accesses = access_pattern->nr_accesses->max,
2768 		.min_age_region = access_pattern->age->min,
2769 		.max_age_region = access_pattern->age->max,
2770 	};
2771 	struct damos_quota quota = {
2772 		.ms = sysfs_quotas->ms,
2773 		.sz = sysfs_quotas->sz,
2774 		.reset_interval = sysfs_quotas->reset_interval_ms,
2775 		.weight_sz = sysfs_weights->sz,
2776 		.weight_nr_accesses = sysfs_weights->nr_accesses,
2777 		.weight_age = sysfs_weights->age,
2778 		.goal_tuner = sysfs_quotas->goal_tuner,
2779 	};
2780 	struct damos_watermarks wmarks = {
2781 		.metric = sysfs_wmarks->metric,
2782 		.interval = sysfs_wmarks->interval_us,
2783 		.high = sysfs_wmarks->high,
2784 		.mid = sysfs_wmarks->mid,
2785 		.low = sysfs_wmarks->low,
2786 	};
2787 
2788 	scheme = damon_new_scheme(&pattern, sysfs_scheme->action,
2789 			sysfs_scheme->apply_interval_us, &quota, &wmarks,
2790 			sysfs_scheme->target_nid);
2791 	if (!scheme)
2792 		return NULL;
2793 
2794 	err = damos_sysfs_add_quota_score(sysfs_quotas->goals, &scheme->quota);
2795 	if (err) {
2796 		damon_destroy_scheme(scheme);
2797 		return NULL;
2798 	}
2799 
2800 	err = damon_sysfs_add_scheme_filters(scheme, sysfs_scheme->core_filters);
2801 	if (err) {
2802 		damon_destroy_scheme(scheme);
2803 		return NULL;
2804 	}
2805 	err = damon_sysfs_add_scheme_filters(scheme, sysfs_scheme->ops_filters);
2806 	if (err) {
2807 		damon_destroy_scheme(scheme);
2808 		return NULL;
2809 	}
2810 	err = damon_sysfs_add_scheme_filters(scheme, sysfs_scheme->filters);
2811 	if (err) {
2812 		damon_destroy_scheme(scheme);
2813 		return NULL;
2814 	}
2815 	err = damos_sysfs_add_migrate_dest(scheme, sysfs_scheme->dests);
2816 	if (err) {
2817 		damon_destroy_scheme(scheme);
2818 		return NULL;
2819 	}
2820 	scheme->max_nr_snapshots = sysfs_scheme->stats->max_nr_snapshots;
2821 	return scheme;
2822 }
2823 
2824 int damon_sysfs_add_schemes(struct damon_ctx *ctx,
2825 		struct damon_sysfs_schemes *sysfs_schemes)
2826 {
2827 	int i;
2828 
2829 	for (i = 0; i < sysfs_schemes->nr; i++) {
2830 		struct damos *scheme, *next;
2831 
2832 		scheme = damon_sysfs_mk_scheme(sysfs_schemes->schemes_arr[i]);
2833 		if (!scheme) {
2834 			damon_for_each_scheme_safe(scheme, next, ctx)
2835 				damon_destroy_scheme(scheme);
2836 			return -ENOMEM;
2837 		}
2838 		damon_add_scheme(ctx, scheme);
2839 	}
2840 	return 0;
2841 }
2842 
2843 void damon_sysfs_schemes_update_stats(
2844 		struct damon_sysfs_schemes *sysfs_schemes,
2845 		struct damon_ctx *ctx)
2846 {
2847 	struct damos *scheme;
2848 	int schemes_idx = 0;
2849 
2850 	damon_for_each_scheme(scheme, ctx) {
2851 		struct damon_sysfs_stats *sysfs_stats;
2852 
2853 		/* user could have removed the scheme sysfs dir */
2854 		if (schemes_idx >= sysfs_schemes->nr)
2855 			break;
2856 
2857 		sysfs_stats = sysfs_schemes->schemes_arr[schemes_idx++]->stats;
2858 		sysfs_stats->nr_tried = scheme->stat.nr_tried;
2859 		sysfs_stats->sz_tried = scheme->stat.sz_tried;
2860 		sysfs_stats->nr_applied = scheme->stat.nr_applied;
2861 		sysfs_stats->sz_applied = scheme->stat.sz_applied;
2862 		sysfs_stats->sz_ops_filter_passed =
2863 			scheme->stat.sz_ops_filter_passed;
2864 		sysfs_stats->qt_exceeds = scheme->stat.qt_exceeds;
2865 		sysfs_stats->nr_snapshots = scheme->stat.nr_snapshots;
2866 	}
2867 }
2868 
2869 /**
2870  * damos_sysfs_populate_region_dir() - Populate a schemes tried region dir.
2871  * @sysfs_schemes:	Schemes directory to populate regions directory.
2872  * @ctx:		Corresponding DAMON context.
2873  * @t:			DAMON target of @r.
2874  * @r:			DAMON region to populate the directory for.
2875  * @s:			Corresponding scheme.
2876  * @total_bytes_only:	Whether the request is for bytes update only.
2877  * @sz_filter_passed:	Bytes of @r that passed filters of @s.
2878  *
2879  * Called from DAMOS walk callback while holding damon_sysfs_lock.
2880  */
2881 void damos_sysfs_populate_region_dir(struct damon_sysfs_schemes *sysfs_schemes,
2882 		struct damon_ctx *ctx, struct damon_target *t,
2883 		struct damon_region *r, struct damos *s, bool total_bytes_only,
2884 		unsigned long sz_filter_passed)
2885 {
2886 	struct damos *scheme;
2887 	struct damon_sysfs_scheme_regions *sysfs_regions;
2888 	struct damon_sysfs_scheme_region *region;
2889 	int schemes_idx = 0;
2890 
2891 	damon_for_each_scheme(scheme, ctx) {
2892 		if (scheme == s)
2893 			break;
2894 		schemes_idx++;
2895 	}
2896 
2897 	/* user could have removed the scheme sysfs dir */
2898 	if (schemes_idx >= sysfs_schemes->nr)
2899 		return;
2900 
2901 	sysfs_regions = sysfs_schemes->schemes_arr[schemes_idx]->tried_regions;
2902 	sysfs_regions->total_bytes += r->ar.end - r->ar.start;
2903 	if (total_bytes_only)
2904 		return;
2905 
2906 	region = damon_sysfs_scheme_region_alloc(r);
2907 	if (!region)
2908 		return;
2909 	region->sz_filter_passed = sz_filter_passed;
2910 	list_add_tail(&region->list, &sysfs_regions->regions_list);
2911 	sysfs_regions->nr_regions++;
2912 	if (kobject_init_and_add(&region->kobj,
2913 				&damon_sysfs_scheme_region_ktype,
2914 				&sysfs_regions->kobj, "%d",
2915 				sysfs_regions->nr_regions++)) {
2916 		kobject_put(&region->kobj);
2917 	}
2918 }
2919 
2920 int damon_sysfs_schemes_clear_regions(
2921 		struct damon_sysfs_schemes *sysfs_schemes)
2922 {
2923 	int i;
2924 
2925 	for (i = 0; i < sysfs_schemes->nr; i++) {
2926 		struct damon_sysfs_scheme *sysfs_scheme;
2927 
2928 		sysfs_scheme = sysfs_schemes->schemes_arr[i];
2929 		damon_sysfs_scheme_regions_rm_dirs(
2930 				sysfs_scheme->tried_regions);
2931 		sysfs_scheme->tried_regions->total_bytes = 0;
2932 	}
2933 	return 0;
2934 }
2935