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