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