xref: /linux/mm/damon/sysfs.c (revision 51bd0de225a7c8488e53056cd35d89cd1cfc1e71)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * DAMON sysfs Interface
4  */
5 
6 #include <linux/pid.h>
7 #include <linux/sched.h>
8 #include <linux/slab.h>
9 
10 #include "sysfs-common.h"
11 
12 /*
13  * init region directory
14  */
15 
16 struct damon_sysfs_region {
17 	struct kobject kobj;
18 	struct damon_addr_range ar;
19 };
20 
21 static struct damon_sysfs_region *damon_sysfs_region_alloc(void)
22 {
23 	return kzalloc_obj(struct damon_sysfs_region);
24 }
25 
26 static ssize_t start_show(struct kobject *kobj, struct kobj_attribute *attr,
27 		char *buf)
28 {
29 	struct damon_sysfs_region *region = container_of(kobj,
30 			struct damon_sysfs_region, kobj);
31 
32 	return sysfs_emit(buf, "%lu\n", region->ar.start);
33 }
34 
35 static ssize_t start_store(struct kobject *kobj, struct kobj_attribute *attr,
36 		const char *buf, size_t count)
37 {
38 	struct damon_sysfs_region *region = container_of(kobj,
39 			struct damon_sysfs_region, kobj);
40 	int err = kstrtoul(buf, 0, &region->ar.start);
41 
42 	return err ? err : count;
43 }
44 
45 static ssize_t end_show(struct kobject *kobj, struct kobj_attribute *attr,
46 		char *buf)
47 {
48 	struct damon_sysfs_region *region = container_of(kobj,
49 			struct damon_sysfs_region, kobj);
50 
51 	return sysfs_emit(buf, "%lu\n", region->ar.end);
52 }
53 
54 static ssize_t end_store(struct kobject *kobj, struct kobj_attribute *attr,
55 		const char *buf, size_t count)
56 {
57 	struct damon_sysfs_region *region = container_of(kobj,
58 			struct damon_sysfs_region, kobj);
59 	int err = kstrtoul(buf, 0, &region->ar.end);
60 
61 	return err ? err : count;
62 }
63 
64 static void damon_sysfs_region_release(struct kobject *kobj)
65 {
66 	kfree(container_of(kobj, struct damon_sysfs_region, kobj));
67 }
68 
69 static struct kobj_attribute damon_sysfs_region_start_attr =
70 		__ATTR_RW_MODE(start, 0600);
71 
72 static struct kobj_attribute damon_sysfs_region_end_attr =
73 		__ATTR_RW_MODE(end, 0600);
74 
75 static struct attribute *damon_sysfs_region_attrs[] = {
76 	&damon_sysfs_region_start_attr.attr,
77 	&damon_sysfs_region_end_attr.attr,
78 	NULL,
79 };
80 ATTRIBUTE_GROUPS(damon_sysfs_region);
81 
82 static const struct kobj_type damon_sysfs_region_ktype = {
83 	.release = damon_sysfs_region_release,
84 	.sysfs_ops = &kobj_sysfs_ops,
85 	.default_groups = damon_sysfs_region_groups,
86 };
87 
88 /*
89  * init_regions directory
90  */
91 
92 struct damon_sysfs_regions {
93 	struct kobject kobj;
94 	struct damon_sysfs_region **regions_arr;
95 	int nr;
96 };
97 
98 static struct damon_sysfs_regions *damon_sysfs_regions_alloc(void)
99 {
100 	return kzalloc_obj(struct damon_sysfs_regions);
101 }
102 
103 static void damon_sysfs_regions_rm_dirs(struct damon_sysfs_regions *regions)
104 {
105 	struct damon_sysfs_region **regions_arr = regions->regions_arr;
106 	int i;
107 
108 	for (i = 0; i < regions->nr; i++) {
109 		kobject_del(&regions_arr[i]->kobj);
110 		kobject_put(&regions_arr[i]->kobj);
111 	}
112 	regions->nr = 0;
113 	kfree(regions_arr);
114 	regions->regions_arr = NULL;
115 }
116 
117 static int damon_sysfs_regions_add_dirs(struct damon_sysfs_regions *regions,
118 		int nr_regions)
119 {
120 	struct damon_sysfs_region **regions_arr, *region;
121 	int err, i;
122 
123 	damon_sysfs_regions_rm_dirs(regions);
124 	if (!nr_regions)
125 		return 0;
126 
127 	regions_arr = kmalloc_objs(*regions_arr, nr_regions,
128 				   GFP_KERNEL | __GFP_NOWARN);
129 	if (!regions_arr)
130 		return -ENOMEM;
131 	regions->regions_arr = regions_arr;
132 
133 	for (i = 0; i < nr_regions; i++) {
134 		region = damon_sysfs_region_alloc();
135 		if (!region) {
136 			damon_sysfs_regions_rm_dirs(regions);
137 			return -ENOMEM;
138 		}
139 
140 		err = kobject_init_and_add(&region->kobj,
141 				&damon_sysfs_region_ktype, &regions->kobj,
142 				"%d", i);
143 		if (err) {
144 			kobject_put(&region->kobj);
145 			damon_sysfs_regions_rm_dirs(regions);
146 			return err;
147 		}
148 
149 		regions_arr[i] = region;
150 		regions->nr++;
151 	}
152 	return 0;
153 }
154 
155 static ssize_t nr_regions_show(struct kobject *kobj,
156 		struct kobj_attribute *attr, char *buf)
157 {
158 	struct damon_sysfs_regions *regions = container_of(kobj,
159 			struct damon_sysfs_regions, kobj);
160 
161 	return sysfs_emit(buf, "%d\n", regions->nr);
162 }
163 
164 static ssize_t nr_regions_store(struct kobject *kobj,
165 		struct kobj_attribute *attr, const char *buf, size_t count)
166 {
167 	struct damon_sysfs_regions *regions;
168 	int nr, err = kstrtoint(buf, 0, &nr);
169 
170 	if (err)
171 		return err;
172 	if (nr < 0)
173 		return -EINVAL;
174 
175 	regions = container_of(kobj, struct damon_sysfs_regions, kobj);
176 
177 	if (!mutex_trylock(&damon_sysfs_lock))
178 		return -EBUSY;
179 	err = damon_sysfs_regions_add_dirs(regions, nr);
180 	mutex_unlock(&damon_sysfs_lock);
181 	if (err)
182 		return err;
183 
184 	return count;
185 }
186 
187 static void damon_sysfs_regions_release(struct kobject *kobj)
188 {
189 	kfree(container_of(kobj, struct damon_sysfs_regions, kobj));
190 }
191 
192 static struct kobj_attribute damon_sysfs_regions_nr_attr =
193 		__ATTR_RW_MODE(nr_regions, 0600);
194 
195 static struct attribute *damon_sysfs_regions_attrs[] = {
196 	&damon_sysfs_regions_nr_attr.attr,
197 	NULL,
198 };
199 ATTRIBUTE_GROUPS(damon_sysfs_regions);
200 
201 static const struct kobj_type damon_sysfs_regions_ktype = {
202 	.release = damon_sysfs_regions_release,
203 	.sysfs_ops = &kobj_sysfs_ops,
204 	.default_groups = damon_sysfs_regions_groups,
205 };
206 
207 /*
208  * target directory
209  */
210 
211 struct damon_sysfs_target {
212 	struct kobject kobj;
213 	struct damon_sysfs_regions *regions;
214 	int pid;
215 	bool obsolete;
216 };
217 
218 static struct damon_sysfs_target *damon_sysfs_target_alloc(void)
219 {
220 	return kzalloc_obj(struct damon_sysfs_target);
221 }
222 
223 static int damon_sysfs_target_add_dirs(struct damon_sysfs_target *target)
224 {
225 	struct damon_sysfs_regions *regions = damon_sysfs_regions_alloc();
226 	int err;
227 
228 	if (!regions)
229 		return -ENOMEM;
230 
231 	err = kobject_init_and_add(&regions->kobj, &damon_sysfs_regions_ktype,
232 			&target->kobj, "regions");
233 	if (err)
234 		kobject_put(&regions->kobj);
235 	else
236 		target->regions = regions;
237 	return err;
238 }
239 
240 static void damon_sysfs_target_rm_dirs(struct damon_sysfs_target *target)
241 {
242 	damon_sysfs_regions_rm_dirs(target->regions);
243 	kobject_put(&target->regions->kobj);
244 }
245 
246 static ssize_t pid_target_show(struct kobject *kobj,
247 		struct kobj_attribute *attr, char *buf)
248 {
249 	struct damon_sysfs_target *target = container_of(kobj,
250 			struct damon_sysfs_target, kobj);
251 
252 	return sysfs_emit(buf, "%d\n", target->pid);
253 }
254 
255 static ssize_t pid_target_store(struct kobject *kobj,
256 		struct kobj_attribute *attr, const char *buf, size_t count)
257 {
258 	struct damon_sysfs_target *target = container_of(kobj,
259 			struct damon_sysfs_target, kobj);
260 	int err = kstrtoint(buf, 0, &target->pid);
261 
262 	if (err)
263 		return -EINVAL;
264 	return count;
265 }
266 
267 static ssize_t obsolete_target_show(struct kobject *kobj,
268 		struct kobj_attribute *attr, char *buf)
269 {
270 	struct damon_sysfs_target *target = container_of(kobj,
271 			struct damon_sysfs_target, kobj);
272 
273 	return sysfs_emit(buf, "%c\n", target->obsolete ? 'Y' : 'N');
274 }
275 
276 static ssize_t obsolete_target_store(struct kobject *kobj,
277 		struct kobj_attribute *attr, const char *buf, size_t count)
278 {
279 	struct damon_sysfs_target *target = container_of(kobj,
280 			struct damon_sysfs_target, kobj);
281 	bool obsolete;
282 	int err = kstrtobool(buf, &obsolete);
283 
284 	if (err)
285 		return err;
286 	target->obsolete = obsolete;
287 	return count;
288 }
289 
290 static void damon_sysfs_target_release(struct kobject *kobj)
291 {
292 	kfree(container_of(kobj, struct damon_sysfs_target, kobj));
293 }
294 
295 static struct kobj_attribute damon_sysfs_target_pid_attr =
296 		__ATTR_RW_MODE(pid_target, 0600);
297 
298 static struct kobj_attribute damon_sysfs_target_obsolete_attr =
299 		__ATTR_RW_MODE(obsolete_target, 0600);
300 
301 static struct attribute *damon_sysfs_target_attrs[] = {
302 	&damon_sysfs_target_pid_attr.attr,
303 	&damon_sysfs_target_obsolete_attr.attr,
304 	NULL,
305 };
306 ATTRIBUTE_GROUPS(damon_sysfs_target);
307 
308 static const struct kobj_type damon_sysfs_target_ktype = {
309 	.release = damon_sysfs_target_release,
310 	.sysfs_ops = &kobj_sysfs_ops,
311 	.default_groups = damon_sysfs_target_groups,
312 };
313 
314 /*
315  * targets directory
316  */
317 
318 struct damon_sysfs_targets {
319 	struct kobject kobj;
320 	struct damon_sysfs_target **targets_arr;
321 	int nr;
322 };
323 
324 static struct damon_sysfs_targets *damon_sysfs_targets_alloc(void)
325 {
326 	return kzalloc_obj(struct damon_sysfs_targets);
327 }
328 
329 static void damon_sysfs_targets_rm_dirs(struct damon_sysfs_targets *targets)
330 {
331 	struct damon_sysfs_target **targets_arr = targets->targets_arr;
332 	int i;
333 
334 	for (i = 0; i < targets->nr; i++) {
335 		damon_sysfs_target_rm_dirs(targets_arr[i]);
336 		kobject_del(&targets_arr[i]->kobj);
337 		kobject_put(&targets_arr[i]->kobj);
338 	}
339 	targets->nr = 0;
340 	kfree(targets_arr);
341 	targets->targets_arr = NULL;
342 }
343 
344 static int damon_sysfs_targets_add_dirs(struct damon_sysfs_targets *targets,
345 		int nr_targets)
346 {
347 	struct damon_sysfs_target **targets_arr, *target;
348 	int err, i;
349 
350 	damon_sysfs_targets_rm_dirs(targets);
351 	if (!nr_targets)
352 		return 0;
353 
354 	targets_arr = kmalloc_objs(*targets_arr, nr_targets,
355 				   GFP_KERNEL | __GFP_NOWARN);
356 	if (!targets_arr)
357 		return -ENOMEM;
358 	targets->targets_arr = targets_arr;
359 
360 	for (i = 0; i < nr_targets; i++) {
361 		target = damon_sysfs_target_alloc();
362 		if (!target) {
363 			damon_sysfs_targets_rm_dirs(targets);
364 			return -ENOMEM;
365 		}
366 
367 		err = kobject_init_and_add(&target->kobj,
368 				&damon_sysfs_target_ktype, &targets->kobj,
369 				"%d", i);
370 		if (err)
371 			goto out;
372 
373 		err = damon_sysfs_target_add_dirs(target);
374 		if (err)
375 			goto del_out;
376 
377 		targets_arr[i] = target;
378 		targets->nr++;
379 	}
380 	return 0;
381 
382 del_out:
383 	kobject_del(&target->kobj);
384 out:
385 	damon_sysfs_targets_rm_dirs(targets);
386 	kobject_put(&target->kobj);
387 	return err;
388 }
389 
390 static ssize_t nr_targets_show(struct kobject *kobj,
391 		struct kobj_attribute *attr, char *buf)
392 {
393 	struct damon_sysfs_targets *targets = container_of(kobj,
394 			struct damon_sysfs_targets, kobj);
395 
396 	return sysfs_emit(buf, "%d\n", targets->nr);
397 }
398 
399 static ssize_t nr_targets_store(struct kobject *kobj,
400 		struct kobj_attribute *attr, const char *buf, size_t count)
401 {
402 	struct damon_sysfs_targets *targets;
403 	int nr, err = kstrtoint(buf, 0, &nr);
404 
405 	if (err)
406 		return err;
407 	if (nr < 0)
408 		return -EINVAL;
409 
410 	targets = container_of(kobj, struct damon_sysfs_targets, kobj);
411 
412 	if (!mutex_trylock(&damon_sysfs_lock))
413 		return -EBUSY;
414 	err = damon_sysfs_targets_add_dirs(targets, nr);
415 	mutex_unlock(&damon_sysfs_lock);
416 	if (err)
417 		return err;
418 
419 	return count;
420 }
421 
422 static void damon_sysfs_targets_release(struct kobject *kobj)
423 {
424 	kfree(container_of(kobj, struct damon_sysfs_targets, kobj));
425 }
426 
427 static struct kobj_attribute damon_sysfs_targets_nr_attr =
428 		__ATTR_RW_MODE(nr_targets, 0600);
429 
430 static struct attribute *damon_sysfs_targets_attrs[] = {
431 	&damon_sysfs_targets_nr_attr.attr,
432 	NULL,
433 };
434 ATTRIBUTE_GROUPS(damon_sysfs_targets);
435 
436 static const struct kobj_type damon_sysfs_targets_ktype = {
437 	.release = damon_sysfs_targets_release,
438 	.sysfs_ops = &kobj_sysfs_ops,
439 	.default_groups = damon_sysfs_targets_groups,
440 };
441 
442 /*
443  * intervals goal directory
444  */
445 
446 struct damon_sysfs_intervals_goal {
447 	struct kobject kobj;
448 	unsigned long access_bp;
449 	unsigned long aggrs;
450 	unsigned long min_sample_us;
451 	unsigned long max_sample_us;
452 };
453 
454 static struct damon_sysfs_intervals_goal *damon_sysfs_intervals_goal_alloc(
455 		unsigned long access_bp, unsigned long aggrs,
456 		unsigned long min_sample_us, unsigned long max_sample_us)
457 {
458 	struct damon_sysfs_intervals_goal *goal = kmalloc_obj(*goal);
459 
460 	if (!goal)
461 		return NULL;
462 
463 	goal->kobj = (struct kobject){};
464 	goal->access_bp = access_bp;
465 	goal->aggrs = aggrs;
466 	goal->min_sample_us = min_sample_us;
467 	goal->max_sample_us = max_sample_us;
468 	return goal;
469 }
470 
471 static ssize_t access_bp_show(struct kobject *kobj,
472 		struct kobj_attribute *attr, char *buf)
473 {
474 	struct damon_sysfs_intervals_goal *goal = container_of(kobj,
475 			struct damon_sysfs_intervals_goal, kobj);
476 
477 	return sysfs_emit(buf, "%lu\n", goal->access_bp);
478 }
479 
480 static ssize_t access_bp_store(struct kobject *kobj,
481 		struct kobj_attribute *attr, const char *buf, size_t count)
482 {
483 	struct damon_sysfs_intervals_goal *goal = container_of(kobj,
484 			struct damon_sysfs_intervals_goal, kobj);
485 	unsigned long nr;
486 	int err = kstrtoul(buf, 0, &nr);
487 
488 	if (err)
489 		return err;
490 
491 	goal->access_bp = nr;
492 	return count;
493 }
494 
495 static ssize_t aggrs_show(struct kobject *kobj,
496 		struct kobj_attribute *attr, char *buf)
497 {
498 	struct damon_sysfs_intervals_goal *goal = container_of(kobj,
499 			struct damon_sysfs_intervals_goal, kobj);
500 
501 	return sysfs_emit(buf, "%lu\n", goal->aggrs);
502 }
503 
504 static ssize_t aggrs_store(struct kobject *kobj,
505 		struct kobj_attribute *attr, const char *buf, size_t count)
506 {
507 	struct damon_sysfs_intervals_goal *goal = container_of(kobj,
508 			struct damon_sysfs_intervals_goal, kobj);
509 	unsigned long nr;
510 	int err = kstrtoul(buf, 0, &nr);
511 
512 	if (err)
513 		return err;
514 
515 	goal->aggrs = nr;
516 	return count;
517 }
518 
519 static ssize_t min_sample_us_show(struct kobject *kobj,
520 		struct kobj_attribute *attr, char *buf)
521 {
522 	struct damon_sysfs_intervals_goal *goal = container_of(kobj,
523 			struct damon_sysfs_intervals_goal, kobj);
524 
525 	return sysfs_emit(buf, "%lu\n", goal->min_sample_us);
526 }
527 
528 static ssize_t min_sample_us_store(struct kobject *kobj,
529 		struct kobj_attribute *attr, const char *buf, size_t count)
530 {
531 	struct damon_sysfs_intervals_goal *goal = container_of(kobj,
532 			struct damon_sysfs_intervals_goal, kobj);
533 	unsigned long nr;
534 	int err = kstrtoul(buf, 0, &nr);
535 
536 	if (err)
537 		return err;
538 
539 	goal->min_sample_us = nr;
540 	return count;
541 }
542 
543 static ssize_t max_sample_us_show(struct kobject *kobj,
544 		struct kobj_attribute *attr, char *buf)
545 {
546 	struct damon_sysfs_intervals_goal *goal = container_of(kobj,
547 			struct damon_sysfs_intervals_goal, kobj);
548 
549 	return sysfs_emit(buf, "%lu\n", goal->max_sample_us);
550 }
551 
552 static ssize_t max_sample_us_store(struct kobject *kobj,
553 		struct kobj_attribute *attr, const char *buf, size_t count)
554 {
555 	struct damon_sysfs_intervals_goal *goal = container_of(kobj,
556 			struct damon_sysfs_intervals_goal, kobj);
557 	unsigned long nr;
558 	int err = kstrtoul(buf, 0, &nr);
559 
560 	if (err)
561 		return err;
562 
563 	goal->max_sample_us = nr;
564 	return count;
565 }
566 
567 static void damon_sysfs_intervals_goal_release(struct kobject *kobj)
568 {
569 	kfree(container_of(kobj, struct damon_sysfs_intervals_goal, kobj));
570 }
571 
572 static struct kobj_attribute damon_sysfs_intervals_goal_access_bp_attr =
573 		__ATTR_RW_MODE(access_bp, 0600);
574 
575 static struct kobj_attribute damon_sysfs_intervals_goal_aggrs_attr =
576 		__ATTR_RW_MODE(aggrs, 0600);
577 
578 static struct kobj_attribute damon_sysfs_intervals_goal_min_sample_us_attr =
579 		__ATTR_RW_MODE(min_sample_us, 0600);
580 
581 static struct kobj_attribute damon_sysfs_intervals_goal_max_sample_us_attr =
582 		__ATTR_RW_MODE(max_sample_us, 0600);
583 
584 static struct attribute *damon_sysfs_intervals_goal_attrs[] = {
585 	&damon_sysfs_intervals_goal_access_bp_attr.attr,
586 	&damon_sysfs_intervals_goal_aggrs_attr.attr,
587 	&damon_sysfs_intervals_goal_min_sample_us_attr.attr,
588 	&damon_sysfs_intervals_goal_max_sample_us_attr.attr,
589 	NULL,
590 };
591 ATTRIBUTE_GROUPS(damon_sysfs_intervals_goal);
592 
593 static const struct kobj_type damon_sysfs_intervals_goal_ktype = {
594 	.release = damon_sysfs_intervals_goal_release,
595 	.sysfs_ops = &kobj_sysfs_ops,
596 	.default_groups = damon_sysfs_intervals_goal_groups,
597 };
598 
599 /*
600  * intervals directory
601  */
602 
603 struct damon_sysfs_intervals {
604 	struct kobject kobj;
605 	unsigned long sample_us;
606 	unsigned long aggr_us;
607 	unsigned long update_us;
608 	struct damon_sysfs_intervals_goal *intervals_goal;
609 };
610 
611 static struct damon_sysfs_intervals *damon_sysfs_intervals_alloc(
612 		unsigned long sample_us, unsigned long aggr_us,
613 		unsigned long update_us)
614 {
615 	struct damon_sysfs_intervals *intervals = kmalloc_obj(*intervals);
616 
617 	if (!intervals)
618 		return NULL;
619 
620 	intervals->kobj = (struct kobject){};
621 	intervals->sample_us = sample_us;
622 	intervals->aggr_us = aggr_us;
623 	intervals->update_us = update_us;
624 	return intervals;
625 }
626 
627 static int damon_sysfs_intervals_add_dirs(struct damon_sysfs_intervals *intervals)
628 {
629 	struct damon_sysfs_intervals_goal *goal;
630 	int err;
631 
632 	goal = damon_sysfs_intervals_goal_alloc(0, 0, 0, 0);
633 	if (!goal)
634 		return -ENOMEM;
635 
636 	err = kobject_init_and_add(&goal->kobj,
637 			&damon_sysfs_intervals_goal_ktype, &intervals->kobj,
638 			"intervals_goal");
639 	if (err) {
640 		kobject_put(&goal->kobj);
641 		intervals->intervals_goal = NULL;
642 		return err;
643 	}
644 	intervals->intervals_goal = goal;
645 	return 0;
646 }
647 
648 static void damon_sysfs_intervals_rm_dirs(struct damon_sysfs_intervals *intervals)
649 {
650 	kobject_put(&intervals->intervals_goal->kobj);
651 }
652 
653 static ssize_t sample_us_show(struct kobject *kobj,
654 		struct kobj_attribute *attr, char *buf)
655 {
656 	struct damon_sysfs_intervals *intervals = container_of(kobj,
657 			struct damon_sysfs_intervals, kobj);
658 
659 	return sysfs_emit(buf, "%lu\n", intervals->sample_us);
660 }
661 
662 static ssize_t sample_us_store(struct kobject *kobj,
663 		struct kobj_attribute *attr, const char *buf, size_t count)
664 {
665 	struct damon_sysfs_intervals *intervals = container_of(kobj,
666 			struct damon_sysfs_intervals, kobj);
667 	unsigned long us;
668 	int err = kstrtoul(buf, 0, &us);
669 
670 	if (err)
671 		return err;
672 
673 	intervals->sample_us = us;
674 	return count;
675 }
676 
677 static ssize_t aggr_us_show(struct kobject *kobj, struct kobj_attribute *attr,
678 		char *buf)
679 {
680 	struct damon_sysfs_intervals *intervals = container_of(kobj,
681 			struct damon_sysfs_intervals, kobj);
682 
683 	return sysfs_emit(buf, "%lu\n", intervals->aggr_us);
684 }
685 
686 static ssize_t aggr_us_store(struct kobject *kobj, struct kobj_attribute *attr,
687 		const char *buf, size_t count)
688 {
689 	struct damon_sysfs_intervals *intervals = container_of(kobj,
690 			struct damon_sysfs_intervals, kobj);
691 	unsigned long us;
692 	int err = kstrtoul(buf, 0, &us);
693 
694 	if (err)
695 		return err;
696 
697 	intervals->aggr_us = us;
698 	return count;
699 }
700 
701 static ssize_t update_us_show(struct kobject *kobj,
702 		struct kobj_attribute *attr, char *buf)
703 {
704 	struct damon_sysfs_intervals *intervals = container_of(kobj,
705 			struct damon_sysfs_intervals, kobj);
706 
707 	return sysfs_emit(buf, "%lu\n", intervals->update_us);
708 }
709 
710 static ssize_t update_us_store(struct kobject *kobj,
711 		struct kobj_attribute *attr, const char *buf, size_t count)
712 {
713 	struct damon_sysfs_intervals *intervals = container_of(kobj,
714 			struct damon_sysfs_intervals, kobj);
715 	unsigned long us;
716 	int err = kstrtoul(buf, 0, &us);
717 
718 	if (err)
719 		return err;
720 
721 	intervals->update_us = us;
722 	return count;
723 }
724 
725 static void damon_sysfs_intervals_release(struct kobject *kobj)
726 {
727 	kfree(container_of(kobj, struct damon_sysfs_intervals, kobj));
728 }
729 
730 static struct kobj_attribute damon_sysfs_intervals_sample_us_attr =
731 		__ATTR_RW_MODE(sample_us, 0600);
732 
733 static struct kobj_attribute damon_sysfs_intervals_aggr_us_attr =
734 		__ATTR_RW_MODE(aggr_us, 0600);
735 
736 static struct kobj_attribute damon_sysfs_intervals_update_us_attr =
737 		__ATTR_RW_MODE(update_us, 0600);
738 
739 static struct attribute *damon_sysfs_intervals_attrs[] = {
740 	&damon_sysfs_intervals_sample_us_attr.attr,
741 	&damon_sysfs_intervals_aggr_us_attr.attr,
742 	&damon_sysfs_intervals_update_us_attr.attr,
743 	NULL,
744 };
745 ATTRIBUTE_GROUPS(damon_sysfs_intervals);
746 
747 static const struct kobj_type damon_sysfs_intervals_ktype = {
748 	.release = damon_sysfs_intervals_release,
749 	.sysfs_ops = &kobj_sysfs_ops,
750 	.default_groups = damon_sysfs_intervals_groups,
751 };
752 
753 /*
754  * filter directory
755  */
756 
757 struct damon_sysfs_filter {
758 	struct kobject kobj;
759 	enum damon_filter_type type;
760 	bool matching;
761 	bool allow;
762 	char *path;
763 };
764 
765 static struct damon_sysfs_filter *damon_sysfs_filter_alloc(void)
766 {
767 	return kzalloc_obj(struct damon_sysfs_filter);
768 }
769 
770 struct damon_sysfs_filter_type_name {
771 	enum damon_filter_type type;
772 	char *name;
773 };
774 
775 static const struct damon_sysfs_filter_type_name
776 damon_sysfs_filter_type_names[] = {
777 	{
778 		.type = DAMON_FILTER_TYPE_ANON,
779 		.name = "anon",
780 	},
781 	{
782 		.type = DAMON_FILTER_TYPE_MEMCG,
783 		.name = "memcg",
784 	},
785 };
786 
787 static ssize_t type_show(struct kobject *kobj,
788 		struct kobj_attribute *attr, char *buf)
789 {
790 	struct damon_sysfs_filter *filter = container_of(kobj,
791 			struct damon_sysfs_filter, kobj);
792 	int i;
793 
794 	for (i = 0; i < ARRAY_SIZE(damon_sysfs_filter_type_names); i++) {
795 		const struct damon_sysfs_filter_type_name *type_name;
796 
797 		type_name = &damon_sysfs_filter_type_names[i];
798 		if (type_name->type == filter->type)
799 			return sysfs_emit(buf, "%s\n", type_name->name);
800 	}
801 	return -EINVAL;
802 }
803 
804 static ssize_t type_store(struct kobject *kobj,
805 		struct kobj_attribute *attr, const char *buf, size_t count)
806 {
807 	struct damon_sysfs_filter *filter = container_of(kobj,
808 			struct damon_sysfs_filter, kobj);
809 	ssize_t ret = -EINVAL;
810 	int i;
811 
812 	for (i = 0; i < ARRAY_SIZE(damon_sysfs_filter_type_names); i++) {
813 		const struct damon_sysfs_filter_type_name *type_name;
814 
815 		type_name = &damon_sysfs_filter_type_names[i];
816 		if (sysfs_streq(buf, type_name->name)) {
817 			filter->type = type_name->type;
818 			ret = count;
819 			break;
820 		}
821 	}
822 	return ret;
823 }
824 
825 static ssize_t matching_show(struct kobject *kobj,
826 		struct kobj_attribute *attr, char *buf)
827 {
828 	struct damon_sysfs_filter *filter = container_of(kobj,
829 			struct damon_sysfs_filter, kobj);
830 
831 	return sysfs_emit(buf, "%c\n", filter->matching ? 'Y' : 'N');
832 }
833 
834 static ssize_t matching_store(struct kobject *kobj,
835 		struct kobj_attribute *attr, const char *buf, size_t count)
836 {
837 	struct damon_sysfs_filter *filter = container_of(kobj,
838 			struct damon_sysfs_filter, kobj);
839 	bool matching;
840 	int err = kstrtobool(buf, &matching);
841 
842 	if (err)
843 		return err;
844 
845 	filter->matching = matching;
846 	return count;
847 }
848 
849 static ssize_t allow_show(struct kobject *kobj,
850 		struct kobj_attribute *attr, char *buf)
851 {
852 	struct damon_sysfs_filter *filter = container_of(kobj,
853 			struct damon_sysfs_filter, kobj);
854 
855 	return sysfs_emit(buf, "%c\n", filter->allow ? 'Y' : 'N');
856 }
857 
858 static ssize_t allow_store(struct kobject *kobj,
859 		struct kobj_attribute *attr, const char *buf, size_t count)
860 {
861 	struct damon_sysfs_filter *filter = container_of(kobj,
862 			struct damon_sysfs_filter, kobj);
863 	bool allow;
864 	int err = kstrtobool(buf, &allow);
865 
866 	if (err)
867 		return err;
868 
869 	filter->allow = allow;
870 	return count;
871 }
872 
873 static ssize_t path_show(struct kobject *kobj,
874 		struct kobj_attribute *attr, char *buf)
875 {
876 	struct damon_sysfs_filter *filter = container_of(kobj,
877 			struct damon_sysfs_filter, kobj);
878 	int len;
879 
880 	if (!mutex_trylock(&damon_sysfs_lock))
881 		return -EBUSY;
882 	len = sysfs_emit(buf, "%s\n", filter->path ? filter->path : "");
883 	mutex_unlock(&damon_sysfs_lock);
884 	return len;
885 }
886 
887 static ssize_t path_store(struct kobject *kobj,
888 		struct kobj_attribute *attr, const char *buf, size_t count)
889 {
890 	struct damon_sysfs_filter *filter = container_of(kobj,
891 			struct damon_sysfs_filter, kobj);
892 	char *path = kmalloc_objs(*path, size_add(count, 1));
893 
894 	if (!path)
895 		return -ENOMEM;
896 	strscpy(path, buf, size_add(count, 1));
897 	if (!mutex_trylock(&damon_sysfs_lock)) {
898 		kfree(path);
899 		return -EBUSY;
900 	}
901 	kfree(filter->path);
902 	filter->path = path;
903 	mutex_unlock(&damon_sysfs_lock);
904 	return count;
905 }
906 
907 static void damon_sysfs_filter_release(struct kobject *kobj)
908 {
909 	struct damon_sysfs_filter *filter = container_of(kobj,
910 			struct damon_sysfs_filter, kobj);
911 
912 	kfree(filter->path);
913 	kfree(filter);
914 }
915 
916 static struct kobj_attribute damon_sysfs_filter_type_attr =
917 		__ATTR_RW_MODE(type, 0600);
918 
919 static struct kobj_attribute damon_sysfs_filter_matching_attr =
920 		__ATTR_RW_MODE(matching, 0600);
921 
922 static struct kobj_attribute damon_sysfs_filter_allow_attr =
923 		__ATTR_RW_MODE(allow, 0600);
924 
925 static struct kobj_attribute damon_sysfs_filter_path_attr =
926 		__ATTR_RW_MODE(path, 0600);
927 
928 static struct attribute *damon_sysfs_filter_attrs[] = {
929 	&damon_sysfs_filter_type_attr.attr,
930 	&damon_sysfs_filter_matching_attr.attr,
931 	&damon_sysfs_filter_allow_attr.attr,
932 	&damon_sysfs_filter_path_attr.attr,
933 	NULL,
934 };
935 ATTRIBUTE_GROUPS(damon_sysfs_filter);
936 
937 static const struct kobj_type damon_sysfs_filter_ktype = {
938 	.release = damon_sysfs_filter_release,
939 	.sysfs_ops = &kobj_sysfs_ops,
940 	.default_groups = damon_sysfs_filter_groups,
941 };
942 
943 /*
944  * filters directory
945  */
946 
947 struct damon_sysfs_filters {
948 	struct kobject kobj;
949 	struct damon_sysfs_filter **filters_arr;
950 	int nr;
951 };
952 
953 static struct damon_sysfs_filters *damon_sysfs_filters_alloc(void)
954 {
955 	return kzalloc_obj(struct damon_sysfs_filters);
956 }
957 
958 static void damon_sysfs_filters_rm_dirs(struct damon_sysfs_filters *filters)
959 {
960 	struct damon_sysfs_filter **filters_arr = filters->filters_arr;
961 	int i;
962 
963 	for (i = 0; i < filters->nr; i++) {
964 		kobject_del(&filters_arr[i]->kobj);
965 		kobject_put(&filters_arr[i]->kobj);
966 	}
967 	filters->nr = 0;
968 	kfree(filters_arr);
969 	filters->filters_arr = NULL;
970 }
971 
972 static int damon_sysfs_filters_add_dirs(
973 		struct damon_sysfs_filters *filters, int nr_filters)
974 {
975 	struct damon_sysfs_filter **filters_arr, *filter;
976 	int err, i;
977 
978 	damon_sysfs_filters_rm_dirs(filters);
979 	if (!nr_filters)
980 		return 0;
981 
982 	filters_arr = kmalloc_objs(*filters_arr, nr_filters,
983 				   GFP_KERNEL | __GFP_NOWARN);
984 	if (!filters_arr)
985 		return -ENOMEM;
986 	filters->filters_arr = filters_arr;
987 
988 	for (i = 0; i < nr_filters; i++) {
989 		filter = damon_sysfs_filter_alloc();
990 		if (!filter) {
991 			damon_sysfs_filters_rm_dirs(filters);
992 			return -ENOMEM;
993 		}
994 
995 		err = kobject_init_and_add(&filter->kobj,
996 				&damon_sysfs_filter_ktype, &filters->kobj,
997 				"%d", i);
998 		if (err) {
999 			kobject_put(&filter->kobj);
1000 			damon_sysfs_filters_rm_dirs(filters);
1001 			return err;
1002 		}
1003 
1004 		filters_arr[i] = filter;
1005 		filters->nr++;
1006 	}
1007 	return 0;
1008 }
1009 
1010 static ssize_t nr_filters_show(struct kobject *kobj,
1011 		struct kobj_attribute *attr, char *buf)
1012 {
1013 	struct damon_sysfs_filters *filters = container_of(kobj,
1014 			struct damon_sysfs_filters, kobj);
1015 
1016 	return sysfs_emit(buf, "%d\n", filters->nr);
1017 }
1018 
1019 static ssize_t nr_filters_store(struct kobject *kobj,
1020 		struct kobj_attribute *attr, const char *buf, size_t count)
1021 {
1022 	struct damon_sysfs_filters *filters;
1023 	int nr, err = kstrtoint(buf, 0, &nr);
1024 
1025 	if (err)
1026 		return err;
1027 	if (nr < 0)
1028 		return -EINVAL;
1029 
1030 	filters = container_of(kobj, struct damon_sysfs_filters, kobj);
1031 
1032 	if (!mutex_trylock(&damon_sysfs_lock))
1033 		return -EBUSY;
1034 	err = damon_sysfs_filters_add_dirs(filters, nr);
1035 	mutex_unlock(&damon_sysfs_lock);
1036 	if (err)
1037 		return err;
1038 
1039 	return count;
1040 }
1041 
1042 static void damon_sysfs_filters_release(struct kobject *kobj)
1043 {
1044 	kfree(container_of(kobj, struct damon_sysfs_filters, kobj));
1045 }
1046 
1047 static struct kobj_attribute damon_sysfs_filters_nr_attr =
1048 		__ATTR_RW_MODE(nr_filters, 0600);
1049 
1050 static struct attribute *damon_sysfs_filters_attrs[] = {
1051 	&damon_sysfs_filters_nr_attr.attr,
1052 	NULL,
1053 };
1054 ATTRIBUTE_GROUPS(damon_sysfs_filters);
1055 
1056 static const struct kobj_type damon_sysfs_filters_ktype = {
1057 	.release = damon_sysfs_filters_release,
1058 	.sysfs_ops = &kobj_sysfs_ops,
1059 	.default_groups = damon_sysfs_filters_groups,
1060 };
1061 
1062 /*
1063  * probe directory
1064  */
1065 
1066 struct damon_sysfs_probe {
1067 	struct kobject kobj;
1068 	struct damon_sysfs_filters *filters;
1069 };
1070 
1071 static struct damon_sysfs_probe *damon_sysfs_probe_alloc(void)
1072 {
1073 	return kzalloc_obj(struct damon_sysfs_probe);
1074 }
1075 
1076 static int damon_sysfs_probe_add_dirs(struct damon_sysfs_probe *probe)
1077 {
1078 	struct damon_sysfs_filters *filters;
1079 	int err;
1080 
1081 	filters = damon_sysfs_filters_alloc();
1082 	if (!filters)
1083 		return -ENOMEM;
1084 	probe->filters = filters;
1085 
1086 	err = kobject_init_and_add(&filters->kobj, &damon_sysfs_filters_ktype,
1087 			&probe->kobj, "filters");
1088 	if (err) {
1089 		kobject_put(&filters->kobj);
1090 		probe->filters = NULL;
1091 	}
1092 	return err;
1093 }
1094 
1095 static void damon_sysfs_probe_rm_dirs(struct damon_sysfs_probe *probe)
1096 {
1097 	if (probe->filters) {
1098 		damon_sysfs_filters_rm_dirs(probe->filters);
1099 		kobject_put(&probe->filters->kobj);
1100 	}
1101 }
1102 
1103 static void damon_sysfs_probe_release(struct kobject *kobj)
1104 {
1105 	kfree(container_of(kobj, struct damon_sysfs_probe, kobj));
1106 }
1107 
1108 static struct attribute *damon_sysfs_probe_attrs[] = {
1109 	NULL,
1110 };
1111 ATTRIBUTE_GROUPS(damon_sysfs_probe);
1112 
1113 static const struct kobj_type damon_sysfs_probe_ktype = {
1114 	.release = damon_sysfs_probe_release,
1115 	.sysfs_ops = &kobj_sysfs_ops,
1116 	.default_groups = damon_sysfs_probe_groups,
1117 };
1118 
1119 /*
1120  * probes directory
1121  */
1122 
1123 struct damon_sysfs_probes {
1124 	struct kobject kobj;
1125 	struct damon_sysfs_probe **probes_arr;
1126 	int nr;
1127 };
1128 
1129 static struct damon_sysfs_probes *damon_sysfs_probes_alloc(void)
1130 {
1131 	return kzalloc_obj(struct damon_sysfs_probes);
1132 }
1133 
1134 static void damon_sysfs_probes_rm_dirs(
1135 		struct damon_sysfs_probes *probes)
1136 {
1137 	struct damon_sysfs_probe **probes_arr = probes->probes_arr;
1138 	int i;
1139 
1140 	for (i = 0; i < probes->nr; i++) {
1141 		damon_sysfs_probe_rm_dirs(probes_arr[i]);
1142 		kobject_del(&probes_arr[i]->kobj);
1143 		kobject_put(&probes_arr[i]->kobj);
1144 	}
1145 	probes->nr = 0;
1146 	kfree(probes_arr);
1147 	probes->probes_arr = NULL;
1148 }
1149 
1150 static int damon_sysfs_probes_add_dirs(
1151 		struct damon_sysfs_probes *probes, int nr_probes)
1152 {
1153 	struct damon_sysfs_probe **probes_arr, *probe;
1154 	int err, i;
1155 
1156 	damon_sysfs_probes_rm_dirs(probes);
1157 	if (!nr_probes)
1158 		return 0;
1159 
1160 	probes_arr = kmalloc_objs(*probes_arr, nr_probes,
1161 				   GFP_KERNEL | __GFP_NOWARN);
1162 	if (!probes_arr)
1163 		return -ENOMEM;
1164 	probes->probes_arr = probes_arr;
1165 
1166 	for (i = 0; i < nr_probes; i++) {
1167 		probe = damon_sysfs_probe_alloc();
1168 		if (!probe) {
1169 			damon_sysfs_probes_rm_dirs(probes);
1170 			return -ENOMEM;
1171 		}
1172 
1173 		err = kobject_init_and_add(&probe->kobj,
1174 				&damon_sysfs_probe_ktype, &probes->kobj,
1175 				"%d", i);
1176 		if (err) {
1177 			kobject_put(&probe->kobj);
1178 			damon_sysfs_probes_rm_dirs(probes);
1179 			return err;
1180 		}
1181 
1182 		err = damon_sysfs_probe_add_dirs(probe);
1183 		if (err) {
1184 			kobject_del(&probe->kobj);
1185 			kobject_put(&probe->kobj);
1186 			damon_sysfs_probes_rm_dirs(probes);
1187 			return err;
1188 		}
1189 
1190 		probes_arr[i] = probe;
1191 		probes->nr++;
1192 	}
1193 	return 0;
1194 }
1195 
1196 static ssize_t nr_probes_show(struct kobject *kobj,
1197 		struct kobj_attribute *attr, char *buf)
1198 {
1199 	struct damon_sysfs_probes *probes = container_of(kobj,
1200 			struct damon_sysfs_probes, kobj);
1201 
1202 	return sysfs_emit(buf, "%d\n", probes->nr);
1203 }
1204 
1205 static ssize_t nr_probes_store(struct kobject *kobj,
1206 		struct kobj_attribute *attr, const char *buf, size_t count)
1207 {
1208 	struct damon_sysfs_probes *probes;
1209 	int nr, err = kstrtoint(buf, 0, &nr);
1210 
1211 	if (err)
1212 		return err;
1213 	if (nr < 0 || nr > DAMON_MAX_PROBES)
1214 		return -EINVAL;
1215 
1216 	probes = container_of(kobj, struct damon_sysfs_probes, kobj);
1217 
1218 	if (!mutex_trylock(&damon_sysfs_lock))
1219 		return -EBUSY;
1220 	err = damon_sysfs_probes_add_dirs(probes, nr);
1221 	mutex_unlock(&damon_sysfs_lock);
1222 	if (err)
1223 		return err;
1224 
1225 	return count;
1226 }
1227 
1228 static void damon_sysfs_probes_release(struct kobject *kobj)
1229 {
1230 	kfree(container_of(kobj, struct damon_sysfs_probes, kobj));
1231 }
1232 
1233 static struct kobj_attribute damon_sysfs_probes_nr_probes =
1234 		__ATTR_RW_MODE(nr_probes, 0600);
1235 
1236 static struct attribute *damon_sysfs_probes_attrs[] = {
1237 	&damon_sysfs_probes_nr_probes.attr,
1238 	NULL,
1239 };
1240 ATTRIBUTE_GROUPS(damon_sysfs_probes);
1241 
1242 static const struct kobj_type damon_sysfs_probes_ktype = {
1243 	.release = damon_sysfs_probes_release,
1244 	.sysfs_ops = &kobj_sysfs_ops,
1245 	.default_groups = damon_sysfs_probes_groups,
1246 };
1247 
1248 /*
1249  * monitoring_attrs directory
1250  */
1251 
1252 struct damon_sysfs_attrs {
1253 	struct kobject kobj;
1254 	struct damon_sysfs_intervals *intervals;
1255 	struct damon_sysfs_ul_range *nr_regions_range;
1256 	struct damon_sysfs_probes *probes;
1257 };
1258 
1259 static struct damon_sysfs_attrs *damon_sysfs_attrs_alloc(void)
1260 {
1261 	struct damon_sysfs_attrs *attrs = kmalloc_obj(*attrs);
1262 
1263 	if (!attrs)
1264 		return NULL;
1265 	attrs->kobj = (struct kobject){};
1266 	return attrs;
1267 }
1268 
1269 static int damon_sysfs_attrs_add_dirs(struct damon_sysfs_attrs *attrs)
1270 {
1271 	struct damon_sysfs_intervals *intervals;
1272 	struct damon_sysfs_ul_range *nr_regions_range;
1273 	struct damon_sysfs_probes *probes;
1274 	int err;
1275 
1276 	intervals = damon_sysfs_intervals_alloc(5000, 100000, 60000000);
1277 	if (!intervals)
1278 		return -ENOMEM;
1279 
1280 	err = kobject_init_and_add(&intervals->kobj,
1281 			&damon_sysfs_intervals_ktype, &attrs->kobj,
1282 			"intervals");
1283 	if (err)
1284 		goto put_intervals_out;
1285 	err = damon_sysfs_intervals_add_dirs(intervals);
1286 	if (err)
1287 		goto put_intervals_out;
1288 	attrs->intervals = intervals;
1289 
1290 	nr_regions_range = damon_sysfs_ul_range_alloc(10, 1000);
1291 	if (!nr_regions_range) {
1292 		err = -ENOMEM;
1293 		goto rmdir_put_intervals_out;
1294 	}
1295 
1296 	err = kobject_init_and_add(&nr_regions_range->kobj,
1297 			&damon_sysfs_ul_range_ktype, &attrs->kobj,
1298 			"nr_regions");
1299 	if (err)
1300 		goto put_nr_regions_intervals_out;
1301 	attrs->nr_regions_range = nr_regions_range;
1302 
1303 	probes = damon_sysfs_probes_alloc();
1304 	if (!probes) {
1305 		err = -ENOMEM;
1306 		goto put_nr_regions_intervals_out;
1307 	}
1308 	err = kobject_init_and_add(&probes->kobj,
1309 			&damon_sysfs_probes_ktype, &attrs->kobj, "probes");
1310 	if (err)
1311 		goto put_probes_out;
1312 	attrs->probes = probes;
1313 	return 0;
1314 
1315 put_probes_out:
1316 	kobject_put(&probes->kobj);
1317 	attrs->probes = NULL;
1318 put_nr_regions_intervals_out:
1319 	kobject_put(&nr_regions_range->kobj);
1320 	attrs->nr_regions_range = NULL;
1321 rmdir_put_intervals_out:
1322 	damon_sysfs_intervals_rm_dirs(intervals);
1323 put_intervals_out:
1324 	kobject_put(&intervals->kobj);
1325 	attrs->intervals = NULL;
1326 	return err;
1327 }
1328 
1329 static void damon_sysfs_attrs_rm_dirs(struct damon_sysfs_attrs *attrs)
1330 {
1331 	kobject_put(&attrs->nr_regions_range->kobj);
1332 	damon_sysfs_intervals_rm_dirs(attrs->intervals);
1333 	kobject_put(&attrs->intervals->kobj);
1334 	damon_sysfs_probes_rm_dirs(attrs->probes);
1335 	kobject_put(&attrs->probes->kobj);
1336 }
1337 
1338 static void damon_sysfs_attrs_release(struct kobject *kobj)
1339 {
1340 	kfree(container_of(kobj, struct damon_sysfs_attrs, kobj));
1341 }
1342 
1343 static struct attribute *damon_sysfs_attrs_attrs[] = {
1344 	NULL,
1345 };
1346 ATTRIBUTE_GROUPS(damon_sysfs_attrs);
1347 
1348 static const struct kobj_type damon_sysfs_attrs_ktype = {
1349 	.release = damon_sysfs_attrs_release,
1350 	.sysfs_ops = &kobj_sysfs_ops,
1351 	.default_groups = damon_sysfs_attrs_groups,
1352 };
1353 
1354 /*
1355  * context directory
1356  */
1357 
1358 struct damon_sysfs_ops_name {
1359 	enum damon_ops_id ops_id;
1360 	char *name;
1361 };
1362 
1363 static const struct damon_sysfs_ops_name damon_sysfs_ops_names[] = {
1364 	{
1365 		.ops_id = DAMON_OPS_VADDR,
1366 		.name = "vaddr",
1367 	},
1368 	{
1369 		.ops_id = DAMON_OPS_FVADDR,
1370 		.name = "fvaddr",
1371 	},
1372 	{
1373 		.ops_id = DAMON_OPS_PADDR,
1374 		.name = "paddr",
1375 	},
1376 };
1377 
1378 struct damon_sysfs_context {
1379 	struct kobject kobj;
1380 	enum damon_ops_id ops_id;
1381 	unsigned long addr_unit;
1382 	struct damon_sysfs_attrs *attrs;
1383 	struct damon_sysfs_targets *targets;
1384 	struct damon_sysfs_schemes *schemes;
1385 	bool pause;
1386 };
1387 
1388 static struct damon_sysfs_context *damon_sysfs_context_alloc(
1389 		enum damon_ops_id ops_id)
1390 {
1391 	struct damon_sysfs_context *context = kmalloc_obj(*context);
1392 
1393 	if (!context)
1394 		return NULL;
1395 	context->kobj = (struct kobject){};
1396 	context->ops_id = ops_id;
1397 	context->addr_unit = 1;
1398 	context->pause = false;
1399 	return context;
1400 }
1401 
1402 static int damon_sysfs_context_set_attrs(struct damon_sysfs_context *context)
1403 {
1404 	struct damon_sysfs_attrs *attrs = damon_sysfs_attrs_alloc();
1405 	int err;
1406 
1407 	if (!attrs)
1408 		return -ENOMEM;
1409 	err = kobject_init_and_add(&attrs->kobj, &damon_sysfs_attrs_ktype,
1410 			&context->kobj, "monitoring_attrs");
1411 	if (err)
1412 		goto out;
1413 	err = damon_sysfs_attrs_add_dirs(attrs);
1414 	if (err)
1415 		goto out;
1416 	context->attrs = attrs;
1417 	return 0;
1418 
1419 out:
1420 	kobject_put(&attrs->kobj);
1421 	return err;
1422 }
1423 
1424 static int damon_sysfs_context_set_targets(struct damon_sysfs_context *context)
1425 {
1426 	struct damon_sysfs_targets *targets = damon_sysfs_targets_alloc();
1427 	int err;
1428 
1429 	if (!targets)
1430 		return -ENOMEM;
1431 	err = kobject_init_and_add(&targets->kobj, &damon_sysfs_targets_ktype,
1432 			&context->kobj, "targets");
1433 	if (err) {
1434 		kobject_put(&targets->kobj);
1435 		return err;
1436 	}
1437 	context->targets = targets;
1438 	return 0;
1439 }
1440 
1441 static int damon_sysfs_context_set_schemes(struct damon_sysfs_context *context)
1442 {
1443 	struct damon_sysfs_schemes *schemes = damon_sysfs_schemes_alloc();
1444 	int err;
1445 
1446 	if (!schemes)
1447 		return -ENOMEM;
1448 	err = kobject_init_and_add(&schemes->kobj, &damon_sysfs_schemes_ktype,
1449 			&context->kobj, "schemes");
1450 	if (err) {
1451 		kobject_put(&schemes->kobj);
1452 		return err;
1453 	}
1454 	context->schemes = schemes;
1455 	return 0;
1456 }
1457 
1458 static int damon_sysfs_context_add_dirs(struct damon_sysfs_context *context)
1459 {
1460 	int err;
1461 
1462 	err = damon_sysfs_context_set_attrs(context);
1463 	if (err)
1464 		return err;
1465 
1466 	err = damon_sysfs_context_set_targets(context);
1467 	if (err)
1468 		goto rmdir_put_attrs_out;
1469 
1470 	err = damon_sysfs_context_set_schemes(context);
1471 	if (err)
1472 		goto put_targets_attrs_out;
1473 	return 0;
1474 
1475 put_targets_attrs_out:
1476 	kobject_put(&context->targets->kobj);
1477 	context->targets = NULL;
1478 rmdir_put_attrs_out:
1479 	damon_sysfs_attrs_rm_dirs(context->attrs);
1480 	kobject_put(&context->attrs->kobj);
1481 	context->attrs = NULL;
1482 	return err;
1483 }
1484 
1485 static void damon_sysfs_context_rm_dirs(struct damon_sysfs_context *context)
1486 {
1487 	damon_sysfs_attrs_rm_dirs(context->attrs);
1488 	kobject_put(&context->attrs->kobj);
1489 	damon_sysfs_targets_rm_dirs(context->targets);
1490 	kobject_put(&context->targets->kobj);
1491 	damon_sysfs_schemes_rm_dirs(context->schemes);
1492 	kobject_put(&context->schemes->kobj);
1493 }
1494 
1495 static ssize_t avail_operations_show(struct kobject *kobj,
1496 		struct kobj_attribute *attr, char *buf)
1497 {
1498 	int len = 0;
1499 	int i;
1500 
1501 	for (i = 0; i < ARRAY_SIZE(damon_sysfs_ops_names); i++) {
1502 		const struct damon_sysfs_ops_name *ops_name;
1503 
1504 		ops_name = &damon_sysfs_ops_names[i];
1505 		if (!damon_is_registered_ops(ops_name->ops_id))
1506 			continue;
1507 		len += sysfs_emit_at(buf, len, "%s\n", ops_name->name);
1508 	}
1509 	return len;
1510 }
1511 
1512 static ssize_t operations_show(struct kobject *kobj,
1513 		struct kobj_attribute *attr, char *buf)
1514 {
1515 	struct damon_sysfs_context *context = container_of(kobj,
1516 			struct damon_sysfs_context, kobj);
1517 	int i;
1518 
1519 	for (i = 0; i < ARRAY_SIZE(damon_sysfs_ops_names); i++) {
1520 		const struct damon_sysfs_ops_name *ops_name;
1521 
1522 		ops_name = &damon_sysfs_ops_names[i];
1523 		if (ops_name->ops_id == context->ops_id)
1524 			return sysfs_emit(buf, "%s\n", ops_name->name);
1525 	}
1526 	return -EINVAL;
1527 }
1528 
1529 static ssize_t operations_store(struct kobject *kobj,
1530 		struct kobj_attribute *attr, const char *buf, size_t count)
1531 {
1532 	struct damon_sysfs_context *context = container_of(kobj,
1533 			struct damon_sysfs_context, kobj);
1534 	int i;
1535 
1536 	for (i = 0; i < ARRAY_SIZE(damon_sysfs_ops_names); i++) {
1537 		const struct damon_sysfs_ops_name *ops_name;
1538 
1539 		ops_name = &damon_sysfs_ops_names[i];
1540 		if (sysfs_streq(buf, ops_name->name)) {
1541 			context->ops_id = ops_name->ops_id;
1542 			return count;
1543 		}
1544 	}
1545 	return -EINVAL;
1546 }
1547 
1548 static ssize_t addr_unit_show(struct kobject *kobj,
1549 		struct kobj_attribute *attr, char *buf)
1550 {
1551 	struct damon_sysfs_context *context = container_of(kobj,
1552 			struct damon_sysfs_context, kobj);
1553 
1554 	return sysfs_emit(buf, "%lu\n", context->addr_unit);
1555 }
1556 
1557 static ssize_t addr_unit_store(struct kobject *kobj,
1558 		struct kobj_attribute *attr, const char *buf, size_t count)
1559 {
1560 	struct damon_sysfs_context *context = container_of(kobj,
1561 			struct damon_sysfs_context, kobj);
1562 	unsigned long input_addr_unit;
1563 	int err = kstrtoul(buf, 0, &input_addr_unit);
1564 
1565 	if (err)
1566 		return err;
1567 	if (!input_addr_unit)
1568 		return -EINVAL;
1569 
1570 	context->addr_unit = input_addr_unit;
1571 	return count;
1572 }
1573 
1574 static ssize_t pause_show(struct kobject *kobj, struct kobj_attribute *attr,
1575 		char *buf)
1576 {
1577 	struct damon_sysfs_context *context = container_of(kobj,
1578 			struct damon_sysfs_context, kobj);
1579 
1580 	return sysfs_emit(buf, "%c\n", context->pause ? 'Y' : 'N');
1581 }
1582 
1583 static ssize_t pause_store(struct kobject *kobj, struct kobj_attribute *attr,
1584 		const char *buf, size_t count)
1585 {
1586 	struct damon_sysfs_context *context = container_of(kobj,
1587 			struct damon_sysfs_context, kobj);
1588 	bool pause;
1589 	int err = kstrtobool(buf, &pause);
1590 
1591 	if (err)
1592 		return err;
1593 	context->pause = pause;
1594 	return count;
1595 }
1596 
1597 
1598 static void damon_sysfs_context_release(struct kobject *kobj)
1599 {
1600 	kfree(container_of(kobj, struct damon_sysfs_context, kobj));
1601 }
1602 
1603 static struct kobj_attribute damon_sysfs_context_avail_operations_attr =
1604 		__ATTR_RO_MODE(avail_operations, 0400);
1605 
1606 static struct kobj_attribute damon_sysfs_context_operations_attr =
1607 		__ATTR_RW_MODE(operations, 0600);
1608 
1609 static struct kobj_attribute damon_sysfs_context_addr_unit_attr =
1610 		__ATTR_RW_MODE(addr_unit, 0600);
1611 
1612 static struct kobj_attribute damon_sysfs_context_pause_attr =
1613 		__ATTR_RW_MODE(pause, 0600);
1614 
1615 static struct attribute *damon_sysfs_context_attrs[] = {
1616 	&damon_sysfs_context_avail_operations_attr.attr,
1617 	&damon_sysfs_context_operations_attr.attr,
1618 	&damon_sysfs_context_addr_unit_attr.attr,
1619 	&damon_sysfs_context_pause_attr.attr,
1620 	NULL,
1621 };
1622 ATTRIBUTE_GROUPS(damon_sysfs_context);
1623 
1624 static const struct kobj_type damon_sysfs_context_ktype = {
1625 	.release = damon_sysfs_context_release,
1626 	.sysfs_ops = &kobj_sysfs_ops,
1627 	.default_groups = damon_sysfs_context_groups,
1628 };
1629 
1630 /*
1631  * contexts directory
1632  */
1633 
1634 struct damon_sysfs_contexts {
1635 	struct kobject kobj;
1636 	struct damon_sysfs_context **contexts_arr;
1637 	int nr;
1638 };
1639 
1640 static struct damon_sysfs_contexts *damon_sysfs_contexts_alloc(void)
1641 {
1642 	return kzalloc_obj(struct damon_sysfs_contexts);
1643 }
1644 
1645 static void damon_sysfs_contexts_rm_dirs(struct damon_sysfs_contexts *contexts)
1646 {
1647 	struct damon_sysfs_context **contexts_arr = contexts->contexts_arr;
1648 	int i;
1649 
1650 	for (i = 0; i < contexts->nr; i++) {
1651 		damon_sysfs_context_rm_dirs(contexts_arr[i]);
1652 		kobject_del(&contexts_arr[i]->kobj);
1653 		kobject_put(&contexts_arr[i]->kobj);
1654 	}
1655 	contexts->nr = 0;
1656 	kfree(contexts_arr);
1657 	contexts->contexts_arr = NULL;
1658 }
1659 
1660 static int damon_sysfs_contexts_add_dirs(struct damon_sysfs_contexts *contexts,
1661 		int nr_contexts)
1662 {
1663 	struct damon_sysfs_context **contexts_arr, *context;
1664 	int err, i;
1665 
1666 	damon_sysfs_contexts_rm_dirs(contexts);
1667 	if (!nr_contexts)
1668 		return 0;
1669 
1670 	contexts_arr = kmalloc_objs(*contexts_arr, nr_contexts,
1671 				    GFP_KERNEL | __GFP_NOWARN);
1672 	if (!contexts_arr)
1673 		return -ENOMEM;
1674 	contexts->contexts_arr = contexts_arr;
1675 
1676 	for (i = 0; i < nr_contexts; i++) {
1677 		context = damon_sysfs_context_alloc(DAMON_OPS_VADDR);
1678 		if (!context) {
1679 			damon_sysfs_contexts_rm_dirs(contexts);
1680 			return -ENOMEM;
1681 		}
1682 
1683 		err = kobject_init_and_add(&context->kobj,
1684 				&damon_sysfs_context_ktype, &contexts->kobj,
1685 				"%d", i);
1686 		if (err)
1687 			goto out;
1688 
1689 		err = damon_sysfs_context_add_dirs(context);
1690 		if (err)
1691 			goto del_out;
1692 
1693 		contexts_arr[i] = context;
1694 		contexts->nr++;
1695 	}
1696 	return 0;
1697 
1698 del_out:
1699 	kobject_del(&context->kobj);
1700 out:
1701 	damon_sysfs_contexts_rm_dirs(contexts);
1702 	kobject_put(&context->kobj);
1703 	return err;
1704 }
1705 
1706 static ssize_t nr_contexts_show(struct kobject *kobj,
1707 		struct kobj_attribute *attr, char *buf)
1708 {
1709 	struct damon_sysfs_contexts *contexts = container_of(kobj,
1710 			struct damon_sysfs_contexts, kobj);
1711 
1712 	return sysfs_emit(buf, "%d\n", contexts->nr);
1713 }
1714 
1715 static ssize_t nr_contexts_store(struct kobject *kobj,
1716 		struct kobj_attribute *attr, const char *buf, size_t count)
1717 {
1718 	struct damon_sysfs_contexts *contexts;
1719 	int nr, err;
1720 
1721 	err = kstrtoint(buf, 0, &nr);
1722 	if (err)
1723 		return err;
1724 	/* TODO: support multiple contexts per kdamond */
1725 	if (nr < 0 || 1 < nr)
1726 		return -EINVAL;
1727 
1728 	contexts = container_of(kobj, struct damon_sysfs_contexts, kobj);
1729 	if (!mutex_trylock(&damon_sysfs_lock))
1730 		return -EBUSY;
1731 	err = damon_sysfs_contexts_add_dirs(contexts, nr);
1732 	mutex_unlock(&damon_sysfs_lock);
1733 	if (err)
1734 		return err;
1735 
1736 	return count;
1737 }
1738 
1739 static void damon_sysfs_contexts_release(struct kobject *kobj)
1740 {
1741 	kfree(container_of(kobj, struct damon_sysfs_contexts, kobj));
1742 }
1743 
1744 static struct kobj_attribute damon_sysfs_contexts_nr_attr
1745 		= __ATTR_RW_MODE(nr_contexts, 0600);
1746 
1747 static struct attribute *damon_sysfs_contexts_attrs[] = {
1748 	&damon_sysfs_contexts_nr_attr.attr,
1749 	NULL,
1750 };
1751 ATTRIBUTE_GROUPS(damon_sysfs_contexts);
1752 
1753 static const struct kobj_type damon_sysfs_contexts_ktype = {
1754 	.release = damon_sysfs_contexts_release,
1755 	.sysfs_ops = &kobj_sysfs_ops,
1756 	.default_groups = damon_sysfs_contexts_groups,
1757 };
1758 
1759 /*
1760  * kdamond directory
1761  */
1762 
1763 struct damon_sysfs_kdamond {
1764 	struct kobject kobj;
1765 	struct damon_sysfs_contexts *contexts;
1766 	struct damon_ctx *damon_ctx;
1767 	unsigned int refresh_ms;
1768 };
1769 
1770 static struct damon_sysfs_kdamond *damon_sysfs_kdamond_alloc(void)
1771 {
1772 	return kzalloc_obj(struct damon_sysfs_kdamond);
1773 }
1774 
1775 static int damon_sysfs_kdamond_add_dirs(struct damon_sysfs_kdamond *kdamond)
1776 {
1777 	struct damon_sysfs_contexts *contexts;
1778 	int err;
1779 
1780 	contexts = damon_sysfs_contexts_alloc();
1781 	if (!contexts)
1782 		return -ENOMEM;
1783 
1784 	err = kobject_init_and_add(&contexts->kobj,
1785 			&damon_sysfs_contexts_ktype, &kdamond->kobj,
1786 			"contexts");
1787 	if (err) {
1788 		kobject_put(&contexts->kobj);
1789 		return err;
1790 	}
1791 	kdamond->contexts = contexts;
1792 
1793 	return err;
1794 }
1795 
1796 static void damon_sysfs_kdamond_rm_dirs(struct damon_sysfs_kdamond *kdamond)
1797 {
1798 	damon_sysfs_contexts_rm_dirs(kdamond->contexts);
1799 	kobject_put(&kdamond->contexts->kobj);
1800 }
1801 
1802 /*
1803  * enum damon_sysfs_cmd - Commands for a specific kdamond.
1804  */
1805 enum damon_sysfs_cmd {
1806 	/* @DAMON_SYSFS_CMD_ON: Turn the kdamond on. */
1807 	DAMON_SYSFS_CMD_ON,
1808 	/* @DAMON_SYSFS_CMD_OFF: Turn the kdamond off. */
1809 	DAMON_SYSFS_CMD_OFF,
1810 	/* @DAMON_SYSFS_CMD_COMMIT: Update kdamond inputs. */
1811 	DAMON_SYSFS_CMD_COMMIT,
1812 	/*
1813 	 * @DAMON_SYSFS_CMD_COMMIT_SCHEMES_QUOTA_GOALS: Commit the quota goals
1814 	 * to DAMON.
1815 	 */
1816 	DAMON_SYSFS_CMD_COMMIT_SCHEMES_QUOTA_GOALS,
1817 	/*
1818 	 * @DAMON_SYSFS_CMD_UPDATE_SCHEMES_STATS: Update scheme stats sysfs
1819 	 * files.
1820 	 */
1821 	DAMON_SYSFS_CMD_UPDATE_SCHEMES_STATS,
1822 	/*
1823 	 * @DAMON_SYSFS_CMD_UPDATE_SCHEMES_TRIED_BYTES: Update
1824 	 * tried_regions/total_bytes sysfs files for each scheme.
1825 	 */
1826 	DAMON_SYSFS_CMD_UPDATE_SCHEMES_TRIED_BYTES,
1827 	/*
1828 	 * @DAMON_SYSFS_CMD_UPDATE_SCHEMES_TRIED_REGIONS: Update schemes tried
1829 	 * regions
1830 	 */
1831 	DAMON_SYSFS_CMD_UPDATE_SCHEMES_TRIED_REGIONS,
1832 	/*
1833 	 * @DAMON_SYSFS_CMD_CLEAR_SCHEMES_TRIED_REGIONS: Clear schemes tried
1834 	 * regions
1835 	 */
1836 	DAMON_SYSFS_CMD_CLEAR_SCHEMES_TRIED_REGIONS,
1837 	/*
1838 	 * @DAMON_SYSFS_CMD_UPDATE_SCHEMES_EFFECTIVE_QUOTAS: Update the
1839 	 * effective size quota of the scheme in bytes.
1840 	 */
1841 	DAMON_SYSFS_CMD_UPDATE_SCHEMES_EFFECTIVE_QUOTAS,
1842 	/*
1843 	 * @DAMON_SYSFS_CMD_UPDATE_TUNED_INTERVALS: Update the tuned monitoring
1844 	 * intervals.
1845 	 */
1846 	DAMON_SYSFS_CMD_UPDATE_TUNED_INTERVALS,
1847 	/*
1848 	 * @NR_DAMON_SYSFS_CMDS: Total number of DAMON sysfs commands.
1849 	 */
1850 	NR_DAMON_SYSFS_CMDS,
1851 };
1852 
1853 /* Should match with enum damon_sysfs_cmd */
1854 static const char * const damon_sysfs_cmd_strs[] = {
1855 	"on",
1856 	"off",
1857 	"commit",
1858 	"commit_schemes_quota_goals",
1859 	"update_schemes_stats",
1860 	"update_schemes_tried_bytes",
1861 	"update_schemes_tried_regions",
1862 	"clear_schemes_tried_regions",
1863 	"update_schemes_effective_quotas",
1864 	"update_tuned_intervals",
1865 };
1866 
1867 static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
1868 		char *buf)
1869 {
1870 	struct damon_sysfs_kdamond *kdamond = container_of(kobj,
1871 			struct damon_sysfs_kdamond, kobj);
1872 	struct damon_ctx *ctx;
1873 	bool running = false;
1874 
1875 	if (!mutex_trylock(&damon_sysfs_lock))
1876 		return -EBUSY;
1877 
1878 	ctx = kdamond->damon_ctx;
1879 	if (ctx)
1880 		running = damon_is_running(ctx);
1881 
1882 	mutex_unlock(&damon_sysfs_lock);
1883 
1884 	return sysfs_emit(buf, "%s\n", running ?
1885 			damon_sysfs_cmd_strs[DAMON_SYSFS_CMD_ON] :
1886 			damon_sysfs_cmd_strs[DAMON_SYSFS_CMD_OFF]);
1887 }
1888 
1889 static int damon_sysfs_set_attrs(struct damon_ctx *ctx,
1890 		struct damon_sysfs_attrs *sys_attrs)
1891 {
1892 	struct damon_sysfs_intervals *sys_intervals = sys_attrs->intervals;
1893 	struct damon_sysfs_intervals_goal *sys_goal =
1894 		sys_intervals->intervals_goal;
1895 	struct damon_sysfs_ul_range *sys_nr_regions =
1896 		sys_attrs->nr_regions_range;
1897 	struct damon_attrs attrs = {
1898 		.sample_interval = sys_intervals->sample_us,
1899 		.aggr_interval = sys_intervals->aggr_us,
1900 		.intervals_goal = {
1901 			.access_bp = sys_goal->access_bp,
1902 			.aggrs = sys_goal->aggrs,
1903 			.min_sample_us = sys_goal->min_sample_us,
1904 			.max_sample_us = sys_goal->max_sample_us},
1905 		.ops_update_interval = sys_intervals->update_us,
1906 		.min_nr_regions = sys_nr_regions->min,
1907 		.max_nr_regions = sys_nr_regions->max,
1908 	};
1909 	return damon_set_attrs(ctx, &attrs);
1910 }
1911 
1912 static int damon_sysfs_set_filters(struct damon_probe *probe,
1913 		struct damon_sysfs_filters *sys_filters)
1914 {
1915 	int i;
1916 
1917 	for (i = 0; i < sys_filters->nr; i++) {
1918 		struct damon_sysfs_filter *sys_filter =
1919 			sys_filters->filters_arr[i];
1920 		struct damon_filter *filter;
1921 
1922 		filter = damon_new_filter(sys_filter->type,
1923 				sys_filter->matching,
1924 				sys_filter->allow);
1925 		if (!filter)
1926 			return -ENOMEM;
1927 		if (filter->type == DAMON_FILTER_TYPE_MEMCG) {
1928 			int err;
1929 
1930 			err = damon_sysfs_memcg_path_to_id(
1931 					sys_filter->path,
1932 					&filter->memcg_id);
1933 			if (err) {
1934 				damon_destroy_filter(filter);
1935 				return err;
1936 			}
1937 		}
1938 		damon_add_filter(probe, filter);
1939 	}
1940 	return 0;
1941 }
1942 
1943 static int damon_sysfs_set_probe(struct damon_probe *probe,
1944 		struct damon_sysfs_probe *sys_probe)
1945 {
1946 	struct damon_sysfs_filters *sys_filters;
1947 
1948 	sys_filters = sys_probe->filters;
1949 	if (!sys_filters)
1950 		return 0;
1951 	return damon_sysfs_set_filters(probe, sys_filters);
1952 }
1953 
1954 static int damon_sysfs_set_probes(struct damon_ctx *ctx,
1955 		struct damon_sysfs_probes *sys_probes)
1956 {
1957 	int i, err;
1958 
1959 	for (i = 0; i < sys_probes->nr; i++) {
1960 		struct damon_sysfs_probe *sys_probe;
1961 		struct damon_probe *p;
1962 
1963 		p = damon_new_probe();
1964 		if (!p)
1965 			return -ENOMEM;
1966 		damon_add_probe(ctx, p);
1967 		sys_probe = sys_probes->probes_arr[i];
1968 		err = damon_sysfs_set_probe(p, sys_probe);
1969 		if (err)
1970 			return err;
1971 	}
1972 	return 0;
1973 }
1974 
1975 static int damon_sysfs_set_regions(struct damon_target *t,
1976 		struct damon_sysfs_regions *sysfs_regions,
1977 		unsigned long min_region_sz)
1978 {
1979 	struct damon_addr_range *ranges = kmalloc_objs(*ranges,
1980 						       sysfs_regions->nr,
1981 						       GFP_KERNEL | __GFP_NOWARN);
1982 	int i, err = -EINVAL;
1983 
1984 	if (!ranges)
1985 		return -ENOMEM;
1986 	for (i = 0; i < sysfs_regions->nr; i++) {
1987 		struct damon_sysfs_region *sys_region =
1988 			sysfs_regions->regions_arr[i];
1989 
1990 		if (sys_region->ar.start > sys_region->ar.end)
1991 			goto out;
1992 
1993 		ranges[i].start = sys_region->ar.start;
1994 		ranges[i].end = sys_region->ar.end;
1995 		if (i == 0)
1996 			continue;
1997 		if (ranges[i - 1].end > ranges[i].start)
1998 			goto out;
1999 	}
2000 	err = damon_set_regions(t, ranges, sysfs_regions->nr, min_region_sz);
2001 out:
2002 	kfree(ranges);
2003 	return err;
2004 
2005 }
2006 
2007 static int damon_sysfs_add_target(struct damon_sysfs_target *sys_target,
2008 		struct damon_ctx *ctx)
2009 {
2010 	struct damon_target *t = damon_new_target();
2011 
2012 	if (!t)
2013 		return -ENOMEM;
2014 	damon_add_target(ctx, t);
2015 	if (damon_target_has_pid(ctx)) {
2016 		t->pid = find_get_pid(sys_target->pid);
2017 		if (!t->pid)
2018 			/* caller will destroy targets */
2019 			return -EINVAL;
2020 	}
2021 	t->obsolete = sys_target->obsolete;
2022 	return damon_sysfs_set_regions(t, sys_target->regions,
2023 			ctx->min_region_sz);
2024 }
2025 
2026 static int damon_sysfs_add_targets(struct damon_ctx *ctx,
2027 		struct damon_sysfs_targets *sysfs_targets)
2028 {
2029 	int i, err;
2030 
2031 	/* Multiple physical address space monitoring targets makes no sense */
2032 	if (ctx->ops.id == DAMON_OPS_PADDR && sysfs_targets->nr > 1)
2033 		return -EINVAL;
2034 
2035 	for (i = 0; i < sysfs_targets->nr; i++) {
2036 		struct damon_sysfs_target *st = sysfs_targets->targets_arr[i];
2037 
2038 		err = damon_sysfs_add_target(st, ctx);
2039 		if (err)
2040 			return err;
2041 	}
2042 	return 0;
2043 }
2044 
2045 /*
2046  * damon_sysfs_upd_schemes_stats() - Update schemes stats sysfs files.
2047  * @data:	The kobject wrapper that associated to the kdamond thread.
2048  *
2049  * This function reads the schemes stats of specific kdamond and update the
2050  * related values for sysfs files.  This function should be called from DAMON
2051  * worker thread,to safely access the DAMON contexts-internal data.  Caller
2052  * should also ensure holding ``damon_syfs_lock``, and ->damon_ctx of @data is
2053  * not NULL but a valid pointer, to safely access DAMON sysfs variables.
2054  */
2055 static int damon_sysfs_upd_schemes_stats(void *data)
2056 {
2057 	struct damon_sysfs_kdamond *kdamond = data;
2058 	struct damon_ctx *ctx = kdamond->damon_ctx;
2059 
2060 	damon_sysfs_schemes_update_stats(
2061 			kdamond->contexts->contexts_arr[0]->schemes, ctx);
2062 	return 0;
2063 }
2064 
2065 static inline bool damon_sysfs_kdamond_running(
2066 		struct damon_sysfs_kdamond *kdamond)
2067 {
2068 	return kdamond->damon_ctx &&
2069 		damon_is_running(kdamond->damon_ctx);
2070 }
2071 
2072 static int damon_sysfs_apply_inputs(struct damon_ctx *ctx,
2073 		struct damon_sysfs_context *sys_ctx)
2074 {
2075 	int err;
2076 
2077 	err = damon_select_ops(ctx, sys_ctx->ops_id);
2078 	if (err)
2079 		return err;
2080 	ctx->addr_unit = sys_ctx->addr_unit;
2081 	/* addr_unit is respected by only DAMON_OPS_PADDR */
2082 	if (sys_ctx->ops_id == DAMON_OPS_PADDR)
2083 		ctx->min_region_sz = max(
2084 				DAMON_MIN_REGION_SZ / sys_ctx->addr_unit, 1);
2085 	ctx->pause = sys_ctx->pause;
2086 	err = damon_sysfs_set_attrs(ctx, sys_ctx->attrs);
2087 	if (err)
2088 		return err;
2089 	err = damon_sysfs_set_probes(ctx, sys_ctx->attrs->probes);
2090 	if (err)
2091 		return err;
2092 	err = damon_sysfs_add_targets(ctx, sys_ctx->targets);
2093 	if (err)
2094 		return err;
2095 	return damon_sysfs_add_schemes(ctx, sys_ctx->schemes);
2096 }
2097 
2098 static struct damon_ctx *damon_sysfs_build_ctx(
2099 		struct damon_sysfs_context *sys_ctx);
2100 
2101 /*
2102  * Return a new damon_ctx for testing new parameters to commit.
2103  */
2104 static struct damon_ctx *damon_sysfs_new_test_ctx(
2105 		struct damon_ctx *running_ctx)
2106 {
2107 	struct damon_ctx *test_ctx;
2108 	int err;
2109 
2110 	test_ctx = damon_new_ctx();
2111 	if (!test_ctx)
2112 		return NULL;
2113 	err = damon_commit_ctx(test_ctx, running_ctx);
2114 	if (err) {
2115 		damon_destroy_ctx(test_ctx);
2116 		return NULL;
2117 	}
2118 	return test_ctx;
2119 }
2120 
2121 /*
2122  * damon_sysfs_commit_input() - Commit user inputs to a running kdamond.
2123  * @kdamond:	The kobject wrapper for the associated kdamond.
2124  *
2125  * Returns error if the sysfs input is wrong.
2126  */
2127 static int damon_sysfs_commit_input(void *data)
2128 {
2129 	struct damon_sysfs_kdamond *kdamond = data;
2130 	struct damon_ctx *param_ctx, *test_ctx;
2131 	int err;
2132 
2133 	if (!damon_sysfs_kdamond_running(kdamond))
2134 		return -EINVAL;
2135 	/* TODO: Support multiple contexts per kdamond */
2136 	if (kdamond->contexts->nr != 1)
2137 		return -EINVAL;
2138 
2139 	param_ctx = damon_sysfs_build_ctx(kdamond->contexts->contexts_arr[0]);
2140 	if (IS_ERR(param_ctx))
2141 		return PTR_ERR(param_ctx);
2142 	test_ctx = damon_sysfs_new_test_ctx(kdamond->damon_ctx);
2143 	if (!test_ctx) {
2144 		damon_destroy_ctx(param_ctx);
2145 		return -ENOMEM;
2146 	}
2147 	err = damon_commit_ctx(test_ctx, param_ctx);
2148 	if (err)
2149 		goto out;
2150 	err = damon_commit_ctx(kdamond->damon_ctx, param_ctx);
2151 out:
2152 	damon_destroy_ctx(test_ctx);
2153 	damon_destroy_ctx(param_ctx);
2154 	return err;
2155 }
2156 
2157 static int damon_sysfs_commit_schemes_quota_goals(void *data)
2158 {
2159 	struct damon_sysfs_kdamond *sysfs_kdamond = data;
2160 	struct damon_ctx *ctx;
2161 	struct damon_sysfs_context *sysfs_ctx;
2162 
2163 	if (!damon_sysfs_kdamond_running(sysfs_kdamond))
2164 		return -EINVAL;
2165 	/* TODO: Support multiple contexts per kdamond */
2166 	if (sysfs_kdamond->contexts->nr != 1)
2167 		return -EINVAL;
2168 
2169 	ctx = sysfs_kdamond->damon_ctx;
2170 	sysfs_ctx = sysfs_kdamond->contexts->contexts_arr[0];
2171 	return damos_sysfs_set_quota_scores(sysfs_ctx->schemes, ctx);
2172 }
2173 
2174 /*
2175  * damon_sysfs_upd_schemes_effective_quotas() - Update schemes effective quotas
2176  * sysfs files.
2177  * @data:	The kobject wrapper that associated to the kdamond thread.
2178  *
2179  * This function reads the schemes' effective quotas of specific kdamond and
2180  * update the related values for sysfs files.  This function should be called
2181  * from DAMON callbacks while holding ``damon_syfs_lock``, to safely access the
2182  * DAMON contexts-internal data and DAMON sysfs variables.
2183  */
2184 static int damon_sysfs_upd_schemes_effective_quotas(void *data)
2185 {
2186 	struct damon_sysfs_kdamond *kdamond = data;
2187 	struct damon_ctx *ctx = kdamond->damon_ctx;
2188 
2189 	damos_sysfs_update_effective_quotas(
2190 			kdamond->contexts->contexts_arr[0]->schemes, ctx);
2191 	return 0;
2192 }
2193 
2194 static int damon_sysfs_upd_tuned_intervals(void *data)
2195 {
2196 	struct damon_sysfs_kdamond *kdamond = data;
2197 	struct damon_ctx *ctx = kdamond->damon_ctx;
2198 
2199 	kdamond->contexts->contexts_arr[0]->attrs->intervals->sample_us =
2200 		ctx->attrs.sample_interval;
2201 	kdamond->contexts->contexts_arr[0]->attrs->intervals->aggr_us =
2202 		ctx->attrs.aggr_interval;
2203 	return 0;
2204 }
2205 
2206 static struct damon_ctx *damon_sysfs_build_ctx(
2207 		struct damon_sysfs_context *sys_ctx)
2208 {
2209 	struct damon_ctx *ctx = damon_new_ctx();
2210 	int err;
2211 
2212 	if (!ctx)
2213 		return ERR_PTR(-ENOMEM);
2214 
2215 	err = damon_sysfs_apply_inputs(ctx, sys_ctx);
2216 	if (err) {
2217 		damon_destroy_ctx(ctx);
2218 		return ERR_PTR(err);
2219 	}
2220 
2221 	return ctx;
2222 }
2223 
2224 static unsigned long damon_sysfs_next_update_jiffies;
2225 
2226 static int damon_sysfs_repeat_call_fn(void *data)
2227 {
2228 	struct damon_sysfs_kdamond *sysfs_kdamond = data;
2229 
2230 	if (!sysfs_kdamond->refresh_ms)
2231 		return 0;
2232 	if (time_before(jiffies, damon_sysfs_next_update_jiffies))
2233 		return 0;
2234 	damon_sysfs_next_update_jiffies = jiffies +
2235 		msecs_to_jiffies(sysfs_kdamond->refresh_ms);
2236 
2237 	if (!mutex_trylock(&damon_sysfs_lock))
2238 		return 0;
2239 	if (sysfs_kdamond->contexts->nr != 1)
2240 		goto out;
2241 	damon_sysfs_upd_tuned_intervals(sysfs_kdamond);
2242 	damon_sysfs_upd_schemes_stats(sysfs_kdamond);
2243 	damon_sysfs_upd_schemes_effective_quotas(sysfs_kdamond);
2244 out:
2245 	mutex_unlock(&damon_sysfs_lock);
2246 	return 0;
2247 }
2248 
2249 static int damon_sysfs_turn_damon_on(struct damon_sysfs_kdamond *kdamond)
2250 {
2251 	struct damon_ctx *ctx;
2252 	struct damon_call_control *repeat_call_control;
2253 	int err;
2254 
2255 	if (damon_sysfs_kdamond_running(kdamond))
2256 		return -EBUSY;
2257 	/* TODO: support multiple contexts per kdamond */
2258 	if (kdamond->contexts->nr != 1)
2259 		return -EINVAL;
2260 
2261 	if (kdamond->damon_ctx)
2262 		damon_destroy_ctx(kdamond->damon_ctx);
2263 	kdamond->damon_ctx = NULL;
2264 
2265 	repeat_call_control = kmalloc_obj(*repeat_call_control);
2266 	if (!repeat_call_control)
2267 		return -ENOMEM;
2268 
2269 	ctx = damon_sysfs_build_ctx(kdamond->contexts->contexts_arr[0]);
2270 	if (IS_ERR(ctx)) {
2271 		kfree(repeat_call_control);
2272 		return PTR_ERR(ctx);
2273 	}
2274 	err = damon_start(&ctx, 1, false);
2275 	if (err) {
2276 		kfree(repeat_call_control);
2277 		damon_destroy_ctx(ctx);
2278 		return err;
2279 	}
2280 	kdamond->damon_ctx = ctx;
2281 
2282 	damon_sysfs_next_update_jiffies =
2283 		jiffies + msecs_to_jiffies(kdamond->refresh_ms);
2284 
2285 	repeat_call_control->fn = damon_sysfs_repeat_call_fn;
2286 	repeat_call_control->data = kdamond;
2287 	repeat_call_control->repeat = true;
2288 	repeat_call_control->dealloc_on_cancel = true;
2289 	if (damon_call(ctx, repeat_call_control))
2290 		kfree(repeat_call_control);
2291 	return err;
2292 }
2293 
2294 static int damon_sysfs_turn_damon_off(struct damon_sysfs_kdamond *kdamond)
2295 {
2296 	if (!kdamond->damon_ctx)
2297 		return -EINVAL;
2298 	return damon_stop(&kdamond->damon_ctx, 1);
2299 	/*
2300 	 * To allow users show final monitoring results of already turned-off
2301 	 * DAMON, we free kdamond->damon_ctx in next
2302 	 * damon_sysfs_turn_damon_on(), or kdamonds_nr_store()
2303 	 */
2304 }
2305 
2306 static int damon_sysfs_damon_call(int (*fn)(void *data),
2307 		struct damon_sysfs_kdamond *kdamond)
2308 {
2309 	struct damon_call_control call_control = {};
2310 	int err;
2311 
2312 	if (!kdamond->damon_ctx)
2313 		return -EINVAL;
2314 	call_control.fn = fn;
2315 	call_control.data = kdamond;
2316 	err = damon_call(kdamond->damon_ctx, &call_control);
2317 	return err ? err : call_control.return_code;
2318 }
2319 
2320 struct damon_sysfs_schemes_walk_data {
2321 	struct damon_sysfs_kdamond *sysfs_kdamond;
2322 	bool total_bytes_only;
2323 };
2324 
2325 /* populate the region directory */
2326 static void damon_sysfs_schemes_tried_regions_upd_one(void *data, struct damon_ctx *ctx,
2327 		struct damon_target *t, struct damon_region *r,
2328 		struct damos *s, unsigned long sz_filter_passed)
2329 {
2330 	struct damon_sysfs_schemes_walk_data *walk_data = data;
2331 	struct damon_sysfs_kdamond *sysfs_kdamond = walk_data->sysfs_kdamond;
2332 
2333 	damos_sysfs_populate_region_dir(
2334 			sysfs_kdamond->contexts->contexts_arr[0]->schemes,
2335 			ctx, t, r, s, walk_data->total_bytes_only,
2336 			sz_filter_passed);
2337 }
2338 
2339 static int damon_sysfs_update_schemes_tried_regions(
2340 		struct damon_sysfs_kdamond *sysfs_kdamond, bool total_bytes_only)
2341 {
2342 	struct damon_sysfs_schemes_walk_data walk_data = {
2343 		.sysfs_kdamond = sysfs_kdamond,
2344 		.total_bytes_only = total_bytes_only,
2345 	};
2346 	struct damos_walk_control control = {
2347 		.walk_fn = damon_sysfs_schemes_tried_regions_upd_one,
2348 		.data = &walk_data,
2349 	};
2350 	struct damon_ctx *ctx = sysfs_kdamond->damon_ctx;
2351 
2352 	if (!ctx)
2353 		return -EINVAL;
2354 
2355 	damon_sysfs_schemes_clear_regions(
2356 			sysfs_kdamond->contexts->contexts_arr[0]->schemes);
2357 	return damos_walk(ctx, &control);
2358 }
2359 
2360 /*
2361  * damon_sysfs_handle_cmd() - Handle a command for a specific kdamond.
2362  * @cmd:	The command to handle.
2363  * @kdamond:	The kobject wrapper for the associated kdamond.
2364  *
2365  * This function handles a DAMON sysfs command for a kdamond.
2366  *
2367  * Return: 0 on success, negative error code otherwise.
2368  */
2369 static int damon_sysfs_handle_cmd(enum damon_sysfs_cmd cmd,
2370 		struct damon_sysfs_kdamond *kdamond)
2371 {
2372 	if (cmd != DAMON_SYSFS_CMD_OFF && kdamond->contexts->nr != 1)
2373 		return -EINVAL;
2374 
2375 	switch (cmd) {
2376 	case DAMON_SYSFS_CMD_ON:
2377 		return damon_sysfs_turn_damon_on(kdamond);
2378 	case DAMON_SYSFS_CMD_OFF:
2379 		return damon_sysfs_turn_damon_off(kdamond);
2380 	case DAMON_SYSFS_CMD_COMMIT:
2381 		return damon_sysfs_damon_call(
2382 				damon_sysfs_commit_input, kdamond);
2383 	case DAMON_SYSFS_CMD_COMMIT_SCHEMES_QUOTA_GOALS:
2384 		return damon_sysfs_damon_call(
2385 				damon_sysfs_commit_schemes_quota_goals,
2386 				kdamond);
2387 	case DAMON_SYSFS_CMD_UPDATE_SCHEMES_STATS:
2388 		return damon_sysfs_damon_call(
2389 				damon_sysfs_upd_schemes_stats, kdamond);
2390 	case DAMON_SYSFS_CMD_UPDATE_SCHEMES_TRIED_BYTES:
2391 		return damon_sysfs_update_schemes_tried_regions(kdamond, true);
2392 	case DAMON_SYSFS_CMD_UPDATE_SCHEMES_TRIED_REGIONS:
2393 		return damon_sysfs_update_schemes_tried_regions(kdamond, false);
2394 	case DAMON_SYSFS_CMD_CLEAR_SCHEMES_TRIED_REGIONS:
2395 		return damon_sysfs_schemes_clear_regions(
2396 			kdamond->contexts->contexts_arr[0]->schemes);
2397 	case DAMON_SYSFS_CMD_UPDATE_SCHEMES_EFFECTIVE_QUOTAS:
2398 		return damon_sysfs_damon_call(
2399 				damon_sysfs_upd_schemes_effective_quotas,
2400 				kdamond);
2401 	case DAMON_SYSFS_CMD_UPDATE_TUNED_INTERVALS:
2402 		return damon_sysfs_damon_call(
2403 				damon_sysfs_upd_tuned_intervals, kdamond);
2404 	default:
2405 		return -EINVAL;
2406 	}
2407 }
2408 
2409 static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
2410 		const char *buf, size_t count)
2411 {
2412 	struct damon_sysfs_kdamond *kdamond = container_of(kobj,
2413 			struct damon_sysfs_kdamond, kobj);
2414 	enum damon_sysfs_cmd cmd;
2415 	ssize_t ret = -EINVAL;
2416 
2417 	if (!mutex_trylock(&damon_sysfs_lock))
2418 		return -EBUSY;
2419 	for (cmd = 0; cmd < NR_DAMON_SYSFS_CMDS; cmd++) {
2420 		if (sysfs_streq(buf, damon_sysfs_cmd_strs[cmd])) {
2421 			ret = damon_sysfs_handle_cmd(cmd, kdamond);
2422 			break;
2423 		}
2424 	}
2425 	mutex_unlock(&damon_sysfs_lock);
2426 	if (!ret)
2427 		ret = count;
2428 	return ret;
2429 }
2430 
2431 static ssize_t pid_show(struct kobject *kobj,
2432 		struct kobj_attribute *attr, char *buf)
2433 {
2434 	struct damon_sysfs_kdamond *kdamond = container_of(kobj,
2435 			struct damon_sysfs_kdamond, kobj);
2436 	struct damon_ctx *ctx;
2437 	int pid = -1;
2438 
2439 	if (!mutex_trylock(&damon_sysfs_lock))
2440 		return -EBUSY;
2441 	ctx = kdamond->damon_ctx;
2442 	if (!ctx)
2443 		goto out;
2444 
2445 	pid = damon_kdamond_pid(ctx);
2446 	if (pid < 0)
2447 		pid = -1;
2448 out:
2449 	mutex_unlock(&damon_sysfs_lock);
2450 	return sysfs_emit(buf, "%d\n", pid);
2451 }
2452 
2453 static ssize_t refresh_ms_show(struct kobject *kobj,
2454 		struct kobj_attribute *attr, char *buf)
2455 {
2456 	struct damon_sysfs_kdamond *kdamond = container_of(kobj,
2457 			struct damon_sysfs_kdamond, kobj);
2458 
2459 	return sysfs_emit(buf, "%u\n", kdamond->refresh_ms);
2460 }
2461 
2462 static ssize_t refresh_ms_store(struct kobject *kobj,
2463 		struct kobj_attribute *attr, const char *buf, size_t count)
2464 {
2465 	struct damon_sysfs_kdamond *kdamond = container_of(kobj,
2466 			struct damon_sysfs_kdamond, kobj);
2467 	unsigned int nr;
2468 	int err = kstrtouint(buf, 0, &nr);
2469 
2470 	if (err)
2471 		return err;
2472 
2473 	kdamond->refresh_ms = nr;
2474 	return count;
2475 }
2476 
2477 static void damon_sysfs_kdamond_release(struct kobject *kobj)
2478 {
2479 	struct damon_sysfs_kdamond *kdamond = container_of(kobj,
2480 			struct damon_sysfs_kdamond, kobj);
2481 
2482 	if (kdamond->damon_ctx)
2483 		damon_destroy_ctx(kdamond->damon_ctx);
2484 	kfree(kdamond);
2485 }
2486 
2487 static struct kobj_attribute damon_sysfs_kdamond_state_attr =
2488 		__ATTR_RW_MODE(state, 0600);
2489 
2490 static struct kobj_attribute damon_sysfs_kdamond_pid_attr =
2491 		__ATTR_RO_MODE(pid, 0400);
2492 
2493 static struct kobj_attribute damon_sysfs_kdamond_refresh_ms_attr =
2494 		__ATTR_RW_MODE(refresh_ms, 0600);
2495 
2496 static struct attribute *damon_sysfs_kdamond_attrs[] = {
2497 	&damon_sysfs_kdamond_state_attr.attr,
2498 	&damon_sysfs_kdamond_pid_attr.attr,
2499 	&damon_sysfs_kdamond_refresh_ms_attr.attr,
2500 	NULL,
2501 };
2502 ATTRIBUTE_GROUPS(damon_sysfs_kdamond);
2503 
2504 static const struct kobj_type damon_sysfs_kdamond_ktype = {
2505 	.release = damon_sysfs_kdamond_release,
2506 	.sysfs_ops = &kobj_sysfs_ops,
2507 	.default_groups = damon_sysfs_kdamond_groups,
2508 };
2509 
2510 /*
2511  * kdamonds directory
2512  */
2513 
2514 struct damon_sysfs_kdamonds {
2515 	struct kobject kobj;
2516 	struct damon_sysfs_kdamond **kdamonds_arr;
2517 	int nr;
2518 };
2519 
2520 static struct damon_sysfs_kdamonds *damon_sysfs_kdamonds_alloc(void)
2521 {
2522 	return kzalloc_obj(struct damon_sysfs_kdamonds);
2523 }
2524 
2525 static void damon_sysfs_kdamonds_rm_dirs(struct damon_sysfs_kdamonds *kdamonds)
2526 {
2527 	struct damon_sysfs_kdamond **kdamonds_arr = kdamonds->kdamonds_arr;
2528 	int i;
2529 
2530 	for (i = 0; i < kdamonds->nr; i++) {
2531 		damon_sysfs_kdamond_rm_dirs(kdamonds_arr[i]);
2532 		kobject_del(&kdamonds_arr[i]->kobj);
2533 		kobject_put(&kdamonds_arr[i]->kobj);
2534 	}
2535 	kdamonds->nr = 0;
2536 	kfree(kdamonds_arr);
2537 	kdamonds->kdamonds_arr = NULL;
2538 }
2539 
2540 static bool damon_sysfs_kdamonds_busy(struct damon_sysfs_kdamond **kdamonds,
2541 		int nr_kdamonds)
2542 {
2543 	int i;
2544 
2545 	for (i = 0; i < nr_kdamonds; i++) {
2546 		if (damon_sysfs_kdamond_running(kdamonds[i]))
2547 			return true;
2548 	}
2549 
2550 	return false;
2551 }
2552 
2553 static int damon_sysfs_kdamonds_add_dirs(struct damon_sysfs_kdamonds *kdamonds,
2554 		int nr_kdamonds)
2555 {
2556 	struct damon_sysfs_kdamond **kdamonds_arr, *kdamond;
2557 	int err, i;
2558 
2559 	if (damon_sysfs_kdamonds_busy(kdamonds->kdamonds_arr, kdamonds->nr))
2560 		return -EBUSY;
2561 
2562 	damon_sysfs_kdamonds_rm_dirs(kdamonds);
2563 	if (!nr_kdamonds)
2564 		return 0;
2565 
2566 	kdamonds_arr = kmalloc_objs(*kdamonds_arr, nr_kdamonds,
2567 				    GFP_KERNEL | __GFP_NOWARN);
2568 	if (!kdamonds_arr)
2569 		return -ENOMEM;
2570 	kdamonds->kdamonds_arr = kdamonds_arr;
2571 
2572 	for (i = 0; i < nr_kdamonds; i++) {
2573 		kdamond = damon_sysfs_kdamond_alloc();
2574 		if (!kdamond) {
2575 			damon_sysfs_kdamonds_rm_dirs(kdamonds);
2576 			return -ENOMEM;
2577 		}
2578 
2579 		err = kobject_init_and_add(&kdamond->kobj,
2580 				&damon_sysfs_kdamond_ktype, &kdamonds->kobj,
2581 				"%d", i);
2582 		if (err)
2583 			goto out;
2584 
2585 		err = damon_sysfs_kdamond_add_dirs(kdamond);
2586 		if (err)
2587 			goto del_out;
2588 
2589 		kdamonds_arr[i] = kdamond;
2590 		kdamonds->nr++;
2591 	}
2592 	return 0;
2593 
2594 del_out:
2595 	kobject_del(&kdamond->kobj);
2596 out:
2597 	damon_sysfs_kdamonds_rm_dirs(kdamonds);
2598 	kobject_put(&kdamond->kobj);
2599 	return err;
2600 }
2601 
2602 static ssize_t nr_kdamonds_show(struct kobject *kobj,
2603 		struct kobj_attribute *attr, char *buf)
2604 {
2605 	struct damon_sysfs_kdamonds *kdamonds = container_of(kobj,
2606 			struct damon_sysfs_kdamonds, kobj);
2607 
2608 	return sysfs_emit(buf, "%d\n", kdamonds->nr);
2609 }
2610 
2611 static ssize_t nr_kdamonds_store(struct kobject *kobj,
2612 		struct kobj_attribute *attr, const char *buf, size_t count)
2613 {
2614 	struct damon_sysfs_kdamonds *kdamonds;
2615 	int nr, err;
2616 
2617 	err = kstrtoint(buf, 0, &nr);
2618 	if (err)
2619 		return err;
2620 	if (nr < 0)
2621 		return -EINVAL;
2622 
2623 	kdamonds = container_of(kobj, struct damon_sysfs_kdamonds, kobj);
2624 
2625 	if (!mutex_trylock(&damon_sysfs_lock))
2626 		return -EBUSY;
2627 	err = damon_sysfs_kdamonds_add_dirs(kdamonds, nr);
2628 	mutex_unlock(&damon_sysfs_lock);
2629 	if (err)
2630 		return err;
2631 
2632 	return count;
2633 }
2634 
2635 static void damon_sysfs_kdamonds_release(struct kobject *kobj)
2636 {
2637 	kfree(container_of(kobj, struct damon_sysfs_kdamonds, kobj));
2638 }
2639 
2640 static struct kobj_attribute damon_sysfs_kdamonds_nr_attr =
2641 		__ATTR_RW_MODE(nr_kdamonds, 0600);
2642 
2643 static struct attribute *damon_sysfs_kdamonds_attrs[] = {
2644 	&damon_sysfs_kdamonds_nr_attr.attr,
2645 	NULL,
2646 };
2647 ATTRIBUTE_GROUPS(damon_sysfs_kdamonds);
2648 
2649 static const struct kobj_type damon_sysfs_kdamonds_ktype = {
2650 	.release = damon_sysfs_kdamonds_release,
2651 	.sysfs_ops = &kobj_sysfs_ops,
2652 	.default_groups = damon_sysfs_kdamonds_groups,
2653 };
2654 
2655 /*
2656  * damon user interface directory
2657  */
2658 
2659 struct damon_sysfs_ui_dir {
2660 	struct kobject kobj;
2661 	struct damon_sysfs_kdamonds *kdamonds;
2662 };
2663 
2664 static struct damon_sysfs_ui_dir *damon_sysfs_ui_dir_alloc(void)
2665 {
2666 	return kzalloc_obj(struct damon_sysfs_ui_dir);
2667 }
2668 
2669 static int damon_sysfs_ui_dir_add_dirs(struct damon_sysfs_ui_dir *ui_dir)
2670 {
2671 	struct damon_sysfs_kdamonds *kdamonds;
2672 	int err;
2673 
2674 	kdamonds = damon_sysfs_kdamonds_alloc();
2675 	if (!kdamonds)
2676 		return -ENOMEM;
2677 
2678 	err = kobject_init_and_add(&kdamonds->kobj,
2679 			&damon_sysfs_kdamonds_ktype, &ui_dir->kobj,
2680 			"kdamonds");
2681 	if (err) {
2682 		kobject_put(&kdamonds->kobj);
2683 		return err;
2684 	}
2685 	ui_dir->kdamonds = kdamonds;
2686 	return err;
2687 }
2688 
2689 static void damon_sysfs_ui_dir_release(struct kobject *kobj)
2690 {
2691 	kfree(container_of(kobj, struct damon_sysfs_ui_dir, kobj));
2692 }
2693 
2694 static struct attribute *damon_sysfs_ui_dir_attrs[] = {
2695 	NULL,
2696 };
2697 ATTRIBUTE_GROUPS(damon_sysfs_ui_dir);
2698 
2699 static const struct kobj_type damon_sysfs_ui_dir_ktype = {
2700 	.release = damon_sysfs_ui_dir_release,
2701 	.sysfs_ops = &kobj_sysfs_ops,
2702 	.default_groups = damon_sysfs_ui_dir_groups,
2703 };
2704 
2705 static int __init damon_sysfs_init(void)
2706 {
2707 	struct kobject *damon_sysfs_root;
2708 	struct damon_sysfs_ui_dir *admin;
2709 	int err;
2710 
2711 	damon_sysfs_root = kobject_create_and_add("damon", mm_kobj);
2712 	if (!damon_sysfs_root)
2713 		return -ENOMEM;
2714 
2715 	admin = damon_sysfs_ui_dir_alloc();
2716 	if (!admin) {
2717 		kobject_put(damon_sysfs_root);
2718 		return -ENOMEM;
2719 	}
2720 	err = kobject_init_and_add(&admin->kobj, &damon_sysfs_ui_dir_ktype,
2721 			damon_sysfs_root, "admin");
2722 	if (err)
2723 		goto out;
2724 	err = damon_sysfs_ui_dir_add_dirs(admin);
2725 	if (err)
2726 		goto out;
2727 	return 0;
2728 
2729 out:
2730 	kobject_put(&admin->kobj);
2731 	kobject_put(damon_sysfs_root);
2732 	return err;
2733 }
2734 subsys_initcall(damon_sysfs_init);
2735 
2736 #include "tests/sysfs-kunit.h"
2737