03ff364c15544fcf5f7504ea98e6584daba7b2c7
[linux-2.6-microblaze.git] / mm / damon / sysfs.c
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  * scheme/weights directory
118  */
119
120 struct damon_sysfs_weights {
121         struct kobject kobj;
122         unsigned int sz;
123         unsigned int nr_accesses;
124         unsigned int age;
125 };
126
127 static struct damon_sysfs_weights *damon_sysfs_weights_alloc(unsigned int sz,
128                 unsigned int nr_accesses, unsigned int age)
129 {
130         struct damon_sysfs_weights *weights = kmalloc(sizeof(*weights),
131                         GFP_KERNEL);
132
133         if (!weights)
134                 return NULL;
135         weights->kobj = (struct kobject){};
136         weights->sz = sz;
137         weights->nr_accesses = nr_accesses;
138         weights->age = age;
139         return weights;
140 }
141
142 static ssize_t sz_permil_show(struct kobject *kobj,
143                 struct kobj_attribute *attr, char *buf)
144 {
145         struct damon_sysfs_weights *weights = container_of(kobj,
146                         struct damon_sysfs_weights, kobj);
147
148         return sysfs_emit(buf, "%u\n", weights->sz);
149 }
150
151 static ssize_t sz_permil_store(struct kobject *kobj,
152                 struct kobj_attribute *attr, const char *buf, size_t count)
153 {
154         struct damon_sysfs_weights *weights = container_of(kobj,
155                         struct damon_sysfs_weights, kobj);
156         int err = kstrtouint(buf, 0, &weights->sz);
157
158         if (err)
159                 return -EINVAL;
160         return count;
161 }
162
163 static ssize_t nr_accesses_permil_show(struct kobject *kobj,
164                 struct kobj_attribute *attr, char *buf)
165 {
166         struct damon_sysfs_weights *weights = container_of(kobj,
167                         struct damon_sysfs_weights, kobj);
168
169         return sysfs_emit(buf, "%u\n", weights->nr_accesses);
170 }
171
172 static ssize_t nr_accesses_permil_store(struct kobject *kobj,
173                 struct kobj_attribute *attr, const char *buf, size_t count)
174 {
175         struct damon_sysfs_weights *weights = container_of(kobj,
176                         struct damon_sysfs_weights, kobj);
177         int err = kstrtouint(buf, 0, &weights->nr_accesses);
178
179         if (err)
180                 return -EINVAL;
181         return count;
182 }
183
184 static ssize_t age_permil_show(struct kobject *kobj,
185                 struct kobj_attribute *attr, char *buf)
186 {
187         struct damon_sysfs_weights *weights = container_of(kobj,
188                         struct damon_sysfs_weights, kobj);
189
190         return sysfs_emit(buf, "%u\n", weights->age);
191 }
192
193 static ssize_t age_permil_store(struct kobject *kobj,
194                 struct kobj_attribute *attr, const char *buf, size_t count)
195 {
196         struct damon_sysfs_weights *weights = container_of(kobj,
197                         struct damon_sysfs_weights, kobj);
198         int err = kstrtouint(buf, 0, &weights->age);
199
200         if (err)
201                 return -EINVAL;
202         return count;
203 }
204
205 static void damon_sysfs_weights_release(struct kobject *kobj)
206 {
207         kfree(container_of(kobj, struct damon_sysfs_weights, kobj));
208 }
209
210 static struct kobj_attribute damon_sysfs_weights_sz_attr =
211                 __ATTR_RW_MODE(sz_permil, 0600);
212
213 static struct kobj_attribute damon_sysfs_weights_nr_accesses_attr =
214                 __ATTR_RW_MODE(nr_accesses_permil, 0600);
215
216 static struct kobj_attribute damon_sysfs_weights_age_attr =
217                 __ATTR_RW_MODE(age_permil, 0600);
218
219 static struct attribute *damon_sysfs_weights_attrs[] = {
220         &damon_sysfs_weights_sz_attr.attr,
221         &damon_sysfs_weights_nr_accesses_attr.attr,
222         &damon_sysfs_weights_age_attr.attr,
223         NULL,
224 };
225 ATTRIBUTE_GROUPS(damon_sysfs_weights);
226
227 static struct kobj_type damon_sysfs_weights_ktype = {
228         .release = damon_sysfs_weights_release,
229         .sysfs_ops = &kobj_sysfs_ops,
230         .default_groups = damon_sysfs_weights_groups,
231 };
232
233 /*
234  * quotas directory
235  */
236
237 struct damon_sysfs_quotas {
238         struct kobject kobj;
239         struct damon_sysfs_weights *weights;
240         unsigned long ms;
241         unsigned long sz;
242         unsigned long reset_interval_ms;
243 };
244
245 static struct damon_sysfs_quotas *damon_sysfs_quotas_alloc(void)
246 {
247         return kzalloc(sizeof(struct damon_sysfs_quotas), GFP_KERNEL);
248 }
249
250 static int damon_sysfs_quotas_add_dirs(struct damon_sysfs_quotas *quotas)
251 {
252         struct damon_sysfs_weights *weights;
253         int err;
254
255         weights = damon_sysfs_weights_alloc(0, 0, 0);
256         if (!weights)
257                 return -ENOMEM;
258
259         err = kobject_init_and_add(&weights->kobj, &damon_sysfs_weights_ktype,
260                         &quotas->kobj, "weights");
261         if (err)
262                 kobject_put(&weights->kobj);
263         else
264                 quotas->weights = weights;
265         return err;
266 }
267
268 static void damon_sysfs_quotas_rm_dirs(struct damon_sysfs_quotas *quotas)
269 {
270         kobject_put(&quotas->weights->kobj);
271 }
272
273 static ssize_t ms_show(struct kobject *kobj, struct kobj_attribute *attr,
274                 char *buf)
275 {
276         struct damon_sysfs_quotas *quotas = container_of(kobj,
277                         struct damon_sysfs_quotas, kobj);
278
279         return sysfs_emit(buf, "%lu\n", quotas->ms);
280 }
281
282 static ssize_t ms_store(struct kobject *kobj, struct kobj_attribute *attr,
283                 const char *buf, size_t count)
284 {
285         struct damon_sysfs_quotas *quotas = container_of(kobj,
286                         struct damon_sysfs_quotas, kobj);
287         int err = kstrtoul(buf, 0, &quotas->ms);
288
289         if (err)
290                 return -EINVAL;
291         return count;
292 }
293
294 static ssize_t bytes_show(struct kobject *kobj, struct kobj_attribute *attr,
295                 char *buf)
296 {
297         struct damon_sysfs_quotas *quotas = container_of(kobj,
298                         struct damon_sysfs_quotas, kobj);
299
300         return sysfs_emit(buf, "%lu\n", quotas->sz);
301 }
302
303 static ssize_t bytes_store(struct kobject *kobj,
304                 struct kobj_attribute *attr, const char *buf, size_t count)
305 {
306         struct damon_sysfs_quotas *quotas = container_of(kobj,
307                         struct damon_sysfs_quotas, kobj);
308         int err = kstrtoul(buf, 0, &quotas->sz);
309
310         if (err)
311                 return -EINVAL;
312         return count;
313 }
314
315 static ssize_t reset_interval_ms_show(struct kobject *kobj,
316                 struct kobj_attribute *attr, char *buf)
317 {
318         struct damon_sysfs_quotas *quotas = container_of(kobj,
319                         struct damon_sysfs_quotas, kobj);
320
321         return sysfs_emit(buf, "%lu\n", quotas->reset_interval_ms);
322 }
323
324 static ssize_t reset_interval_ms_store(struct kobject *kobj,
325                 struct kobj_attribute *attr, const char *buf, size_t count)
326 {
327         struct damon_sysfs_quotas *quotas = container_of(kobj,
328                         struct damon_sysfs_quotas, kobj);
329         int err = kstrtoul(buf, 0, &quotas->reset_interval_ms);
330
331         if (err)
332                 return -EINVAL;
333         return count;
334 }
335
336 static void damon_sysfs_quotas_release(struct kobject *kobj)
337 {
338         kfree(container_of(kobj, struct damon_sysfs_quotas, kobj));
339 }
340
341 static struct kobj_attribute damon_sysfs_quotas_ms_attr =
342                 __ATTR_RW_MODE(ms, 0600);
343
344 static struct kobj_attribute damon_sysfs_quotas_sz_attr =
345                 __ATTR_RW_MODE(bytes, 0600);
346
347 static struct kobj_attribute damon_sysfs_quotas_reset_interval_ms_attr =
348                 __ATTR_RW_MODE(reset_interval_ms, 0600);
349
350 static struct attribute *damon_sysfs_quotas_attrs[] = {
351         &damon_sysfs_quotas_ms_attr.attr,
352         &damon_sysfs_quotas_sz_attr.attr,
353         &damon_sysfs_quotas_reset_interval_ms_attr.attr,
354         NULL,
355 };
356 ATTRIBUTE_GROUPS(damon_sysfs_quotas);
357
358 static struct kobj_type damon_sysfs_quotas_ktype = {
359         .release = damon_sysfs_quotas_release,
360         .sysfs_ops = &kobj_sysfs_ops,
361         .default_groups = damon_sysfs_quotas_groups,
362 };
363
364 /*
365  * access_pattern directory
366  */
367
368 struct damon_sysfs_access_pattern {
369         struct kobject kobj;
370         struct damon_sysfs_ul_range *sz;
371         struct damon_sysfs_ul_range *nr_accesses;
372         struct damon_sysfs_ul_range *age;
373 };
374
375 static
376 struct damon_sysfs_access_pattern *damon_sysfs_access_pattern_alloc(void)
377 {
378         struct damon_sysfs_access_pattern *access_pattern =
379                 kmalloc(sizeof(*access_pattern), GFP_KERNEL);
380
381         if (!access_pattern)
382                 return NULL;
383         access_pattern->kobj = (struct kobject){};
384         return access_pattern;
385 }
386
387 static int damon_sysfs_access_pattern_add_range_dir(
388                 struct damon_sysfs_access_pattern *access_pattern,
389                 struct damon_sysfs_ul_range **range_dir_ptr,
390                 char *name)
391 {
392         struct damon_sysfs_ul_range *range = damon_sysfs_ul_range_alloc(0, 0);
393         int err;
394
395         if (!range)
396                 return -ENOMEM;
397         err = kobject_init_and_add(&range->kobj, &damon_sysfs_ul_range_ktype,
398                         &access_pattern->kobj, name);
399         if (err)
400                 kobject_put(&range->kobj);
401         else
402                 *range_dir_ptr = range;
403         return err;
404 }
405
406 static int damon_sysfs_access_pattern_add_dirs(
407                 struct damon_sysfs_access_pattern *access_pattern)
408 {
409         int err;
410
411         err = damon_sysfs_access_pattern_add_range_dir(access_pattern,
412                         &access_pattern->sz, "sz");
413         if (err)
414                 goto put_sz_out;
415
416         err = damon_sysfs_access_pattern_add_range_dir(access_pattern,
417                         &access_pattern->nr_accesses, "nr_accesses");
418         if (err)
419                 goto put_nr_accesses_sz_out;
420
421         err = damon_sysfs_access_pattern_add_range_dir(access_pattern,
422                         &access_pattern->age, "age");
423         if (err)
424                 goto put_age_nr_accesses_sz_out;
425         return 0;
426
427 put_age_nr_accesses_sz_out:
428         kobject_put(&access_pattern->age->kobj);
429         access_pattern->age = NULL;
430 put_nr_accesses_sz_out:
431         kobject_put(&access_pattern->nr_accesses->kobj);
432         access_pattern->nr_accesses = NULL;
433 put_sz_out:
434         kobject_put(&access_pattern->sz->kobj);
435         access_pattern->sz = NULL;
436         return err;
437 }
438
439 static void damon_sysfs_access_pattern_rm_dirs(
440                 struct damon_sysfs_access_pattern *access_pattern)
441 {
442         kobject_put(&access_pattern->sz->kobj);
443         kobject_put(&access_pattern->nr_accesses->kobj);
444         kobject_put(&access_pattern->age->kobj);
445 }
446
447 static void damon_sysfs_access_pattern_release(struct kobject *kobj)
448 {
449         kfree(container_of(kobj, struct damon_sysfs_access_pattern, kobj));
450 }
451
452 static struct attribute *damon_sysfs_access_pattern_attrs[] = {
453         NULL,
454 };
455 ATTRIBUTE_GROUPS(damon_sysfs_access_pattern);
456
457 static struct kobj_type damon_sysfs_access_pattern_ktype = {
458         .release = damon_sysfs_access_pattern_release,
459         .sysfs_ops = &kobj_sysfs_ops,
460         .default_groups = damon_sysfs_access_pattern_groups,
461 };
462
463 /*
464  * scheme directory
465  */
466
467 struct damon_sysfs_scheme {
468         struct kobject kobj;
469         enum damos_action action;
470         struct damon_sysfs_access_pattern *access_pattern;
471         struct damon_sysfs_quotas *quotas;
472 };
473
474 /* This should match with enum damos_action */
475 static const char * const damon_sysfs_damos_action_strs[] = {
476         "willneed",
477         "cold",
478         "pageout",
479         "hugepage",
480         "nohugepage",
481         "stat",
482 };
483
484 static struct damon_sysfs_scheme *damon_sysfs_scheme_alloc(
485                 enum damos_action action)
486 {
487         struct damon_sysfs_scheme *scheme = kmalloc(sizeof(*scheme),
488                                 GFP_KERNEL);
489
490         if (!scheme)
491                 return NULL;
492         scheme->kobj = (struct kobject){};
493         scheme->action = action;
494         return scheme;
495 }
496
497 static int damon_sysfs_scheme_set_access_pattern(
498                 struct damon_sysfs_scheme *scheme)
499 {
500         struct damon_sysfs_access_pattern *access_pattern;
501         int err;
502
503         access_pattern = damon_sysfs_access_pattern_alloc();
504         if (!access_pattern)
505                 return -ENOMEM;
506         err = kobject_init_and_add(&access_pattern->kobj,
507                         &damon_sysfs_access_pattern_ktype, &scheme->kobj,
508                         "access_pattern");
509         if (err)
510                 goto out;
511         err = damon_sysfs_access_pattern_add_dirs(access_pattern);
512         if (err)
513                 goto out;
514         scheme->access_pattern = access_pattern;
515         return 0;
516
517 out:
518         kobject_put(&access_pattern->kobj);
519         return err;
520 }
521
522 static int damon_sysfs_scheme_set_quotas(struct damon_sysfs_scheme *scheme)
523 {
524         struct damon_sysfs_quotas *quotas = damon_sysfs_quotas_alloc();
525         int err;
526
527         if (!quotas)
528                 return -ENOMEM;
529         err = kobject_init_and_add(&quotas->kobj, &damon_sysfs_quotas_ktype,
530                         &scheme->kobj, "quotas");
531         if (err)
532                 goto out;
533         err = damon_sysfs_quotas_add_dirs(quotas);
534         if (err)
535                 goto out;
536         scheme->quotas = quotas;
537         return 0;
538
539 out:
540         kobject_put(&quotas->kobj);
541         return err;
542 }
543
544 static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme)
545 {
546         int err;
547
548         err = damon_sysfs_scheme_set_access_pattern(scheme);
549         if (err)
550                 return err;
551         err = damon_sysfs_scheme_set_quotas(scheme);
552         if (err)
553                 goto put_access_pattern_out;
554         return 0;
555
556 put_access_pattern_out:
557         kobject_put(&scheme->access_pattern->kobj);
558         scheme->access_pattern = NULL;
559         return err;
560 }
561
562 static void damon_sysfs_scheme_rm_dirs(struct damon_sysfs_scheme *scheme)
563 {
564         damon_sysfs_access_pattern_rm_dirs(scheme->access_pattern);
565         kobject_put(&scheme->access_pattern->kobj);
566         damon_sysfs_quotas_rm_dirs(scheme->quotas);
567         kobject_put(&scheme->quotas->kobj);
568 }
569
570 static ssize_t action_show(struct kobject *kobj, struct kobj_attribute *attr,
571                 char *buf)
572 {
573         struct damon_sysfs_scheme *scheme = container_of(kobj,
574                         struct damon_sysfs_scheme, kobj);
575
576         return sysfs_emit(buf, "%s\n",
577                         damon_sysfs_damos_action_strs[scheme->action]);
578 }
579
580 static ssize_t action_store(struct kobject *kobj, struct kobj_attribute *attr,
581                 const char *buf, size_t count)
582 {
583         struct damon_sysfs_scheme *scheme = container_of(kobj,
584                         struct damon_sysfs_scheme, kobj);
585         enum damos_action action;
586
587         for (action = 0; action < NR_DAMOS_ACTIONS; action++) {
588                 if (sysfs_streq(buf, damon_sysfs_damos_action_strs[action])) {
589                         scheme->action = action;
590                         return count;
591                 }
592         }
593         return -EINVAL;
594 }
595
596 static void damon_sysfs_scheme_release(struct kobject *kobj)
597 {
598         kfree(container_of(kobj, struct damon_sysfs_scheme, kobj));
599 }
600
601 static struct kobj_attribute damon_sysfs_scheme_action_attr =
602                 __ATTR_RW_MODE(action, 0600);
603
604 static struct attribute *damon_sysfs_scheme_attrs[] = {
605         &damon_sysfs_scheme_action_attr.attr,
606         NULL,
607 };
608 ATTRIBUTE_GROUPS(damon_sysfs_scheme);
609
610 static struct kobj_type damon_sysfs_scheme_ktype = {
611         .release = damon_sysfs_scheme_release,
612         .sysfs_ops = &kobj_sysfs_ops,
613         .default_groups = damon_sysfs_scheme_groups,
614 };
615
616 /*
617  * schemes directory
618  */
619
620 struct damon_sysfs_schemes {
621         struct kobject kobj;
622         struct damon_sysfs_scheme **schemes_arr;
623         int nr;
624 };
625
626 static struct damon_sysfs_schemes *damon_sysfs_schemes_alloc(void)
627 {
628         return kzalloc(sizeof(struct damon_sysfs_schemes), GFP_KERNEL);
629 }
630
631 static void damon_sysfs_schemes_rm_dirs(struct damon_sysfs_schemes *schemes)
632 {
633         struct damon_sysfs_scheme **schemes_arr = schemes->schemes_arr;
634         int i;
635
636         for (i = 0; i < schemes->nr; i++) {
637                 damon_sysfs_scheme_rm_dirs(schemes_arr[i]);
638                 kobject_put(&schemes_arr[i]->kobj);
639         }
640         schemes->nr = 0;
641         kfree(schemes_arr);
642         schemes->schemes_arr = NULL;
643 }
644
645 static int damon_sysfs_schemes_add_dirs(struct damon_sysfs_schemes *schemes,
646                 int nr_schemes)
647 {
648         struct damon_sysfs_scheme **schemes_arr, *scheme;
649         int err, i;
650
651         damon_sysfs_schemes_rm_dirs(schemes);
652         if (!nr_schemes)
653                 return 0;
654
655         schemes_arr = kmalloc_array(nr_schemes, sizeof(*schemes_arr),
656                         GFP_KERNEL | __GFP_NOWARN);
657         if (!schemes_arr)
658                 return -ENOMEM;
659         schemes->schemes_arr = schemes_arr;
660
661         for (i = 0; i < nr_schemes; i++) {
662                 scheme = damon_sysfs_scheme_alloc(DAMOS_STAT);
663                 if (!scheme) {
664                         damon_sysfs_schemes_rm_dirs(schemes);
665                         return -ENOMEM;
666                 }
667
668                 err = kobject_init_and_add(&scheme->kobj,
669                                 &damon_sysfs_scheme_ktype, &schemes->kobj,
670                                 "%d", i);
671                 if (err)
672                         goto out;
673                 err = damon_sysfs_scheme_add_dirs(scheme);
674                 if (err)
675                         goto out;
676
677                 schemes_arr[i] = scheme;
678                 schemes->nr++;
679         }
680         return 0;
681
682 out:
683         damon_sysfs_schemes_rm_dirs(schemes);
684         kobject_put(&scheme->kobj);
685         return err;
686 }
687
688 static ssize_t nr_schemes_show(struct kobject *kobj,
689                 struct kobj_attribute *attr, char *buf)
690 {
691         struct damon_sysfs_schemes *schemes = container_of(kobj,
692                         struct damon_sysfs_schemes, kobj);
693
694         return sysfs_emit(buf, "%d\n", schemes->nr);
695 }
696
697 static ssize_t nr_schemes_store(struct kobject *kobj,
698                 struct kobj_attribute *attr, const char *buf, size_t count)
699 {
700         struct damon_sysfs_schemes *schemes = container_of(kobj,
701                         struct damon_sysfs_schemes, kobj);
702         int nr, err = kstrtoint(buf, 0, &nr);
703
704         if (err)
705                 return err;
706         if (nr < 0)
707                 return -EINVAL;
708
709         if (!mutex_trylock(&damon_sysfs_lock))
710                 return -EBUSY;
711         err = damon_sysfs_schemes_add_dirs(schemes, nr);
712         mutex_unlock(&damon_sysfs_lock);
713         if (err)
714                 return err;
715         return count;
716 }
717
718 static void damon_sysfs_schemes_release(struct kobject *kobj)
719 {
720         kfree(container_of(kobj, struct damon_sysfs_schemes, kobj));
721 }
722
723 static struct kobj_attribute damon_sysfs_schemes_nr_attr =
724                 __ATTR_RW_MODE(nr_schemes, 0600);
725
726 static struct attribute *damon_sysfs_schemes_attrs[] = {
727         &damon_sysfs_schemes_nr_attr.attr,
728         NULL,
729 };
730 ATTRIBUTE_GROUPS(damon_sysfs_schemes);
731
732 static struct kobj_type damon_sysfs_schemes_ktype = {
733         .release = damon_sysfs_schemes_release,
734         .sysfs_ops = &kobj_sysfs_ops,
735         .default_groups = damon_sysfs_schemes_groups,
736 };
737
738 /*
739  * init region directory
740  */
741
742 struct damon_sysfs_region {
743         struct kobject kobj;
744         unsigned long start;
745         unsigned long end;
746 };
747
748 static struct damon_sysfs_region *damon_sysfs_region_alloc(
749                 unsigned long start,
750                 unsigned long end)
751 {
752         struct damon_sysfs_region *region = kmalloc(sizeof(*region),
753                         GFP_KERNEL);
754
755         if (!region)
756                 return NULL;
757         region->kobj = (struct kobject){};
758         region->start = start;
759         region->end = end;
760         return region;
761 }
762
763 static ssize_t start_show(struct kobject *kobj, struct kobj_attribute *attr,
764                 char *buf)
765 {
766         struct damon_sysfs_region *region = container_of(kobj,
767                         struct damon_sysfs_region, kobj);
768
769         return sysfs_emit(buf, "%lu\n", region->start);
770 }
771
772 static ssize_t start_store(struct kobject *kobj, struct kobj_attribute *attr,
773                 const char *buf, size_t count)
774 {
775         struct damon_sysfs_region *region = container_of(kobj,
776                         struct damon_sysfs_region, kobj);
777         int err = kstrtoul(buf, 0, &region->start);
778
779         if (err)
780                 return -EINVAL;
781         return count;
782 }
783
784 static ssize_t end_show(struct kobject *kobj, struct kobj_attribute *attr,
785                 char *buf)
786 {
787         struct damon_sysfs_region *region = container_of(kobj,
788                         struct damon_sysfs_region, kobj);
789
790         return sysfs_emit(buf, "%lu\n", region->end);
791 }
792
793 static ssize_t end_store(struct kobject *kobj, struct kobj_attribute *attr,
794                 const char *buf, size_t count)
795 {
796         struct damon_sysfs_region *region = container_of(kobj,
797                         struct damon_sysfs_region, kobj);
798         int err = kstrtoul(buf, 0, &region->end);
799
800         if (err)
801                 return -EINVAL;
802         return count;
803 }
804
805 static void damon_sysfs_region_release(struct kobject *kobj)
806 {
807         kfree(container_of(kobj, struct damon_sysfs_region, kobj));
808 }
809
810 static struct kobj_attribute damon_sysfs_region_start_attr =
811                 __ATTR_RW_MODE(start, 0600);
812
813 static struct kobj_attribute damon_sysfs_region_end_attr =
814                 __ATTR_RW_MODE(end, 0600);
815
816 static struct attribute *damon_sysfs_region_attrs[] = {
817         &damon_sysfs_region_start_attr.attr,
818         &damon_sysfs_region_end_attr.attr,
819         NULL,
820 };
821 ATTRIBUTE_GROUPS(damon_sysfs_region);
822
823 static struct kobj_type damon_sysfs_region_ktype = {
824         .release = damon_sysfs_region_release,
825         .sysfs_ops = &kobj_sysfs_ops,
826         .default_groups = damon_sysfs_region_groups,
827 };
828
829 /*
830  * init_regions directory
831  */
832
833 struct damon_sysfs_regions {
834         struct kobject kobj;
835         struct damon_sysfs_region **regions_arr;
836         int nr;
837 };
838
839 static struct damon_sysfs_regions *damon_sysfs_regions_alloc(void)
840 {
841         return kzalloc(sizeof(struct damon_sysfs_regions), GFP_KERNEL);
842 }
843
844 static void damon_sysfs_regions_rm_dirs(struct damon_sysfs_regions *regions)
845 {
846         struct damon_sysfs_region **regions_arr = regions->regions_arr;
847         int i;
848
849         for (i = 0; i < regions->nr; i++)
850                 kobject_put(&regions_arr[i]->kobj);
851         regions->nr = 0;
852         kfree(regions_arr);
853         regions->regions_arr = NULL;
854 }
855
856 static int damon_sysfs_regions_add_dirs(struct damon_sysfs_regions *regions,
857                 int nr_regions)
858 {
859         struct damon_sysfs_region **regions_arr, *region;
860         int err, i;
861
862         damon_sysfs_regions_rm_dirs(regions);
863         if (!nr_regions)
864                 return 0;
865
866         regions_arr = kmalloc_array(nr_regions, sizeof(*regions_arr),
867                         GFP_KERNEL | __GFP_NOWARN);
868         if (!regions_arr)
869                 return -ENOMEM;
870         regions->regions_arr = regions_arr;
871
872         for (i = 0; i < nr_regions; i++) {
873                 region = damon_sysfs_region_alloc(0, 0);
874                 if (!region) {
875                         damon_sysfs_regions_rm_dirs(regions);
876                         return -ENOMEM;
877                 }
878
879                 err = kobject_init_and_add(&region->kobj,
880                                 &damon_sysfs_region_ktype, &regions->kobj,
881                                 "%d", i);
882                 if (err) {
883                         kobject_put(&region->kobj);
884                         damon_sysfs_regions_rm_dirs(regions);
885                         return err;
886                 }
887
888                 regions_arr[i] = region;
889                 regions->nr++;
890         }
891         return 0;
892 }
893
894 static ssize_t nr_regions_show(struct kobject *kobj,
895                 struct kobj_attribute *attr, char *buf)
896 {
897         struct damon_sysfs_regions *regions = container_of(kobj,
898                         struct damon_sysfs_regions, kobj);
899
900         return sysfs_emit(buf, "%d\n", regions->nr);
901 }
902
903 static ssize_t nr_regions_store(struct kobject *kobj,
904                 struct kobj_attribute *attr, const char *buf, size_t count)
905 {
906         struct damon_sysfs_regions *regions = container_of(kobj,
907                         struct damon_sysfs_regions, kobj);
908         int nr, err = kstrtoint(buf, 0, &nr);
909
910         if (err)
911                 return err;
912         if (nr < 0)
913                 return -EINVAL;
914
915         if (!mutex_trylock(&damon_sysfs_lock))
916                 return -EBUSY;
917         err = damon_sysfs_regions_add_dirs(regions, nr);
918         mutex_unlock(&damon_sysfs_lock);
919         if (err)
920                 return err;
921
922         return count;
923 }
924
925 static void damon_sysfs_regions_release(struct kobject *kobj)
926 {
927         kfree(container_of(kobj, struct damon_sysfs_regions, kobj));
928 }
929
930 static struct kobj_attribute damon_sysfs_regions_nr_attr =
931                 __ATTR_RW_MODE(nr_regions, 0600);
932
933 static struct attribute *damon_sysfs_regions_attrs[] = {
934         &damon_sysfs_regions_nr_attr.attr,
935         NULL,
936 };
937 ATTRIBUTE_GROUPS(damon_sysfs_regions);
938
939 static struct kobj_type damon_sysfs_regions_ktype = {
940         .release = damon_sysfs_regions_release,
941         .sysfs_ops = &kobj_sysfs_ops,
942         .default_groups = damon_sysfs_regions_groups,
943 };
944
945 /*
946  * target directory
947  */
948
949 struct damon_sysfs_target {
950         struct kobject kobj;
951         struct damon_sysfs_regions *regions;
952         int pid;
953 };
954
955 static struct damon_sysfs_target *damon_sysfs_target_alloc(void)
956 {
957         return kzalloc(sizeof(struct damon_sysfs_target), GFP_KERNEL);
958 }
959
960 static int damon_sysfs_target_add_dirs(struct damon_sysfs_target *target)
961 {
962         struct damon_sysfs_regions *regions = damon_sysfs_regions_alloc();
963         int err;
964
965         if (!regions)
966                 return -ENOMEM;
967
968         err = kobject_init_and_add(&regions->kobj, &damon_sysfs_regions_ktype,
969                         &target->kobj, "regions");
970         if (err)
971                 kobject_put(&regions->kobj);
972         else
973                 target->regions = regions;
974         return err;
975 }
976
977 static void damon_sysfs_target_rm_dirs(struct damon_sysfs_target *target)
978 {
979         damon_sysfs_regions_rm_dirs(target->regions);
980         kobject_put(&target->regions->kobj);
981 }
982
983 static ssize_t pid_target_show(struct kobject *kobj,
984                 struct kobj_attribute *attr, char *buf)
985 {
986         struct damon_sysfs_target *target = container_of(kobj,
987                         struct damon_sysfs_target, kobj);
988
989         return sysfs_emit(buf, "%d\n", target->pid);
990 }
991
992 static ssize_t pid_target_store(struct kobject *kobj,
993                 struct kobj_attribute *attr, const char *buf, size_t count)
994 {
995         struct damon_sysfs_target *target = container_of(kobj,
996                         struct damon_sysfs_target, kobj);
997         int err = kstrtoint(buf, 0, &target->pid);
998
999         if (err)
1000                 return -EINVAL;
1001         return count;
1002 }
1003
1004 static void damon_sysfs_target_release(struct kobject *kobj)
1005 {
1006         kfree(container_of(kobj, struct damon_sysfs_target, kobj));
1007 }
1008
1009 static struct kobj_attribute damon_sysfs_target_pid_attr =
1010                 __ATTR_RW_MODE(pid_target, 0600);
1011
1012 static struct attribute *damon_sysfs_target_attrs[] = {
1013         &damon_sysfs_target_pid_attr.attr,
1014         NULL,
1015 };
1016 ATTRIBUTE_GROUPS(damon_sysfs_target);
1017
1018 static struct kobj_type damon_sysfs_target_ktype = {
1019         .release = damon_sysfs_target_release,
1020         .sysfs_ops = &kobj_sysfs_ops,
1021         .default_groups = damon_sysfs_target_groups,
1022 };
1023
1024 /*
1025  * targets directory
1026  */
1027
1028 struct damon_sysfs_targets {
1029         struct kobject kobj;
1030         struct damon_sysfs_target **targets_arr;
1031         int nr;
1032 };
1033
1034 static struct damon_sysfs_targets *damon_sysfs_targets_alloc(void)
1035 {
1036         return kzalloc(sizeof(struct damon_sysfs_targets), GFP_KERNEL);
1037 }
1038
1039 static void damon_sysfs_targets_rm_dirs(struct damon_sysfs_targets *targets)
1040 {
1041         struct damon_sysfs_target **targets_arr = targets->targets_arr;
1042         int i;
1043
1044         for (i = 0; i < targets->nr; i++) {
1045                 damon_sysfs_target_rm_dirs(targets_arr[i]);
1046                 kobject_put(&targets_arr[i]->kobj);
1047         }
1048         targets->nr = 0;
1049         kfree(targets_arr);
1050         targets->targets_arr = NULL;
1051 }
1052
1053 static int damon_sysfs_targets_add_dirs(struct damon_sysfs_targets *targets,
1054                 int nr_targets)
1055 {
1056         struct damon_sysfs_target **targets_arr, *target;
1057         int err, i;
1058
1059         damon_sysfs_targets_rm_dirs(targets);
1060         if (!nr_targets)
1061                 return 0;
1062
1063         targets_arr = kmalloc_array(nr_targets, sizeof(*targets_arr),
1064                         GFP_KERNEL | __GFP_NOWARN);
1065         if (!targets_arr)
1066                 return -ENOMEM;
1067         targets->targets_arr = targets_arr;
1068
1069         for (i = 0; i < nr_targets; i++) {
1070                 target = damon_sysfs_target_alloc();
1071                 if (!target) {
1072                         damon_sysfs_targets_rm_dirs(targets);
1073                         return -ENOMEM;
1074                 }
1075
1076                 err = kobject_init_and_add(&target->kobj,
1077                                 &damon_sysfs_target_ktype, &targets->kobj,
1078                                 "%d", i);
1079                 if (err)
1080                         goto out;
1081
1082                 err = damon_sysfs_target_add_dirs(target);
1083                 if (err)
1084                         goto out;
1085
1086                 targets_arr[i] = target;
1087                 targets->nr++;
1088         }
1089         return 0;
1090
1091 out:
1092         damon_sysfs_targets_rm_dirs(targets);
1093         kobject_put(&target->kobj);
1094         return err;
1095 }
1096
1097 static ssize_t nr_targets_show(struct kobject *kobj,
1098                 struct kobj_attribute *attr, char *buf)
1099 {
1100         struct damon_sysfs_targets *targets = container_of(kobj,
1101                         struct damon_sysfs_targets, kobj);
1102
1103         return sysfs_emit(buf, "%d\n", targets->nr);
1104 }
1105
1106 static ssize_t nr_targets_store(struct kobject *kobj,
1107                 struct kobj_attribute *attr, const char *buf, size_t count)
1108 {
1109         struct damon_sysfs_targets *targets = container_of(kobj,
1110                         struct damon_sysfs_targets, kobj);
1111         int nr, err = kstrtoint(buf, 0, &nr);
1112
1113         if (err)
1114                 return err;
1115         if (nr < 0)
1116                 return -EINVAL;
1117
1118         if (!mutex_trylock(&damon_sysfs_lock))
1119                 return -EBUSY;
1120         err = damon_sysfs_targets_add_dirs(targets, nr);
1121         mutex_unlock(&damon_sysfs_lock);
1122         if (err)
1123                 return err;
1124
1125         return count;
1126 }
1127
1128 static void damon_sysfs_targets_release(struct kobject *kobj)
1129 {
1130         kfree(container_of(kobj, struct damon_sysfs_targets, kobj));
1131 }
1132
1133 static struct kobj_attribute damon_sysfs_targets_nr_attr =
1134                 __ATTR_RW_MODE(nr_targets, 0600);
1135
1136 static struct attribute *damon_sysfs_targets_attrs[] = {
1137         &damon_sysfs_targets_nr_attr.attr,
1138         NULL,
1139 };
1140 ATTRIBUTE_GROUPS(damon_sysfs_targets);
1141
1142 static struct kobj_type damon_sysfs_targets_ktype = {
1143         .release = damon_sysfs_targets_release,
1144         .sysfs_ops = &kobj_sysfs_ops,
1145         .default_groups = damon_sysfs_targets_groups,
1146 };
1147
1148 /*
1149  * intervals directory
1150  */
1151
1152 struct damon_sysfs_intervals {
1153         struct kobject kobj;
1154         unsigned long sample_us;
1155         unsigned long aggr_us;
1156         unsigned long update_us;
1157 };
1158
1159 static struct damon_sysfs_intervals *damon_sysfs_intervals_alloc(
1160                 unsigned long sample_us, unsigned long aggr_us,
1161                 unsigned long update_us)
1162 {
1163         struct damon_sysfs_intervals *intervals = kmalloc(sizeof(*intervals),
1164                         GFP_KERNEL);
1165
1166         if (!intervals)
1167                 return NULL;
1168
1169         intervals->kobj = (struct kobject){};
1170         intervals->sample_us = sample_us;
1171         intervals->aggr_us = aggr_us;
1172         intervals->update_us = update_us;
1173         return intervals;
1174 }
1175
1176 static ssize_t sample_us_show(struct kobject *kobj,
1177                 struct kobj_attribute *attr, char *buf)
1178 {
1179         struct damon_sysfs_intervals *intervals = container_of(kobj,
1180                         struct damon_sysfs_intervals, kobj);
1181
1182         return sysfs_emit(buf, "%lu\n", intervals->sample_us);
1183 }
1184
1185 static ssize_t sample_us_store(struct kobject *kobj,
1186                 struct kobj_attribute *attr, const char *buf, size_t count)
1187 {
1188         struct damon_sysfs_intervals *intervals = container_of(kobj,
1189                         struct damon_sysfs_intervals, kobj);
1190         unsigned long us;
1191         int err = kstrtoul(buf, 0, &us);
1192
1193         if (err)
1194                 return -EINVAL;
1195
1196         intervals->sample_us = us;
1197         return count;
1198 }
1199
1200 static ssize_t aggr_us_show(struct kobject *kobj, struct kobj_attribute *attr,
1201                 char *buf)
1202 {
1203         struct damon_sysfs_intervals *intervals = container_of(kobj,
1204                         struct damon_sysfs_intervals, kobj);
1205
1206         return sysfs_emit(buf, "%lu\n", intervals->aggr_us);
1207 }
1208
1209 static ssize_t aggr_us_store(struct kobject *kobj, struct kobj_attribute *attr,
1210                 const char *buf, size_t count)
1211 {
1212         struct damon_sysfs_intervals *intervals = container_of(kobj,
1213                         struct damon_sysfs_intervals, kobj);
1214         unsigned long us;
1215         int err = kstrtoul(buf, 0, &us);
1216
1217         if (err)
1218                 return -EINVAL;
1219
1220         intervals->aggr_us = us;
1221         return count;
1222 }
1223
1224 static ssize_t update_us_show(struct kobject *kobj,
1225                 struct kobj_attribute *attr, char *buf)
1226 {
1227         struct damon_sysfs_intervals *intervals = container_of(kobj,
1228                         struct damon_sysfs_intervals, kobj);
1229
1230         return sysfs_emit(buf, "%lu\n", intervals->update_us);
1231 }
1232
1233 static ssize_t update_us_store(struct kobject *kobj,
1234                 struct kobj_attribute *attr, const char *buf, size_t count)
1235 {
1236         struct damon_sysfs_intervals *intervals = container_of(kobj,
1237                         struct damon_sysfs_intervals, kobj);
1238         unsigned long us;
1239         int err = kstrtoul(buf, 0, &us);
1240
1241         if (err)
1242                 return -EINVAL;
1243
1244         intervals->update_us = us;
1245         return count;
1246 }
1247
1248 static void damon_sysfs_intervals_release(struct kobject *kobj)
1249 {
1250         kfree(container_of(kobj, struct damon_sysfs_intervals, kobj));
1251 }
1252
1253 static struct kobj_attribute damon_sysfs_intervals_sample_us_attr =
1254                 __ATTR_RW_MODE(sample_us, 0600);
1255
1256 static struct kobj_attribute damon_sysfs_intervals_aggr_us_attr =
1257                 __ATTR_RW_MODE(aggr_us, 0600);
1258
1259 static struct kobj_attribute damon_sysfs_intervals_update_us_attr =
1260                 __ATTR_RW_MODE(update_us, 0600);
1261
1262 static struct attribute *damon_sysfs_intervals_attrs[] = {
1263         &damon_sysfs_intervals_sample_us_attr.attr,
1264         &damon_sysfs_intervals_aggr_us_attr.attr,
1265         &damon_sysfs_intervals_update_us_attr.attr,
1266         NULL,
1267 };
1268 ATTRIBUTE_GROUPS(damon_sysfs_intervals);
1269
1270 static struct kobj_type damon_sysfs_intervals_ktype = {
1271         .release = damon_sysfs_intervals_release,
1272         .sysfs_ops = &kobj_sysfs_ops,
1273         .default_groups = damon_sysfs_intervals_groups,
1274 };
1275
1276 /*
1277  * monitoring_attrs directory
1278  */
1279
1280 struct damon_sysfs_attrs {
1281         struct kobject kobj;
1282         struct damon_sysfs_intervals *intervals;
1283         struct damon_sysfs_ul_range *nr_regions_range;
1284 };
1285
1286 static struct damon_sysfs_attrs *damon_sysfs_attrs_alloc(void)
1287 {
1288         struct damon_sysfs_attrs *attrs = kmalloc(sizeof(*attrs), GFP_KERNEL);
1289
1290         if (!attrs)
1291                 return NULL;
1292         attrs->kobj = (struct kobject){};
1293         return attrs;
1294 }
1295
1296 static int damon_sysfs_attrs_add_dirs(struct damon_sysfs_attrs *attrs)
1297 {
1298         struct damon_sysfs_intervals *intervals;
1299         struct damon_sysfs_ul_range *nr_regions_range;
1300         int err;
1301
1302         intervals = damon_sysfs_intervals_alloc(5000, 100000, 60000000);
1303         if (!intervals)
1304                 return -ENOMEM;
1305
1306         err = kobject_init_and_add(&intervals->kobj,
1307                         &damon_sysfs_intervals_ktype, &attrs->kobj,
1308                         "intervals");
1309         if (err)
1310                 goto put_intervals_out;
1311         attrs->intervals = intervals;
1312
1313         nr_regions_range = damon_sysfs_ul_range_alloc(10, 1000);
1314         if (!nr_regions_range) {
1315                 err = -ENOMEM;
1316                 goto put_intervals_out;
1317         }
1318
1319         err = kobject_init_and_add(&nr_regions_range->kobj,
1320                         &damon_sysfs_ul_range_ktype, &attrs->kobj,
1321                         "nr_regions");
1322         if (err)
1323                 goto put_nr_regions_intervals_out;
1324         attrs->nr_regions_range = nr_regions_range;
1325         return 0;
1326
1327 put_nr_regions_intervals_out:
1328         kobject_put(&nr_regions_range->kobj);
1329         attrs->nr_regions_range = NULL;
1330 put_intervals_out:
1331         kobject_put(&intervals->kobj);
1332         attrs->intervals = NULL;
1333         return err;
1334 }
1335
1336 static void damon_sysfs_attrs_rm_dirs(struct damon_sysfs_attrs *attrs)
1337 {
1338         kobject_put(&attrs->nr_regions_range->kobj);
1339         kobject_put(&attrs->intervals->kobj);
1340 }
1341
1342 static void damon_sysfs_attrs_release(struct kobject *kobj)
1343 {
1344         kfree(container_of(kobj, struct damon_sysfs_attrs, kobj));
1345 }
1346
1347 static struct attribute *damon_sysfs_attrs_attrs[] = {
1348         NULL,
1349 };
1350 ATTRIBUTE_GROUPS(damon_sysfs_attrs);
1351
1352 static struct kobj_type damon_sysfs_attrs_ktype = {
1353         .release = damon_sysfs_attrs_release,
1354         .sysfs_ops = &kobj_sysfs_ops,
1355         .default_groups = damon_sysfs_attrs_groups,
1356 };
1357
1358 /*
1359  * context directory
1360  */
1361
1362 /* This should match with enum damon_ops_id */
1363 static const char * const damon_sysfs_ops_strs[] = {
1364         "vaddr",
1365         "paddr",
1366 };
1367
1368 struct damon_sysfs_context {
1369         struct kobject kobj;
1370         enum damon_ops_id ops_id;
1371         struct damon_sysfs_attrs *attrs;
1372         struct damon_sysfs_targets *targets;
1373         struct damon_sysfs_schemes *schemes;
1374 };
1375
1376 static struct damon_sysfs_context *damon_sysfs_context_alloc(
1377                 enum damon_ops_id ops_id)
1378 {
1379         struct damon_sysfs_context *context = kmalloc(sizeof(*context),
1380                                 GFP_KERNEL);
1381
1382         if (!context)
1383                 return NULL;
1384         context->kobj = (struct kobject){};
1385         context->ops_id = ops_id;
1386         return context;
1387 }
1388
1389 static int damon_sysfs_context_set_attrs(struct damon_sysfs_context *context)
1390 {
1391         struct damon_sysfs_attrs *attrs = damon_sysfs_attrs_alloc();
1392         int err;
1393
1394         if (!attrs)
1395                 return -ENOMEM;
1396         err = kobject_init_and_add(&attrs->kobj, &damon_sysfs_attrs_ktype,
1397                         &context->kobj, "monitoring_attrs");
1398         if (err)
1399                 goto out;
1400         err = damon_sysfs_attrs_add_dirs(attrs);
1401         if (err)
1402                 goto out;
1403         context->attrs = attrs;
1404         return 0;
1405
1406 out:
1407         kobject_put(&attrs->kobj);
1408         return err;
1409 }
1410
1411 static int damon_sysfs_context_set_targets(struct damon_sysfs_context *context)
1412 {
1413         struct damon_sysfs_targets *targets = damon_sysfs_targets_alloc();
1414         int err;
1415
1416         if (!targets)
1417                 return -ENOMEM;
1418         err = kobject_init_and_add(&targets->kobj, &damon_sysfs_targets_ktype,
1419                         &context->kobj, "targets");
1420         if (err) {
1421                 kobject_put(&targets->kobj);
1422                 return err;
1423         }
1424         context->targets = targets;
1425         return 0;
1426 }
1427
1428 static int damon_sysfs_context_set_schemes(struct damon_sysfs_context *context)
1429 {
1430         struct damon_sysfs_schemes *schemes = damon_sysfs_schemes_alloc();
1431         int err;
1432
1433         if (!schemes)
1434                 return -ENOMEM;
1435         err = kobject_init_and_add(&schemes->kobj, &damon_sysfs_schemes_ktype,
1436                         &context->kobj, "schemes");
1437         if (err) {
1438                 kobject_put(&schemes->kobj);
1439                 return err;
1440         }
1441         context->schemes = schemes;
1442         return 0;
1443 }
1444
1445 static int damon_sysfs_context_add_dirs(struct damon_sysfs_context *context)
1446 {
1447         int err;
1448
1449         err = damon_sysfs_context_set_attrs(context);
1450         if (err)
1451                 return err;
1452
1453         err = damon_sysfs_context_set_targets(context);
1454         if (err)
1455                 goto put_attrs_out;
1456
1457         err = damon_sysfs_context_set_schemes(context);
1458         if (err)
1459                 goto put_targets_attrs_out;
1460         return 0;
1461
1462 put_targets_attrs_out:
1463         kobject_put(&context->targets->kobj);
1464         context->targets = NULL;
1465 put_attrs_out:
1466         kobject_put(&context->attrs->kobj);
1467         context->attrs = NULL;
1468         return err;
1469 }
1470
1471 static void damon_sysfs_context_rm_dirs(struct damon_sysfs_context *context)
1472 {
1473         damon_sysfs_attrs_rm_dirs(context->attrs);
1474         kobject_put(&context->attrs->kobj);
1475         damon_sysfs_targets_rm_dirs(context->targets);
1476         kobject_put(&context->targets->kobj);
1477         damon_sysfs_schemes_rm_dirs(context->schemes);
1478         kobject_put(&context->schemes->kobj);
1479 }
1480
1481 static ssize_t operations_show(struct kobject *kobj,
1482                 struct kobj_attribute *attr, char *buf)
1483 {
1484         struct damon_sysfs_context *context = container_of(kobj,
1485                         struct damon_sysfs_context, kobj);
1486
1487         return sysfs_emit(buf, "%s\n", damon_sysfs_ops_strs[context->ops_id]);
1488 }
1489
1490 static ssize_t operations_store(struct kobject *kobj,
1491                 struct kobj_attribute *attr, const char *buf, size_t count)
1492 {
1493         struct damon_sysfs_context *context = container_of(kobj,
1494                         struct damon_sysfs_context, kobj);
1495         enum damon_ops_id id;
1496
1497         for (id = 0; id < NR_DAMON_OPS; id++) {
1498                 if (sysfs_streq(buf, damon_sysfs_ops_strs[id])) {
1499                         context->ops_id = id;
1500                         return count;
1501                 }
1502         }
1503         return -EINVAL;
1504 }
1505
1506 static void damon_sysfs_context_release(struct kobject *kobj)
1507 {
1508         kfree(container_of(kobj, struct damon_sysfs_context, kobj));
1509 }
1510
1511 static struct kobj_attribute damon_sysfs_context_operations_attr =
1512                 __ATTR_RW_MODE(operations, 0600);
1513
1514 static struct attribute *damon_sysfs_context_attrs[] = {
1515         &damon_sysfs_context_operations_attr.attr,
1516         NULL,
1517 };
1518 ATTRIBUTE_GROUPS(damon_sysfs_context);
1519
1520 static struct kobj_type damon_sysfs_context_ktype = {
1521         .release = damon_sysfs_context_release,
1522         .sysfs_ops = &kobj_sysfs_ops,
1523         .default_groups = damon_sysfs_context_groups,
1524 };
1525
1526 /*
1527  * contexts directory
1528  */
1529
1530 struct damon_sysfs_contexts {
1531         struct kobject kobj;
1532         struct damon_sysfs_context **contexts_arr;
1533         int nr;
1534 };
1535
1536 static struct damon_sysfs_contexts *damon_sysfs_contexts_alloc(void)
1537 {
1538         return kzalloc(sizeof(struct damon_sysfs_contexts), GFP_KERNEL);
1539 }
1540
1541 static void damon_sysfs_contexts_rm_dirs(struct damon_sysfs_contexts *contexts)
1542 {
1543         struct damon_sysfs_context **contexts_arr = contexts->contexts_arr;
1544         int i;
1545
1546         for (i = 0; i < contexts->nr; i++) {
1547                 damon_sysfs_context_rm_dirs(contexts_arr[i]);
1548                 kobject_put(&contexts_arr[i]->kobj);
1549         }
1550         contexts->nr = 0;
1551         kfree(contexts_arr);
1552         contexts->contexts_arr = NULL;
1553 }
1554
1555 static int damon_sysfs_contexts_add_dirs(struct damon_sysfs_contexts *contexts,
1556                 int nr_contexts)
1557 {
1558         struct damon_sysfs_context **contexts_arr, *context;
1559         int err, i;
1560
1561         damon_sysfs_contexts_rm_dirs(contexts);
1562         if (!nr_contexts)
1563                 return 0;
1564
1565         contexts_arr = kmalloc_array(nr_contexts, sizeof(*contexts_arr),
1566                         GFP_KERNEL | __GFP_NOWARN);
1567         if (!contexts_arr)
1568                 return -ENOMEM;
1569         contexts->contexts_arr = contexts_arr;
1570
1571         for (i = 0; i < nr_contexts; i++) {
1572                 context = damon_sysfs_context_alloc(DAMON_OPS_VADDR);
1573                 if (!context) {
1574                         damon_sysfs_contexts_rm_dirs(contexts);
1575                         return -ENOMEM;
1576                 }
1577
1578                 err = kobject_init_and_add(&context->kobj,
1579                                 &damon_sysfs_context_ktype, &contexts->kobj,
1580                                 "%d", i);
1581                 if (err)
1582                         goto out;
1583
1584                 err = damon_sysfs_context_add_dirs(context);
1585                 if (err)
1586                         goto out;
1587
1588                 contexts_arr[i] = context;
1589                 contexts->nr++;
1590         }
1591         return 0;
1592
1593 out:
1594         damon_sysfs_contexts_rm_dirs(contexts);
1595         kobject_put(&context->kobj);
1596         return err;
1597 }
1598
1599 static ssize_t nr_contexts_show(struct kobject *kobj,
1600                 struct kobj_attribute *attr, char *buf)
1601 {
1602         struct damon_sysfs_contexts *contexts = container_of(kobj,
1603                         struct damon_sysfs_contexts, kobj);
1604
1605         return sysfs_emit(buf, "%d\n", contexts->nr);
1606 }
1607
1608 static ssize_t nr_contexts_store(struct kobject *kobj,
1609                 struct kobj_attribute *attr, const char *buf, size_t count)
1610 {
1611         struct damon_sysfs_contexts *contexts = container_of(kobj,
1612                         struct damon_sysfs_contexts, kobj);
1613         int nr, err;
1614
1615         err = kstrtoint(buf, 0, &nr);
1616         if (err)
1617                 return err;
1618         /* TODO: support multiple contexts per kdamond */
1619         if (nr < 0 || 1 < nr)
1620                 return -EINVAL;
1621
1622         if (!mutex_trylock(&damon_sysfs_lock))
1623                 return -EBUSY;
1624         err = damon_sysfs_contexts_add_dirs(contexts, nr);
1625         mutex_unlock(&damon_sysfs_lock);
1626         if (err)
1627                 return err;
1628
1629         return count;
1630 }
1631
1632 static void damon_sysfs_contexts_release(struct kobject *kobj)
1633 {
1634         kfree(container_of(kobj, struct damon_sysfs_contexts, kobj));
1635 }
1636
1637 static struct kobj_attribute damon_sysfs_contexts_nr_attr
1638                 = __ATTR_RW_MODE(nr_contexts, 0600);
1639
1640 static struct attribute *damon_sysfs_contexts_attrs[] = {
1641         &damon_sysfs_contexts_nr_attr.attr,
1642         NULL,
1643 };
1644 ATTRIBUTE_GROUPS(damon_sysfs_contexts);
1645
1646 static struct kobj_type damon_sysfs_contexts_ktype = {
1647         .release = damon_sysfs_contexts_release,
1648         .sysfs_ops = &kobj_sysfs_ops,
1649         .default_groups = damon_sysfs_contexts_groups,
1650 };
1651
1652 /*
1653  * kdamond directory
1654  */
1655
1656 struct damon_sysfs_kdamond {
1657         struct kobject kobj;
1658         struct damon_sysfs_contexts *contexts;
1659         struct damon_ctx *damon_ctx;
1660 };
1661
1662 static struct damon_sysfs_kdamond *damon_sysfs_kdamond_alloc(void)
1663 {
1664         return kzalloc(sizeof(struct damon_sysfs_kdamond), GFP_KERNEL);
1665 }
1666
1667 static int damon_sysfs_kdamond_add_dirs(struct damon_sysfs_kdamond *kdamond)
1668 {
1669         struct damon_sysfs_contexts *contexts;
1670         int err;
1671
1672         contexts = damon_sysfs_contexts_alloc();
1673         if (!contexts)
1674                 return -ENOMEM;
1675
1676         err = kobject_init_and_add(&contexts->kobj,
1677                         &damon_sysfs_contexts_ktype, &kdamond->kobj,
1678                         "contexts");
1679         if (err) {
1680                 kobject_put(&contexts->kobj);
1681                 return err;
1682         }
1683         kdamond->contexts = contexts;
1684
1685         return err;
1686 }
1687
1688 static void damon_sysfs_kdamond_rm_dirs(struct damon_sysfs_kdamond *kdamond)
1689 {
1690         damon_sysfs_contexts_rm_dirs(kdamond->contexts);
1691         kobject_put(&kdamond->contexts->kobj);
1692 }
1693
1694 static bool damon_sysfs_ctx_running(struct damon_ctx *ctx)
1695 {
1696         bool running;
1697
1698         mutex_lock(&ctx->kdamond_lock);
1699         running = ctx->kdamond != NULL;
1700         mutex_unlock(&ctx->kdamond_lock);
1701         return running;
1702 }
1703
1704 static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
1705                 char *buf)
1706 {
1707         struct damon_sysfs_kdamond *kdamond = container_of(kobj,
1708                         struct damon_sysfs_kdamond, kobj);
1709         struct damon_ctx *ctx = kdamond->damon_ctx;
1710         bool running;
1711
1712         if (!ctx)
1713                 running = false;
1714         else
1715                 running = damon_sysfs_ctx_running(ctx);
1716
1717         return sysfs_emit(buf, "%s\n", running ? "on" : "off");
1718 }
1719
1720 static int damon_sysfs_set_attrs(struct damon_ctx *ctx,
1721                 struct damon_sysfs_attrs *sys_attrs)
1722 {
1723         struct damon_sysfs_intervals *sys_intervals = sys_attrs->intervals;
1724         struct damon_sysfs_ul_range *sys_nr_regions =
1725                 sys_attrs->nr_regions_range;
1726
1727         return damon_set_attrs(ctx, sys_intervals->sample_us,
1728                         sys_intervals->aggr_us, sys_intervals->update_us,
1729                         sys_nr_regions->min, sys_nr_regions->max);
1730 }
1731
1732 static void damon_sysfs_destroy_targets(struct damon_ctx *ctx)
1733 {
1734         struct damon_target *t, *next;
1735
1736         damon_for_each_target_safe(t, next, ctx) {
1737                 if (ctx->ops.id == DAMON_OPS_VADDR)
1738                         put_pid(t->pid);
1739                 damon_destroy_target(t);
1740         }
1741 }
1742
1743 static int damon_sysfs_set_regions(struct damon_target *t,
1744                 struct damon_sysfs_regions *sysfs_regions)
1745 {
1746         int i;
1747
1748         for (i = 0; i < sysfs_regions->nr; i++) {
1749                 struct damon_sysfs_region *sys_region =
1750                         sysfs_regions->regions_arr[i];
1751                 struct damon_region *prev, *r;
1752
1753                 if (sys_region->start > sys_region->end)
1754                         return -EINVAL;
1755                 r = damon_new_region(sys_region->start, sys_region->end);
1756                 if (!r)
1757                         return -ENOMEM;
1758                 damon_add_region(r, t);
1759                 if (damon_nr_regions(t) > 1) {
1760                         prev = damon_prev_region(r);
1761                         if (prev->ar.end > r->ar.start) {
1762                                 damon_destroy_region(r, t);
1763                                 return -EINVAL;
1764                         }
1765                 }
1766         }
1767         return 0;
1768 }
1769
1770 static int damon_sysfs_set_targets(struct damon_ctx *ctx,
1771                 struct damon_sysfs_targets *sysfs_targets)
1772 {
1773         int i, err;
1774
1775         for (i = 0; i < sysfs_targets->nr; i++) {
1776                 struct damon_sysfs_target *sys_target =
1777                         sysfs_targets->targets_arr[i];
1778                 struct damon_target *t = damon_new_target();
1779
1780                 if (!t) {
1781                         damon_sysfs_destroy_targets(ctx);
1782                         return -ENOMEM;
1783                 }
1784                 if (ctx->ops.id == DAMON_OPS_VADDR) {
1785                         t->pid = find_get_pid(sys_target->pid);
1786                         if (!t->pid) {
1787                                 damon_sysfs_destroy_targets(ctx);
1788                                 return -EINVAL;
1789                         }
1790                 }
1791                 damon_add_target(ctx, t);
1792                 err = damon_sysfs_set_regions(t, sys_target->regions);
1793                 if (err) {
1794                         damon_sysfs_destroy_targets(ctx);
1795                         return err;
1796                 }
1797         }
1798         return 0;
1799 }
1800
1801 static struct damos *damon_sysfs_mk_scheme(
1802                 struct damon_sysfs_scheme *sysfs_scheme)
1803 {
1804         struct damon_sysfs_access_pattern *pattern =
1805                 sysfs_scheme->access_pattern;
1806         struct damon_sysfs_quotas *sysfs_quotas = sysfs_scheme->quotas;
1807         struct damon_sysfs_weights *sysfs_weights = sysfs_quotas->weights;
1808         struct damos_quota quota = {
1809                 .ms = sysfs_quotas->ms,
1810                 .sz = sysfs_quotas->sz,
1811                 .reset_interval = sysfs_quotas->reset_interval_ms,
1812                 .weight_sz = sysfs_weights->sz,
1813                 .weight_nr_accesses = sysfs_weights->nr_accesses,
1814                 .weight_age = sysfs_weights->age,
1815         };
1816         struct damos_watermarks wmarks = {
1817                 .metric = DAMOS_WMARK_NONE,
1818                 .interval = 0,
1819                 .high = 0,
1820                 .mid = 0,
1821                 .low = 0,
1822         };
1823
1824         return damon_new_scheme(pattern->sz->min, pattern->sz->max,
1825                         pattern->nr_accesses->min, pattern->nr_accesses->max,
1826                         pattern->age->min, pattern->age->max,
1827                         sysfs_scheme->action, &quota, &wmarks);
1828 }
1829
1830 static int damon_sysfs_set_schemes(struct damon_ctx *ctx,
1831                 struct damon_sysfs_schemes *sysfs_schemes)
1832 {
1833         int i;
1834
1835         for (i = 0; i < sysfs_schemes->nr; i++) {
1836                 struct damos *scheme, *next;
1837
1838                 scheme = damon_sysfs_mk_scheme(sysfs_schemes->schemes_arr[i]);
1839                 if (!scheme) {
1840                         damon_for_each_scheme_safe(scheme, next, ctx)
1841                                 damon_destroy_scheme(scheme);
1842                         return -ENOMEM;
1843                 }
1844                 damon_add_scheme(ctx, scheme);
1845         }
1846         return 0;
1847 }
1848
1849 static void damon_sysfs_before_terminate(struct damon_ctx *ctx)
1850 {
1851         struct damon_target *t, *next;
1852
1853         if (ctx->ops.id != DAMON_OPS_VADDR)
1854                 return;
1855
1856         mutex_lock(&ctx->kdamond_lock);
1857         damon_for_each_target_safe(t, next, ctx) {
1858                 put_pid(t->pid);
1859                 damon_destroy_target(t);
1860         }
1861         mutex_unlock(&ctx->kdamond_lock);
1862 }
1863
1864 static struct damon_ctx *damon_sysfs_build_ctx(
1865                 struct damon_sysfs_context *sys_ctx)
1866 {
1867         struct damon_ctx *ctx = damon_new_ctx();
1868         int err;
1869
1870         if (!ctx)
1871                 return ERR_PTR(-ENOMEM);
1872
1873         err = damon_select_ops(ctx, sys_ctx->ops_id);
1874         if (err)
1875                 goto out;
1876         err = damon_sysfs_set_attrs(ctx, sys_ctx->attrs);
1877         if (err)
1878                 goto out;
1879         err = damon_sysfs_set_targets(ctx, sys_ctx->targets);
1880         if (err)
1881                 goto out;
1882         err = damon_sysfs_set_schemes(ctx, sys_ctx->schemes);
1883         if (err)
1884                 goto out;
1885
1886         ctx->callback.before_terminate = damon_sysfs_before_terminate;
1887         return ctx;
1888
1889 out:
1890         damon_destroy_ctx(ctx);
1891         return ERR_PTR(err);
1892 }
1893
1894 static int damon_sysfs_turn_damon_on(struct damon_sysfs_kdamond *kdamond)
1895 {
1896         struct damon_ctx *ctx;
1897         int err;
1898
1899         if (kdamond->damon_ctx &&
1900                         damon_sysfs_ctx_running(kdamond->damon_ctx))
1901                 return -EBUSY;
1902         /* TODO: support multiple contexts per kdamond */
1903         if (kdamond->contexts->nr != 1)
1904                 return -EINVAL;
1905
1906         if (kdamond->damon_ctx)
1907                 damon_destroy_ctx(kdamond->damon_ctx);
1908         kdamond->damon_ctx = NULL;
1909
1910         ctx = damon_sysfs_build_ctx(kdamond->contexts->contexts_arr[0]);
1911         if (IS_ERR(ctx))
1912                 return PTR_ERR(ctx);
1913         err = damon_start(&ctx, 1, false);
1914         if (err) {
1915                 damon_destroy_ctx(ctx);
1916                 return err;
1917         }
1918         kdamond->damon_ctx = ctx;
1919         return err;
1920 }
1921
1922 static int damon_sysfs_turn_damon_off(struct damon_sysfs_kdamond *kdamond)
1923 {
1924         if (!kdamond->damon_ctx)
1925                 return -EINVAL;
1926         return damon_stop(&kdamond->damon_ctx, 1);
1927         /*
1928          * To allow users show final monitoring results of already turned-off
1929          * DAMON, we free kdamond->damon_ctx in next
1930          * damon_sysfs_turn_damon_on(), or kdamonds_nr_store()
1931          */
1932 }
1933
1934 static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
1935                 const char *buf, size_t count)
1936 {
1937         struct damon_sysfs_kdamond *kdamond = container_of(kobj,
1938                         struct damon_sysfs_kdamond, kobj);
1939         ssize_t ret;
1940
1941         if (!mutex_trylock(&damon_sysfs_lock))
1942                 return -EBUSY;
1943         if (sysfs_streq(buf, "on"))
1944                 ret = damon_sysfs_turn_damon_on(kdamond);
1945         else if (sysfs_streq(buf, "off"))
1946                 ret = damon_sysfs_turn_damon_off(kdamond);
1947         else
1948                 ret = -EINVAL;
1949         mutex_unlock(&damon_sysfs_lock);
1950         if (!ret)
1951                 ret = count;
1952         return ret;
1953 }
1954
1955 static ssize_t pid_show(struct kobject *kobj,
1956                 struct kobj_attribute *attr, char *buf)
1957 {
1958         struct damon_sysfs_kdamond *kdamond = container_of(kobj,
1959                         struct damon_sysfs_kdamond, kobj);
1960         struct damon_ctx *ctx;
1961         int pid;
1962
1963         if (!mutex_trylock(&damon_sysfs_lock))
1964                 return -EBUSY;
1965         ctx = kdamond->damon_ctx;
1966         if (!ctx) {
1967                 pid = -1;
1968                 goto out;
1969         }
1970         mutex_lock(&ctx->kdamond_lock);
1971         if (!ctx->kdamond)
1972                 pid = -1;
1973         else
1974                 pid = ctx->kdamond->pid;
1975         mutex_unlock(&ctx->kdamond_lock);
1976 out:
1977         mutex_unlock(&damon_sysfs_lock);
1978         return sysfs_emit(buf, "%d\n", pid);
1979 }
1980
1981 static void damon_sysfs_kdamond_release(struct kobject *kobj)
1982 {
1983         struct damon_sysfs_kdamond *kdamond = container_of(kobj,
1984                         struct damon_sysfs_kdamond, kobj);
1985
1986         if (kdamond->damon_ctx)
1987                 damon_destroy_ctx(kdamond->damon_ctx);
1988         kfree(container_of(kobj, struct damon_sysfs_kdamond, kobj));
1989 }
1990
1991 static struct kobj_attribute damon_sysfs_kdamond_state_attr =
1992                 __ATTR_RW_MODE(state, 0600);
1993
1994 static struct kobj_attribute damon_sysfs_kdamond_pid_attr =
1995                 __ATTR_RO_MODE(pid, 0400);
1996
1997 static struct attribute *damon_sysfs_kdamond_attrs[] = {
1998         &damon_sysfs_kdamond_state_attr.attr,
1999         &damon_sysfs_kdamond_pid_attr.attr,
2000         NULL,
2001 };
2002 ATTRIBUTE_GROUPS(damon_sysfs_kdamond);
2003
2004 static struct kobj_type damon_sysfs_kdamond_ktype = {
2005         .release = damon_sysfs_kdamond_release,
2006         .sysfs_ops = &kobj_sysfs_ops,
2007         .default_groups = damon_sysfs_kdamond_groups,
2008 };
2009
2010 /*
2011  * kdamonds directory
2012  */
2013
2014 struct damon_sysfs_kdamonds {
2015         struct kobject kobj;
2016         struct damon_sysfs_kdamond **kdamonds_arr;
2017         int nr;
2018 };
2019
2020 static struct damon_sysfs_kdamonds *damon_sysfs_kdamonds_alloc(void)
2021 {
2022         return kzalloc(sizeof(struct damon_sysfs_kdamonds), GFP_KERNEL);
2023 }
2024
2025 static void damon_sysfs_kdamonds_rm_dirs(struct damon_sysfs_kdamonds *kdamonds)
2026 {
2027         struct damon_sysfs_kdamond **kdamonds_arr = kdamonds->kdamonds_arr;
2028         int i;
2029
2030         for (i = 0; i < kdamonds->nr; i++) {
2031                 damon_sysfs_kdamond_rm_dirs(kdamonds_arr[i]);
2032                 kobject_put(&kdamonds_arr[i]->kobj);
2033         }
2034         kdamonds->nr = 0;
2035         kfree(kdamonds_arr);
2036         kdamonds->kdamonds_arr = NULL;
2037 }
2038
2039 static int damon_sysfs_nr_running_ctxs(struct damon_sysfs_kdamond **kdamonds,
2040                 int nr_kdamonds)
2041 {
2042         int nr_running_ctxs = 0;
2043         int i;
2044
2045         for (i = 0; i < nr_kdamonds; i++) {
2046                 struct damon_ctx *ctx = kdamonds[i]->damon_ctx;
2047
2048                 if (!ctx)
2049                         continue;
2050                 mutex_lock(&ctx->kdamond_lock);
2051                 if (ctx->kdamond)
2052                         nr_running_ctxs++;
2053                 mutex_unlock(&ctx->kdamond_lock);
2054         }
2055         return nr_running_ctxs;
2056 }
2057
2058 static int damon_sysfs_kdamonds_add_dirs(struct damon_sysfs_kdamonds *kdamonds,
2059                 int nr_kdamonds)
2060 {
2061         struct damon_sysfs_kdamond **kdamonds_arr, *kdamond;
2062         int err, i;
2063
2064         if (damon_sysfs_nr_running_ctxs(kdamonds->kdamonds_arr, kdamonds->nr))
2065                 return -EBUSY;
2066
2067         damon_sysfs_kdamonds_rm_dirs(kdamonds);
2068         if (!nr_kdamonds)
2069                 return 0;
2070
2071         kdamonds_arr = kmalloc_array(nr_kdamonds, sizeof(*kdamonds_arr),
2072                         GFP_KERNEL | __GFP_NOWARN);
2073         if (!kdamonds_arr)
2074                 return -ENOMEM;
2075         kdamonds->kdamonds_arr = kdamonds_arr;
2076
2077         for (i = 0; i < nr_kdamonds; i++) {
2078                 kdamond = damon_sysfs_kdamond_alloc();
2079                 if (!kdamond) {
2080                         damon_sysfs_kdamonds_rm_dirs(kdamonds);
2081                         return -ENOMEM;
2082                 }
2083
2084                 err = kobject_init_and_add(&kdamond->kobj,
2085                                 &damon_sysfs_kdamond_ktype, &kdamonds->kobj,
2086                                 "%d", i);
2087                 if (err)
2088                         goto out;
2089
2090                 err = damon_sysfs_kdamond_add_dirs(kdamond);
2091                 if (err)
2092                         goto out;
2093
2094                 kdamonds_arr[i] = kdamond;
2095                 kdamonds->nr++;
2096         }
2097         return 0;
2098
2099 out:
2100         damon_sysfs_kdamonds_rm_dirs(kdamonds);
2101         kobject_put(&kdamond->kobj);
2102         return err;
2103 }
2104
2105 static ssize_t nr_kdamonds_show(struct kobject *kobj,
2106                 struct kobj_attribute *attr, char *buf)
2107 {
2108         struct damon_sysfs_kdamonds *kdamonds = container_of(kobj,
2109                         struct damon_sysfs_kdamonds, kobj);
2110
2111         return sysfs_emit(buf, "%d\n", kdamonds->nr);
2112 }
2113
2114 static ssize_t nr_kdamonds_store(struct kobject *kobj,
2115                 struct kobj_attribute *attr, const char *buf, size_t count)
2116 {
2117         struct damon_sysfs_kdamonds *kdamonds = container_of(kobj,
2118                         struct damon_sysfs_kdamonds, kobj);
2119         int nr, err;
2120
2121         err = kstrtoint(buf, 0, &nr);
2122         if (err)
2123                 return err;
2124         if (nr < 0)
2125                 return -EINVAL;
2126
2127         if (!mutex_trylock(&damon_sysfs_lock))
2128                 return -EBUSY;
2129         err = damon_sysfs_kdamonds_add_dirs(kdamonds, nr);
2130         mutex_unlock(&damon_sysfs_lock);
2131         if (err)
2132                 return err;
2133
2134         return count;
2135 }
2136
2137 static void damon_sysfs_kdamonds_release(struct kobject *kobj)
2138 {
2139         kfree(container_of(kobj, struct damon_sysfs_kdamonds, kobj));
2140 }
2141
2142 static struct kobj_attribute damon_sysfs_kdamonds_nr_attr =
2143                 __ATTR_RW_MODE(nr_kdamonds, 0600);
2144
2145 static struct attribute *damon_sysfs_kdamonds_attrs[] = {
2146         &damon_sysfs_kdamonds_nr_attr.attr,
2147         NULL,
2148 };
2149 ATTRIBUTE_GROUPS(damon_sysfs_kdamonds);
2150
2151 static struct kobj_type damon_sysfs_kdamonds_ktype = {
2152         .release = damon_sysfs_kdamonds_release,
2153         .sysfs_ops = &kobj_sysfs_ops,
2154         .default_groups = damon_sysfs_kdamonds_groups,
2155 };
2156
2157 /*
2158  * damon user interface directory
2159  */
2160
2161 struct damon_sysfs_ui_dir {
2162         struct kobject kobj;
2163         struct damon_sysfs_kdamonds *kdamonds;
2164 };
2165
2166 static struct damon_sysfs_ui_dir *damon_sysfs_ui_dir_alloc(void)
2167 {
2168         return kzalloc(sizeof(struct damon_sysfs_ui_dir), GFP_KERNEL);
2169 }
2170
2171 static int damon_sysfs_ui_dir_add_dirs(struct damon_sysfs_ui_dir *ui_dir)
2172 {
2173         struct damon_sysfs_kdamonds *kdamonds;
2174         int err;
2175
2176         kdamonds = damon_sysfs_kdamonds_alloc();
2177         if (!kdamonds)
2178                 return -ENOMEM;
2179
2180         err = kobject_init_and_add(&kdamonds->kobj,
2181                         &damon_sysfs_kdamonds_ktype, &ui_dir->kobj,
2182                         "kdamonds");
2183         if (err) {
2184                 kobject_put(&kdamonds->kobj);
2185                 return err;
2186         }
2187         ui_dir->kdamonds = kdamonds;
2188         return err;
2189 }
2190
2191 static void damon_sysfs_ui_dir_release(struct kobject *kobj)
2192 {
2193         kfree(container_of(kobj, struct damon_sysfs_ui_dir, kobj));
2194 }
2195
2196 static struct attribute *damon_sysfs_ui_dir_attrs[] = {
2197         NULL,
2198 };
2199 ATTRIBUTE_GROUPS(damon_sysfs_ui_dir);
2200
2201 static struct kobj_type damon_sysfs_ui_dir_ktype = {
2202         .release = damon_sysfs_ui_dir_release,
2203         .sysfs_ops = &kobj_sysfs_ops,
2204         .default_groups = damon_sysfs_ui_dir_groups,
2205 };
2206
2207 static int __init damon_sysfs_init(void)
2208 {
2209         struct kobject *damon_sysfs_root;
2210         struct damon_sysfs_ui_dir *admin;
2211         int err;
2212
2213         damon_sysfs_root = kobject_create_and_add("damon", mm_kobj);
2214         if (!damon_sysfs_root)
2215                 return -ENOMEM;
2216
2217         admin = damon_sysfs_ui_dir_alloc();
2218         if (!admin) {
2219                 kobject_put(damon_sysfs_root);
2220                 return -ENOMEM;
2221         }
2222         err = kobject_init_and_add(&admin->kobj, &damon_sysfs_ui_dir_ktype,
2223                         damon_sysfs_root, "admin");
2224         if (err)
2225                 goto out;
2226         err = damon_sysfs_ui_dir_add_dirs(admin);
2227         if (err)
2228                 goto out;
2229         return 0;
2230
2231 out:
2232         kobject_put(&admin->kobj);
2233         kobject_put(damon_sysfs_root);
2234         return err;
2235 }
2236 subsys_initcall(damon_sysfs_init);