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