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