Merge tag 'mm-hotfixes-stable-2022-12-22-14-34' of git://git.kernel.org/pub/scm/linux...
[platform/kernel/linux-starfive.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;
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 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 struct damon_sysfs_scheme_regions {
117         struct kobject kobj;
118         struct list_head regions_list;
119         int nr_regions;
120 };
121
122 static struct damon_sysfs_scheme_regions *
123 damon_sysfs_scheme_regions_alloc(void)
124 {
125         struct damon_sysfs_scheme_regions *regions = kmalloc(sizeof(*regions),
126                         GFP_KERNEL);
127
128         regions->kobj = (struct kobject){};
129         INIT_LIST_HEAD(&regions->regions_list);
130         regions->nr_regions = 0;
131         return regions;
132 }
133
134 static void damon_sysfs_scheme_regions_rm_dirs(
135                 struct damon_sysfs_scheme_regions *regions)
136 {
137         struct damon_sysfs_scheme_region *r, *next;
138
139         list_for_each_entry_safe(r, next, &regions->regions_list, list) {
140                 /* release function deletes it from the list */
141                 kobject_put(&r->kobj);
142                 regions->nr_regions--;
143         }
144 }
145
146 static void damon_sysfs_scheme_regions_release(struct kobject *kobj)
147 {
148         kfree(container_of(kobj, struct damon_sysfs_scheme_regions, kobj));
149 }
150
151 static struct attribute *damon_sysfs_scheme_regions_attrs[] = {
152         NULL,
153 };
154 ATTRIBUTE_GROUPS(damon_sysfs_scheme_regions);
155
156 static struct kobj_type damon_sysfs_scheme_regions_ktype = {
157         .release = damon_sysfs_scheme_regions_release,
158         .sysfs_ops = &kobj_sysfs_ops,
159         .default_groups = damon_sysfs_scheme_regions_groups,
160 };
161
162 /*
163  * schemes/stats directory
164  */
165
166 struct damon_sysfs_stats {
167         struct kobject kobj;
168         unsigned long nr_tried;
169         unsigned long sz_tried;
170         unsigned long nr_applied;
171         unsigned long sz_applied;
172         unsigned long qt_exceeds;
173 };
174
175 static struct damon_sysfs_stats *damon_sysfs_stats_alloc(void)
176 {
177         return kzalloc(sizeof(struct damon_sysfs_stats), GFP_KERNEL);
178 }
179
180 static ssize_t nr_tried_show(struct kobject *kobj, struct kobj_attribute *attr,
181                 char *buf)
182 {
183         struct damon_sysfs_stats *stats = container_of(kobj,
184                         struct damon_sysfs_stats, kobj);
185
186         return sysfs_emit(buf, "%lu\n", stats->nr_tried);
187 }
188
189 static ssize_t sz_tried_show(struct kobject *kobj, struct kobj_attribute *attr,
190                 char *buf)
191 {
192         struct damon_sysfs_stats *stats = container_of(kobj,
193                         struct damon_sysfs_stats, kobj);
194
195         return sysfs_emit(buf, "%lu\n", stats->sz_tried);
196 }
197
198 static ssize_t nr_applied_show(struct kobject *kobj,
199                 struct kobj_attribute *attr, char *buf)
200 {
201         struct damon_sysfs_stats *stats = container_of(kobj,
202                         struct damon_sysfs_stats, kobj);
203
204         return sysfs_emit(buf, "%lu\n", stats->nr_applied);
205 }
206
207 static ssize_t sz_applied_show(struct kobject *kobj,
208                 struct kobj_attribute *attr, char *buf)
209 {
210         struct damon_sysfs_stats *stats = container_of(kobj,
211                         struct damon_sysfs_stats, kobj);
212
213         return sysfs_emit(buf, "%lu\n", stats->sz_applied);
214 }
215
216 static ssize_t qt_exceeds_show(struct kobject *kobj,
217                 struct kobj_attribute *attr, char *buf)
218 {
219         struct damon_sysfs_stats *stats = container_of(kobj,
220                         struct damon_sysfs_stats, kobj);
221
222         return sysfs_emit(buf, "%lu\n", stats->qt_exceeds);
223 }
224
225 static void damon_sysfs_stats_release(struct kobject *kobj)
226 {
227         kfree(container_of(kobj, struct damon_sysfs_stats, kobj));
228 }
229
230 static struct kobj_attribute damon_sysfs_stats_nr_tried_attr =
231                 __ATTR_RO_MODE(nr_tried, 0400);
232
233 static struct kobj_attribute damon_sysfs_stats_sz_tried_attr =
234                 __ATTR_RO_MODE(sz_tried, 0400);
235
236 static struct kobj_attribute damon_sysfs_stats_nr_applied_attr =
237                 __ATTR_RO_MODE(nr_applied, 0400);
238
239 static struct kobj_attribute damon_sysfs_stats_sz_applied_attr =
240                 __ATTR_RO_MODE(sz_applied, 0400);
241
242 static struct kobj_attribute damon_sysfs_stats_qt_exceeds_attr =
243                 __ATTR_RO_MODE(qt_exceeds, 0400);
244
245 static struct attribute *damon_sysfs_stats_attrs[] = {
246         &damon_sysfs_stats_nr_tried_attr.attr,
247         &damon_sysfs_stats_sz_tried_attr.attr,
248         &damon_sysfs_stats_nr_applied_attr.attr,
249         &damon_sysfs_stats_sz_applied_attr.attr,
250         &damon_sysfs_stats_qt_exceeds_attr.attr,
251         NULL,
252 };
253 ATTRIBUTE_GROUPS(damon_sysfs_stats);
254
255 static struct kobj_type damon_sysfs_stats_ktype = {
256         .release = damon_sysfs_stats_release,
257         .sysfs_ops = &kobj_sysfs_ops,
258         .default_groups = damon_sysfs_stats_groups,
259 };
260
261 /*
262  * watermarks directory
263  */
264
265 struct damon_sysfs_watermarks {
266         struct kobject kobj;
267         enum damos_wmark_metric metric;
268         unsigned long interval_us;
269         unsigned long high;
270         unsigned long mid;
271         unsigned long low;
272 };
273
274 static struct damon_sysfs_watermarks *damon_sysfs_watermarks_alloc(
275                 enum damos_wmark_metric metric, unsigned long interval_us,
276                 unsigned long high, unsigned long mid, unsigned long low)
277 {
278         struct damon_sysfs_watermarks *watermarks = kmalloc(
279                         sizeof(*watermarks), GFP_KERNEL);
280
281         if (!watermarks)
282                 return NULL;
283         watermarks->kobj = (struct kobject){};
284         watermarks->metric = metric;
285         watermarks->interval_us = interval_us;
286         watermarks->high = high;
287         watermarks->mid = mid;
288         watermarks->low = low;
289         return watermarks;
290 }
291
292 /* Should match with enum damos_wmark_metric */
293 static const char * const damon_sysfs_wmark_metric_strs[] = {
294         "none",
295         "free_mem_rate",
296 };
297
298 static ssize_t metric_show(struct kobject *kobj, struct kobj_attribute *attr,
299                 char *buf)
300 {
301         struct damon_sysfs_watermarks *watermarks = container_of(kobj,
302                         struct damon_sysfs_watermarks, kobj);
303
304         return sysfs_emit(buf, "%s\n",
305                         damon_sysfs_wmark_metric_strs[watermarks->metric]);
306 }
307
308 static ssize_t metric_store(struct kobject *kobj, struct kobj_attribute *attr,
309                 const char *buf, size_t count)
310 {
311         struct damon_sysfs_watermarks *watermarks = container_of(kobj,
312                         struct damon_sysfs_watermarks, kobj);
313         enum damos_wmark_metric metric;
314
315         for (metric = 0; metric < NR_DAMOS_WMARK_METRICS; metric++) {
316                 if (sysfs_streq(buf, damon_sysfs_wmark_metric_strs[metric])) {
317                         watermarks->metric = metric;
318                         return count;
319                 }
320         }
321         return -EINVAL;
322 }
323
324 static ssize_t interval_us_show(struct kobject *kobj,
325                 struct kobj_attribute *attr, char *buf)
326 {
327         struct damon_sysfs_watermarks *watermarks = container_of(kobj,
328                         struct damon_sysfs_watermarks, kobj);
329
330         return sysfs_emit(buf, "%lu\n", watermarks->interval_us);
331 }
332
333 static ssize_t interval_us_store(struct kobject *kobj,
334                 struct kobj_attribute *attr, const char *buf, size_t count)
335 {
336         struct damon_sysfs_watermarks *watermarks = container_of(kobj,
337                         struct damon_sysfs_watermarks, kobj);
338         int err = kstrtoul(buf, 0, &watermarks->interval_us);
339
340         return err ? err : count;
341 }
342
343 static ssize_t high_show(struct kobject *kobj,
344                 struct kobj_attribute *attr, char *buf)
345 {
346         struct damon_sysfs_watermarks *watermarks = container_of(kobj,
347                         struct damon_sysfs_watermarks, kobj);
348
349         return sysfs_emit(buf, "%lu\n", watermarks->high);
350 }
351
352 static ssize_t high_store(struct kobject *kobj,
353                 struct kobj_attribute *attr, const char *buf, size_t count)
354 {
355         struct damon_sysfs_watermarks *watermarks = container_of(kobj,
356                         struct damon_sysfs_watermarks, kobj);
357         int err = kstrtoul(buf, 0, &watermarks->high);
358
359         return err ? err : count;
360 }
361
362 static ssize_t mid_show(struct kobject *kobj,
363                 struct kobj_attribute *attr, char *buf)
364 {
365         struct damon_sysfs_watermarks *watermarks = container_of(kobj,
366                         struct damon_sysfs_watermarks, kobj);
367
368         return sysfs_emit(buf, "%lu\n", watermarks->mid);
369 }
370
371 static ssize_t mid_store(struct kobject *kobj,
372                 struct kobj_attribute *attr, const char *buf, size_t count)
373 {
374         struct damon_sysfs_watermarks *watermarks = container_of(kobj,
375                         struct damon_sysfs_watermarks, kobj);
376         int err = kstrtoul(buf, 0, &watermarks->mid);
377
378         return err ? err : count;
379 }
380
381 static ssize_t low_show(struct kobject *kobj,
382                 struct kobj_attribute *attr, char *buf)
383 {
384         struct damon_sysfs_watermarks *watermarks = container_of(kobj,
385                         struct damon_sysfs_watermarks, kobj);
386
387         return sysfs_emit(buf, "%lu\n", watermarks->low);
388 }
389
390 static ssize_t low_store(struct kobject *kobj,
391                 struct kobj_attribute *attr, const char *buf, size_t count)
392 {
393         struct damon_sysfs_watermarks *watermarks = container_of(kobj,
394                         struct damon_sysfs_watermarks, kobj);
395         int err = kstrtoul(buf, 0, &watermarks->low);
396
397         return err ? err : count;
398 }
399
400 static void damon_sysfs_watermarks_release(struct kobject *kobj)
401 {
402         kfree(container_of(kobj, struct damon_sysfs_watermarks, kobj));
403 }
404
405 static struct kobj_attribute damon_sysfs_watermarks_metric_attr =
406                 __ATTR_RW_MODE(metric, 0600);
407
408 static struct kobj_attribute damon_sysfs_watermarks_interval_us_attr =
409                 __ATTR_RW_MODE(interval_us, 0600);
410
411 static struct kobj_attribute damon_sysfs_watermarks_high_attr =
412                 __ATTR_RW_MODE(high, 0600);
413
414 static struct kobj_attribute damon_sysfs_watermarks_mid_attr =
415                 __ATTR_RW_MODE(mid, 0600);
416
417 static struct kobj_attribute damon_sysfs_watermarks_low_attr =
418                 __ATTR_RW_MODE(low, 0600);
419
420 static struct attribute *damon_sysfs_watermarks_attrs[] = {
421         &damon_sysfs_watermarks_metric_attr.attr,
422         &damon_sysfs_watermarks_interval_us_attr.attr,
423         &damon_sysfs_watermarks_high_attr.attr,
424         &damon_sysfs_watermarks_mid_attr.attr,
425         &damon_sysfs_watermarks_low_attr.attr,
426         NULL,
427 };
428 ATTRIBUTE_GROUPS(damon_sysfs_watermarks);
429
430 static struct kobj_type damon_sysfs_watermarks_ktype = {
431         .release = damon_sysfs_watermarks_release,
432         .sysfs_ops = &kobj_sysfs_ops,
433         .default_groups = damon_sysfs_watermarks_groups,
434 };
435
436 /*
437  * scheme/weights directory
438  */
439
440 struct damon_sysfs_weights {
441         struct kobject kobj;
442         unsigned int sz;
443         unsigned int nr_accesses;
444         unsigned int age;
445 };
446
447 static struct damon_sysfs_weights *damon_sysfs_weights_alloc(unsigned int sz,
448                 unsigned int nr_accesses, unsigned int age)
449 {
450         struct damon_sysfs_weights *weights = kmalloc(sizeof(*weights),
451                         GFP_KERNEL);
452
453         if (!weights)
454                 return NULL;
455         weights->kobj = (struct kobject){};
456         weights->sz = sz;
457         weights->nr_accesses = nr_accesses;
458         weights->age = age;
459         return weights;
460 }
461
462 static ssize_t sz_permil_show(struct kobject *kobj,
463                 struct kobj_attribute *attr, char *buf)
464 {
465         struct damon_sysfs_weights *weights = container_of(kobj,
466                         struct damon_sysfs_weights, kobj);
467
468         return sysfs_emit(buf, "%u\n", weights->sz);
469 }
470
471 static ssize_t sz_permil_store(struct kobject *kobj,
472                 struct kobj_attribute *attr, const char *buf, size_t count)
473 {
474         struct damon_sysfs_weights *weights = container_of(kobj,
475                         struct damon_sysfs_weights, kobj);
476         int err = kstrtouint(buf, 0, &weights->sz);
477
478         return err ? err : count;
479 }
480
481 static ssize_t nr_accesses_permil_show(struct kobject *kobj,
482                 struct kobj_attribute *attr, char *buf)
483 {
484         struct damon_sysfs_weights *weights = container_of(kobj,
485                         struct damon_sysfs_weights, kobj);
486
487         return sysfs_emit(buf, "%u\n", weights->nr_accesses);
488 }
489
490 static ssize_t nr_accesses_permil_store(struct kobject *kobj,
491                 struct kobj_attribute *attr, const char *buf, size_t count)
492 {
493         struct damon_sysfs_weights *weights = container_of(kobj,
494                         struct damon_sysfs_weights, kobj);
495         int err = kstrtouint(buf, 0, &weights->nr_accesses);
496
497         return err ? err : count;
498 }
499
500 static ssize_t age_permil_show(struct kobject *kobj,
501                 struct kobj_attribute *attr, char *buf)
502 {
503         struct damon_sysfs_weights *weights = container_of(kobj,
504                         struct damon_sysfs_weights, kobj);
505
506         return sysfs_emit(buf, "%u\n", weights->age);
507 }
508
509 static ssize_t age_permil_store(struct kobject *kobj,
510                 struct kobj_attribute *attr, const char *buf, size_t count)
511 {
512         struct damon_sysfs_weights *weights = container_of(kobj,
513                         struct damon_sysfs_weights, kobj);
514         int err = kstrtouint(buf, 0, &weights->age);
515
516         return err ? err : count;
517 }
518
519 static void damon_sysfs_weights_release(struct kobject *kobj)
520 {
521         kfree(container_of(kobj, struct damon_sysfs_weights, kobj));
522 }
523
524 static struct kobj_attribute damon_sysfs_weights_sz_attr =
525                 __ATTR_RW_MODE(sz_permil, 0600);
526
527 static struct kobj_attribute damon_sysfs_weights_nr_accesses_attr =
528                 __ATTR_RW_MODE(nr_accesses_permil, 0600);
529
530 static struct kobj_attribute damon_sysfs_weights_age_attr =
531                 __ATTR_RW_MODE(age_permil, 0600);
532
533 static struct attribute *damon_sysfs_weights_attrs[] = {
534         &damon_sysfs_weights_sz_attr.attr,
535         &damon_sysfs_weights_nr_accesses_attr.attr,
536         &damon_sysfs_weights_age_attr.attr,
537         NULL,
538 };
539 ATTRIBUTE_GROUPS(damon_sysfs_weights);
540
541 static struct kobj_type damon_sysfs_weights_ktype = {
542         .release = damon_sysfs_weights_release,
543         .sysfs_ops = &kobj_sysfs_ops,
544         .default_groups = damon_sysfs_weights_groups,
545 };
546
547 /*
548  * quotas directory
549  */
550
551 struct damon_sysfs_quotas {
552         struct kobject kobj;
553         struct damon_sysfs_weights *weights;
554         unsigned long ms;
555         unsigned long sz;
556         unsigned long reset_interval_ms;
557 };
558
559 static struct damon_sysfs_quotas *damon_sysfs_quotas_alloc(void)
560 {
561         return kzalloc(sizeof(struct damon_sysfs_quotas), GFP_KERNEL);
562 }
563
564 static int damon_sysfs_quotas_add_dirs(struct damon_sysfs_quotas *quotas)
565 {
566         struct damon_sysfs_weights *weights;
567         int err;
568
569         weights = damon_sysfs_weights_alloc(0, 0, 0);
570         if (!weights)
571                 return -ENOMEM;
572
573         err = kobject_init_and_add(&weights->kobj, &damon_sysfs_weights_ktype,
574                         &quotas->kobj, "weights");
575         if (err)
576                 kobject_put(&weights->kobj);
577         else
578                 quotas->weights = weights;
579         return err;
580 }
581
582 static void damon_sysfs_quotas_rm_dirs(struct damon_sysfs_quotas *quotas)
583 {
584         kobject_put(&quotas->weights->kobj);
585 }
586
587 static ssize_t ms_show(struct kobject *kobj, struct kobj_attribute *attr,
588                 char *buf)
589 {
590         struct damon_sysfs_quotas *quotas = container_of(kobj,
591                         struct damon_sysfs_quotas, kobj);
592
593         return sysfs_emit(buf, "%lu\n", quotas->ms);
594 }
595
596 static ssize_t ms_store(struct kobject *kobj, struct kobj_attribute *attr,
597                 const char *buf, size_t count)
598 {
599         struct damon_sysfs_quotas *quotas = container_of(kobj,
600                         struct damon_sysfs_quotas, kobj);
601         int err = kstrtoul(buf, 0, &quotas->ms);
602
603         if (err)
604                 return -EINVAL;
605         return count;
606 }
607
608 static ssize_t bytes_show(struct kobject *kobj, struct kobj_attribute *attr,
609                 char *buf)
610 {
611         struct damon_sysfs_quotas *quotas = container_of(kobj,
612                         struct damon_sysfs_quotas, kobj);
613
614         return sysfs_emit(buf, "%lu\n", quotas->sz);
615 }
616
617 static ssize_t bytes_store(struct kobject *kobj,
618                 struct kobj_attribute *attr, const char *buf, size_t count)
619 {
620         struct damon_sysfs_quotas *quotas = container_of(kobj,
621                         struct damon_sysfs_quotas, kobj);
622         int err = kstrtoul(buf, 0, &quotas->sz);
623
624         if (err)
625                 return -EINVAL;
626         return count;
627 }
628
629 static ssize_t reset_interval_ms_show(struct kobject *kobj,
630                 struct kobj_attribute *attr, char *buf)
631 {
632         struct damon_sysfs_quotas *quotas = container_of(kobj,
633                         struct damon_sysfs_quotas, kobj);
634
635         return sysfs_emit(buf, "%lu\n", quotas->reset_interval_ms);
636 }
637
638 static ssize_t reset_interval_ms_store(struct kobject *kobj,
639                 struct kobj_attribute *attr, const char *buf, size_t count)
640 {
641         struct damon_sysfs_quotas *quotas = container_of(kobj,
642                         struct damon_sysfs_quotas, kobj);
643         int err = kstrtoul(buf, 0, &quotas->reset_interval_ms);
644
645         if (err)
646                 return -EINVAL;
647         return count;
648 }
649
650 static void damon_sysfs_quotas_release(struct kobject *kobj)
651 {
652         kfree(container_of(kobj, struct damon_sysfs_quotas, kobj));
653 }
654
655 static struct kobj_attribute damon_sysfs_quotas_ms_attr =
656                 __ATTR_RW_MODE(ms, 0600);
657
658 static struct kobj_attribute damon_sysfs_quotas_sz_attr =
659                 __ATTR_RW_MODE(bytes, 0600);
660
661 static struct kobj_attribute damon_sysfs_quotas_reset_interval_ms_attr =
662                 __ATTR_RW_MODE(reset_interval_ms, 0600);
663
664 static struct attribute *damon_sysfs_quotas_attrs[] = {
665         &damon_sysfs_quotas_ms_attr.attr,
666         &damon_sysfs_quotas_sz_attr.attr,
667         &damon_sysfs_quotas_reset_interval_ms_attr.attr,
668         NULL,
669 };
670 ATTRIBUTE_GROUPS(damon_sysfs_quotas);
671
672 static struct kobj_type damon_sysfs_quotas_ktype = {
673         .release = damon_sysfs_quotas_release,
674         .sysfs_ops = &kobj_sysfs_ops,
675         .default_groups = damon_sysfs_quotas_groups,
676 };
677
678 /*
679  * access_pattern directory
680  */
681
682 struct damon_sysfs_access_pattern {
683         struct kobject kobj;
684         struct damon_sysfs_ul_range *sz;
685         struct damon_sysfs_ul_range *nr_accesses;
686         struct damon_sysfs_ul_range *age;
687 };
688
689 static
690 struct damon_sysfs_access_pattern *damon_sysfs_access_pattern_alloc(void)
691 {
692         struct damon_sysfs_access_pattern *access_pattern =
693                 kmalloc(sizeof(*access_pattern), GFP_KERNEL);
694
695         if (!access_pattern)
696                 return NULL;
697         access_pattern->kobj = (struct kobject){};
698         return access_pattern;
699 }
700
701 static int damon_sysfs_access_pattern_add_range_dir(
702                 struct damon_sysfs_access_pattern *access_pattern,
703                 struct damon_sysfs_ul_range **range_dir_ptr,
704                 char *name)
705 {
706         struct damon_sysfs_ul_range *range = damon_sysfs_ul_range_alloc(0, 0);
707         int err;
708
709         if (!range)
710                 return -ENOMEM;
711         err = kobject_init_and_add(&range->kobj, &damon_sysfs_ul_range_ktype,
712                         &access_pattern->kobj, name);
713         if (err)
714                 kobject_put(&range->kobj);
715         else
716                 *range_dir_ptr = range;
717         return err;
718 }
719
720 static int damon_sysfs_access_pattern_add_dirs(
721                 struct damon_sysfs_access_pattern *access_pattern)
722 {
723         int err;
724
725         err = damon_sysfs_access_pattern_add_range_dir(access_pattern,
726                         &access_pattern->sz, "sz");
727         if (err)
728                 goto put_sz_out;
729
730         err = damon_sysfs_access_pattern_add_range_dir(access_pattern,
731                         &access_pattern->nr_accesses, "nr_accesses");
732         if (err)
733                 goto put_nr_accesses_sz_out;
734
735         err = damon_sysfs_access_pattern_add_range_dir(access_pattern,
736                         &access_pattern->age, "age");
737         if (err)
738                 goto put_age_nr_accesses_sz_out;
739         return 0;
740
741 put_age_nr_accesses_sz_out:
742         kobject_put(&access_pattern->age->kobj);
743         access_pattern->age = NULL;
744 put_nr_accesses_sz_out:
745         kobject_put(&access_pattern->nr_accesses->kobj);
746         access_pattern->nr_accesses = NULL;
747 put_sz_out:
748         kobject_put(&access_pattern->sz->kobj);
749         access_pattern->sz = NULL;
750         return err;
751 }
752
753 static void damon_sysfs_access_pattern_rm_dirs(
754                 struct damon_sysfs_access_pattern *access_pattern)
755 {
756         kobject_put(&access_pattern->sz->kobj);
757         kobject_put(&access_pattern->nr_accesses->kobj);
758         kobject_put(&access_pattern->age->kobj);
759 }
760
761 static void damon_sysfs_access_pattern_release(struct kobject *kobj)
762 {
763         kfree(container_of(kobj, struct damon_sysfs_access_pattern, kobj));
764 }
765
766 static struct attribute *damon_sysfs_access_pattern_attrs[] = {
767         NULL,
768 };
769 ATTRIBUTE_GROUPS(damon_sysfs_access_pattern);
770
771 static struct kobj_type damon_sysfs_access_pattern_ktype = {
772         .release = damon_sysfs_access_pattern_release,
773         .sysfs_ops = &kobj_sysfs_ops,
774         .default_groups = damon_sysfs_access_pattern_groups,
775 };
776
777 /*
778  * scheme directory
779  */
780
781 struct damon_sysfs_scheme {
782         struct kobject kobj;
783         enum damos_action action;
784         struct damon_sysfs_access_pattern *access_pattern;
785         struct damon_sysfs_quotas *quotas;
786         struct damon_sysfs_watermarks *watermarks;
787         struct damon_sysfs_stats *stats;
788         struct damon_sysfs_scheme_regions *tried_regions;
789 };
790
791 /* This should match with enum damos_action */
792 static const char * const damon_sysfs_damos_action_strs[] = {
793         "willneed",
794         "cold",
795         "pageout",
796         "hugepage",
797         "nohugepage",
798         "lru_prio",
799         "lru_deprio",
800         "stat",
801 };
802
803 static struct damon_sysfs_scheme *damon_sysfs_scheme_alloc(
804                 enum damos_action action)
805 {
806         struct damon_sysfs_scheme *scheme = kmalloc(sizeof(*scheme),
807                                 GFP_KERNEL);
808
809         if (!scheme)
810                 return NULL;
811         scheme->kobj = (struct kobject){};
812         scheme->action = action;
813         return scheme;
814 }
815
816 static int damon_sysfs_scheme_set_access_pattern(
817                 struct damon_sysfs_scheme *scheme)
818 {
819         struct damon_sysfs_access_pattern *access_pattern;
820         int err;
821
822         access_pattern = damon_sysfs_access_pattern_alloc();
823         if (!access_pattern)
824                 return -ENOMEM;
825         err = kobject_init_and_add(&access_pattern->kobj,
826                         &damon_sysfs_access_pattern_ktype, &scheme->kobj,
827                         "access_pattern");
828         if (err)
829                 goto out;
830         err = damon_sysfs_access_pattern_add_dirs(access_pattern);
831         if (err)
832                 goto out;
833         scheme->access_pattern = access_pattern;
834         return 0;
835
836 out:
837         kobject_put(&access_pattern->kobj);
838         return err;
839 }
840
841 static int damon_sysfs_scheme_set_quotas(struct damon_sysfs_scheme *scheme)
842 {
843         struct damon_sysfs_quotas *quotas = damon_sysfs_quotas_alloc();
844         int err;
845
846         if (!quotas)
847                 return -ENOMEM;
848         err = kobject_init_and_add(&quotas->kobj, &damon_sysfs_quotas_ktype,
849                         &scheme->kobj, "quotas");
850         if (err)
851                 goto out;
852         err = damon_sysfs_quotas_add_dirs(quotas);
853         if (err)
854                 goto out;
855         scheme->quotas = quotas;
856         return 0;
857
858 out:
859         kobject_put(&quotas->kobj);
860         return err;
861 }
862
863 static int damon_sysfs_scheme_set_watermarks(struct damon_sysfs_scheme *scheme)
864 {
865         struct damon_sysfs_watermarks *watermarks =
866                 damon_sysfs_watermarks_alloc(DAMOS_WMARK_NONE, 0, 0, 0, 0);
867         int err;
868
869         if (!watermarks)
870                 return -ENOMEM;
871         err = kobject_init_and_add(&watermarks->kobj,
872                         &damon_sysfs_watermarks_ktype, &scheme->kobj,
873                         "watermarks");
874         if (err)
875                 kobject_put(&watermarks->kobj);
876         else
877                 scheme->watermarks = watermarks;
878         return err;
879 }
880
881 static int damon_sysfs_scheme_set_stats(struct damon_sysfs_scheme *scheme)
882 {
883         struct damon_sysfs_stats *stats = damon_sysfs_stats_alloc();
884         int err;
885
886         if (!stats)
887                 return -ENOMEM;
888         err = kobject_init_and_add(&stats->kobj, &damon_sysfs_stats_ktype,
889                         &scheme->kobj, "stats");
890         if (err)
891                 kobject_put(&stats->kobj);
892         else
893                 scheme->stats = stats;
894         return err;
895 }
896
897 static int damon_sysfs_scheme_set_tried_regions(
898                 struct damon_sysfs_scheme *scheme)
899 {
900         struct damon_sysfs_scheme_regions *tried_regions =
901                 damon_sysfs_scheme_regions_alloc();
902         int err;
903
904         if (!tried_regions)
905                 return -ENOMEM;
906         err = kobject_init_and_add(&tried_regions->kobj,
907                         &damon_sysfs_scheme_regions_ktype, &scheme->kobj,
908                         "tried_regions");
909         if (err)
910                 kobject_put(&tried_regions->kobj);
911         else
912                 scheme->tried_regions = tried_regions;
913         return err;
914 }
915
916 static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme)
917 {
918         int err;
919
920         err = damon_sysfs_scheme_set_access_pattern(scheme);
921         if (err)
922                 return err;
923         err = damon_sysfs_scheme_set_quotas(scheme);
924         if (err)
925                 goto put_access_pattern_out;
926         err = damon_sysfs_scheme_set_watermarks(scheme);
927         if (err)
928                 goto put_quotas_access_pattern_out;
929         err = damon_sysfs_scheme_set_stats(scheme);
930         if (err)
931                 goto put_watermarks_quotas_access_pattern_out;
932         err = damon_sysfs_scheme_set_tried_regions(scheme);
933         if (err)
934                 goto put_tried_regions_out;
935         return 0;
936
937 put_tried_regions_out:
938         kobject_put(&scheme->tried_regions->kobj);
939         scheme->tried_regions = NULL;
940 put_watermarks_quotas_access_pattern_out:
941         kobject_put(&scheme->watermarks->kobj);
942         scheme->watermarks = NULL;
943 put_quotas_access_pattern_out:
944         kobject_put(&scheme->quotas->kobj);
945         scheme->quotas = NULL;
946 put_access_pattern_out:
947         kobject_put(&scheme->access_pattern->kobj);
948         scheme->access_pattern = NULL;
949         return err;
950 }
951
952 static void damon_sysfs_scheme_rm_dirs(struct damon_sysfs_scheme *scheme)
953 {
954         damon_sysfs_access_pattern_rm_dirs(scheme->access_pattern);
955         kobject_put(&scheme->access_pattern->kobj);
956         damon_sysfs_quotas_rm_dirs(scheme->quotas);
957         kobject_put(&scheme->quotas->kobj);
958         kobject_put(&scheme->watermarks->kobj);
959         kobject_put(&scheme->stats->kobj);
960         damon_sysfs_scheme_regions_rm_dirs(scheme->tried_regions);
961         kobject_put(&scheme->tried_regions->kobj);
962 }
963
964 static ssize_t action_show(struct kobject *kobj, struct kobj_attribute *attr,
965                 char *buf)
966 {
967         struct damon_sysfs_scheme *scheme = container_of(kobj,
968                         struct damon_sysfs_scheme, kobj);
969
970         return sysfs_emit(buf, "%s\n",
971                         damon_sysfs_damos_action_strs[scheme->action]);
972 }
973
974 static ssize_t action_store(struct kobject *kobj, struct kobj_attribute *attr,
975                 const char *buf, size_t count)
976 {
977         struct damon_sysfs_scheme *scheme = container_of(kobj,
978                         struct damon_sysfs_scheme, kobj);
979         enum damos_action action;
980
981         for (action = 0; action < NR_DAMOS_ACTIONS; action++) {
982                 if (sysfs_streq(buf, damon_sysfs_damos_action_strs[action])) {
983                         scheme->action = action;
984                         return count;
985                 }
986         }
987         return -EINVAL;
988 }
989
990 static void damon_sysfs_scheme_release(struct kobject *kobj)
991 {
992         kfree(container_of(kobj, struct damon_sysfs_scheme, kobj));
993 }
994
995 static struct kobj_attribute damon_sysfs_scheme_action_attr =
996                 __ATTR_RW_MODE(action, 0600);
997
998 static struct attribute *damon_sysfs_scheme_attrs[] = {
999         &damon_sysfs_scheme_action_attr.attr,
1000         NULL,
1001 };
1002 ATTRIBUTE_GROUPS(damon_sysfs_scheme);
1003
1004 static struct kobj_type damon_sysfs_scheme_ktype = {
1005         .release = damon_sysfs_scheme_release,
1006         .sysfs_ops = &kobj_sysfs_ops,
1007         .default_groups = damon_sysfs_scheme_groups,
1008 };
1009
1010 /*
1011  * schemes directory
1012  */
1013
1014 struct damon_sysfs_schemes *damon_sysfs_schemes_alloc(void)
1015 {
1016         return kzalloc(sizeof(struct damon_sysfs_schemes), GFP_KERNEL);
1017 }
1018
1019 void damon_sysfs_schemes_rm_dirs(struct damon_sysfs_schemes *schemes)
1020 {
1021         struct damon_sysfs_scheme **schemes_arr = schemes->schemes_arr;
1022         int i;
1023
1024         for (i = 0; i < schemes->nr; i++) {
1025                 damon_sysfs_scheme_rm_dirs(schemes_arr[i]);
1026                 kobject_put(&schemes_arr[i]->kobj);
1027         }
1028         schemes->nr = 0;
1029         kfree(schemes_arr);
1030         schemes->schemes_arr = NULL;
1031 }
1032
1033 static int damon_sysfs_schemes_add_dirs(struct damon_sysfs_schemes *schemes,
1034                 int nr_schemes)
1035 {
1036         struct damon_sysfs_scheme **schemes_arr, *scheme;
1037         int err, i;
1038
1039         damon_sysfs_schemes_rm_dirs(schemes);
1040         if (!nr_schemes)
1041                 return 0;
1042
1043         schemes_arr = kmalloc_array(nr_schemes, sizeof(*schemes_arr),
1044                         GFP_KERNEL | __GFP_NOWARN);
1045         if (!schemes_arr)
1046                 return -ENOMEM;
1047         schemes->schemes_arr = schemes_arr;
1048
1049         for (i = 0; i < nr_schemes; i++) {
1050                 scheme = damon_sysfs_scheme_alloc(DAMOS_STAT);
1051                 if (!scheme) {
1052                         damon_sysfs_schemes_rm_dirs(schemes);
1053                         return -ENOMEM;
1054                 }
1055
1056                 err = kobject_init_and_add(&scheme->kobj,
1057                                 &damon_sysfs_scheme_ktype, &schemes->kobj,
1058                                 "%d", i);
1059                 if (err)
1060                         goto out;
1061                 err = damon_sysfs_scheme_add_dirs(scheme);
1062                 if (err)
1063                         goto out;
1064
1065                 schemes_arr[i] = scheme;
1066                 schemes->nr++;
1067         }
1068         return 0;
1069
1070 out:
1071         damon_sysfs_schemes_rm_dirs(schemes);
1072         kobject_put(&scheme->kobj);
1073         return err;
1074 }
1075
1076 static ssize_t nr_schemes_show(struct kobject *kobj,
1077                 struct kobj_attribute *attr, char *buf)
1078 {
1079         struct damon_sysfs_schemes *schemes = container_of(kobj,
1080                         struct damon_sysfs_schemes, kobj);
1081
1082         return sysfs_emit(buf, "%d\n", schemes->nr);
1083 }
1084
1085 static ssize_t nr_schemes_store(struct kobject *kobj,
1086                 struct kobj_attribute *attr, const char *buf, size_t count)
1087 {
1088         struct damon_sysfs_schemes *schemes;
1089         int nr, err = kstrtoint(buf, 0, &nr);
1090
1091         if (err)
1092                 return err;
1093         if (nr < 0)
1094                 return -EINVAL;
1095
1096         schemes = container_of(kobj, struct damon_sysfs_schemes, kobj);
1097
1098         if (!mutex_trylock(&damon_sysfs_lock))
1099                 return -EBUSY;
1100         err = damon_sysfs_schemes_add_dirs(schemes, nr);
1101         mutex_unlock(&damon_sysfs_lock);
1102         if (err)
1103                 return err;
1104         return count;
1105 }
1106
1107 static void damon_sysfs_schemes_release(struct kobject *kobj)
1108 {
1109         kfree(container_of(kobj, struct damon_sysfs_schemes, kobj));
1110 }
1111
1112 static struct kobj_attribute damon_sysfs_schemes_nr_attr =
1113                 __ATTR_RW_MODE(nr_schemes, 0600);
1114
1115 static struct attribute *damon_sysfs_schemes_attrs[] = {
1116         &damon_sysfs_schemes_nr_attr.attr,
1117         NULL,
1118 };
1119 ATTRIBUTE_GROUPS(damon_sysfs_schemes);
1120
1121 struct kobj_type damon_sysfs_schemes_ktype = {
1122         .release = damon_sysfs_schemes_release,
1123         .sysfs_ops = &kobj_sysfs_ops,
1124         .default_groups = damon_sysfs_schemes_groups,
1125 };
1126
1127 static struct damos *damon_sysfs_mk_scheme(
1128                 struct damon_sysfs_scheme *sysfs_scheme)
1129 {
1130         struct damon_sysfs_access_pattern *access_pattern =
1131                 sysfs_scheme->access_pattern;
1132         struct damon_sysfs_quotas *sysfs_quotas = sysfs_scheme->quotas;
1133         struct damon_sysfs_weights *sysfs_weights = sysfs_quotas->weights;
1134         struct damon_sysfs_watermarks *sysfs_wmarks = sysfs_scheme->watermarks;
1135
1136         struct damos_access_pattern pattern = {
1137                 .min_sz_region = access_pattern->sz->min,
1138                 .max_sz_region = access_pattern->sz->max,
1139                 .min_nr_accesses = access_pattern->nr_accesses->min,
1140                 .max_nr_accesses = access_pattern->nr_accesses->max,
1141                 .min_age_region = access_pattern->age->min,
1142                 .max_age_region = access_pattern->age->max,
1143         };
1144         struct damos_quota quota = {
1145                 .ms = sysfs_quotas->ms,
1146                 .sz = sysfs_quotas->sz,
1147                 .reset_interval = sysfs_quotas->reset_interval_ms,
1148                 .weight_sz = sysfs_weights->sz,
1149                 .weight_nr_accesses = sysfs_weights->nr_accesses,
1150                 .weight_age = sysfs_weights->age,
1151         };
1152         struct damos_watermarks wmarks = {
1153                 .metric = sysfs_wmarks->metric,
1154                 .interval = sysfs_wmarks->interval_us,
1155                 .high = sysfs_wmarks->high,
1156                 .mid = sysfs_wmarks->mid,
1157                 .low = sysfs_wmarks->low,
1158         };
1159
1160         return damon_new_scheme(&pattern, sysfs_scheme->action, &quota,
1161                         &wmarks);
1162 }
1163
1164 static void damon_sysfs_update_scheme(struct damos *scheme,
1165                 struct damon_sysfs_scheme *sysfs_scheme)
1166 {
1167         struct damon_sysfs_access_pattern *access_pattern =
1168                 sysfs_scheme->access_pattern;
1169         struct damon_sysfs_quotas *sysfs_quotas = sysfs_scheme->quotas;
1170         struct damon_sysfs_weights *sysfs_weights = sysfs_quotas->weights;
1171         struct damon_sysfs_watermarks *sysfs_wmarks = sysfs_scheme->watermarks;
1172
1173         scheme->pattern.min_sz_region = access_pattern->sz->min;
1174         scheme->pattern.max_sz_region = access_pattern->sz->max;
1175         scheme->pattern.min_nr_accesses = access_pattern->nr_accesses->min;
1176         scheme->pattern.max_nr_accesses = access_pattern->nr_accesses->max;
1177         scheme->pattern.min_age_region = access_pattern->age->min;
1178         scheme->pattern.max_age_region = access_pattern->age->max;
1179
1180         scheme->action = sysfs_scheme->action;
1181
1182         scheme->quota.ms = sysfs_quotas->ms;
1183         scheme->quota.sz = sysfs_quotas->sz;
1184         scheme->quota.reset_interval = sysfs_quotas->reset_interval_ms;
1185         scheme->quota.weight_sz = sysfs_weights->sz;
1186         scheme->quota.weight_nr_accesses = sysfs_weights->nr_accesses;
1187         scheme->quota.weight_age = sysfs_weights->age;
1188
1189         scheme->wmarks.metric = sysfs_wmarks->metric;
1190         scheme->wmarks.interval = sysfs_wmarks->interval_us;
1191         scheme->wmarks.high = sysfs_wmarks->high;
1192         scheme->wmarks.mid = sysfs_wmarks->mid;
1193         scheme->wmarks.low = sysfs_wmarks->low;
1194 }
1195
1196 int damon_sysfs_set_schemes(struct damon_ctx *ctx,
1197                 struct damon_sysfs_schemes *sysfs_schemes)
1198 {
1199         struct damos *scheme, *next;
1200         int i = 0;
1201
1202         damon_for_each_scheme_safe(scheme, next, ctx) {
1203                 if (i < sysfs_schemes->nr)
1204                         damon_sysfs_update_scheme(scheme,
1205                                         sysfs_schemes->schemes_arr[i]);
1206                 else
1207                         damon_destroy_scheme(scheme);
1208                 i++;
1209         }
1210
1211         for (; i < sysfs_schemes->nr; i++) {
1212                 struct damos *scheme, *next;
1213
1214                 scheme = damon_sysfs_mk_scheme(sysfs_schemes->schemes_arr[i]);
1215                 if (!scheme) {
1216                         damon_for_each_scheme_safe(scheme, next, ctx)
1217                                 damon_destroy_scheme(scheme);
1218                         return -ENOMEM;
1219                 }
1220                 damon_add_scheme(ctx, scheme);
1221         }
1222         return 0;
1223 }
1224
1225 void damon_sysfs_schemes_update_stats(
1226                 struct damon_sysfs_schemes *sysfs_schemes,
1227                 struct damon_ctx *ctx)
1228 {
1229         struct damos *scheme;
1230         int schemes_idx = 0;
1231
1232         damon_for_each_scheme(scheme, ctx) {
1233                 struct damon_sysfs_stats *sysfs_stats;
1234
1235                 /* user could have removed the scheme sysfs dir */
1236                 if (schemes_idx >= sysfs_schemes->nr)
1237                         break;
1238
1239                 sysfs_stats = sysfs_schemes->schemes_arr[schemes_idx++]->stats;
1240                 sysfs_stats->nr_tried = scheme->stat.nr_tried;
1241                 sysfs_stats->sz_tried = scheme->stat.sz_tried;
1242                 sysfs_stats->nr_applied = scheme->stat.nr_applied;
1243                 sysfs_stats->sz_applied = scheme->stat.sz_applied;
1244                 sysfs_stats->qt_exceeds = scheme->stat.qt_exceeds;
1245         }
1246 }
1247
1248 /*
1249  * damon_sysfs_schemes that need to update its schemes regions dir.  Protected
1250  * by damon_sysfs_lock
1251  */
1252 static struct damon_sysfs_schemes *damon_sysfs_schemes_for_damos_callback;
1253 static int damon_sysfs_schemes_region_idx;
1254
1255 /*
1256  * DAMON callback that called before damos apply.  While this callback is
1257  * registered, damon_sysfs_lock should be held to ensure the regions
1258  * directories exist.
1259  */
1260 static int damon_sysfs_before_damos_apply(struct damon_ctx *ctx,
1261                 struct damon_target *t, struct damon_region *r,
1262                 struct damos *s)
1263 {
1264         struct damos *scheme;
1265         struct damon_sysfs_scheme_regions *sysfs_regions;
1266         struct damon_sysfs_scheme_region *region;
1267         struct damon_sysfs_schemes *sysfs_schemes =
1268                 damon_sysfs_schemes_for_damos_callback;
1269         int schemes_idx = 0;
1270
1271         damon_for_each_scheme(scheme, ctx) {
1272                 if (scheme == s)
1273                         break;
1274                 schemes_idx++;
1275         }
1276
1277         /* user could have removed the scheme sysfs dir */
1278         if (schemes_idx >= sysfs_schemes->nr)
1279                 return 0;
1280
1281         sysfs_regions = sysfs_schemes->schemes_arr[schemes_idx]->tried_regions;
1282         region = damon_sysfs_scheme_region_alloc(r);
1283         list_add_tail(&region->list, &sysfs_regions->regions_list);
1284         sysfs_regions->nr_regions++;
1285         if (kobject_init_and_add(&region->kobj,
1286                                 &damon_sysfs_scheme_region_ktype,
1287                                 &sysfs_regions->kobj, "%d",
1288                                 damon_sysfs_schemes_region_idx++)) {
1289                 kobject_put(&region->kobj);
1290         }
1291         return 0;
1292 }
1293
1294 /* Called from damon_sysfs_cmd_request_callback under damon_sysfs_lock */
1295 int damon_sysfs_schemes_clear_regions(
1296                 struct damon_sysfs_schemes *sysfs_schemes,
1297                 struct damon_ctx *ctx)
1298 {
1299         struct damos *scheme;
1300         int schemes_idx = 0;
1301
1302         damon_for_each_scheme(scheme, ctx) {
1303                 struct damon_sysfs_scheme *sysfs_scheme;
1304
1305                 /* user could have removed the scheme sysfs dir */
1306                 if (schemes_idx >= sysfs_schemes->nr)
1307                         break;
1308
1309                 sysfs_scheme = sysfs_schemes->schemes_arr[schemes_idx++];
1310                 damon_sysfs_scheme_regions_rm_dirs(
1311                                 sysfs_scheme->tried_regions);
1312         }
1313         return 0;
1314 }
1315
1316 /* Called from damon_sysfs_cmd_request_callback under damon_sysfs_lock */
1317 int damon_sysfs_schemes_update_regions_start(
1318                 struct damon_sysfs_schemes *sysfs_schemes,
1319                 struct damon_ctx *ctx)
1320 {
1321         damon_sysfs_schemes_clear_regions(sysfs_schemes, ctx);
1322         damon_sysfs_schemes_for_damos_callback = sysfs_schemes;
1323         ctx->callback.before_damos_apply = damon_sysfs_before_damos_apply;
1324         return 0;
1325 }
1326
1327 /*
1328  * Called from damon_sysfs_cmd_request_callback under damon_sysfs_lock.  Caller
1329  * should unlock damon_sysfs_lock which held before
1330  * damon_sysfs_schemes_update_regions_start()
1331  */
1332 int damon_sysfs_schemes_update_regions_stop(struct damon_ctx *ctx)
1333 {
1334         damon_sysfs_schemes_for_damos_callback = NULL;
1335         ctx->callback.before_damos_apply = NULL;
1336         damon_sysfs_schemes_region_idx = 0;
1337         return 0;
1338 }