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