1 // SPDX-License-Identifier: GPL-2.0
3 * DAMON sysfs Interface
5 * Copyright (c) 2022 SeongJae Park <sj@kernel.org>
8 #include <linux/slab.h>
9 #include <linux/numa.h>
11 #include "sysfs-common.h"
14 * scheme region directory
17 struct damon_sysfs_scheme_region
{
19 struct damon_addr_range ar
;
20 unsigned int nr_accesses
;
22 unsigned long sz_filter_passed
;
23 struct list_head list
;
26 static struct damon_sysfs_scheme_region
*damon_sysfs_scheme_region_alloc(
27 struct damon_region
*region
)
29 struct damon_sysfs_scheme_region
*sysfs_region
= kmalloc(
30 sizeof(*sysfs_region
), GFP_KERNEL
);
34 sysfs_region
->kobj
= (struct kobject
){};
35 sysfs_region
->ar
= region
->ar
;
36 sysfs_region
->nr_accesses
= region
->nr_accesses_bp
/ 10000;
37 sysfs_region
->age
= region
->age
;
38 INIT_LIST_HEAD(&sysfs_region
->list
);
42 static ssize_t
start_show(struct kobject
*kobj
, struct kobj_attribute
*attr
,
45 struct damon_sysfs_scheme_region
*region
= container_of(kobj
,
46 struct damon_sysfs_scheme_region
, kobj
);
48 return sysfs_emit(buf
, "%lu\n", region
->ar
.start
);
51 static ssize_t
end_show(struct kobject
*kobj
, struct kobj_attribute
*attr
,
54 struct damon_sysfs_scheme_region
*region
= container_of(kobj
,
55 struct damon_sysfs_scheme_region
, kobj
);
57 return sysfs_emit(buf
, "%lu\n", region
->ar
.end
);
60 static ssize_t
nr_accesses_show(struct kobject
*kobj
,
61 struct kobj_attribute
*attr
, char *buf
)
63 struct damon_sysfs_scheme_region
*region
= container_of(kobj
,
64 struct damon_sysfs_scheme_region
, kobj
);
66 return sysfs_emit(buf
, "%u\n", region
->nr_accesses
);
69 static ssize_t
age_show(struct kobject
*kobj
, struct kobj_attribute
*attr
,
72 struct damon_sysfs_scheme_region
*region
= container_of(kobj
,
73 struct damon_sysfs_scheme_region
, kobj
);
75 return sysfs_emit(buf
, "%u\n", region
->age
);
78 static ssize_t
sz_filter_passed_show(struct kobject
*kobj
,
79 struct kobj_attribute
*attr
, char *buf
)
81 struct damon_sysfs_scheme_region
*region
= container_of(kobj
,
82 struct damon_sysfs_scheme_region
, kobj
);
84 return sysfs_emit(buf
, "%lu\n", region
->sz_filter_passed
);
87 static void damon_sysfs_scheme_region_release(struct kobject
*kobj
)
89 struct damon_sysfs_scheme_region
*region
= container_of(kobj
,
90 struct damon_sysfs_scheme_region
, kobj
);
92 list_del(®ion
->list
);
96 static struct kobj_attribute damon_sysfs_scheme_region_start_attr
=
97 __ATTR_RO_MODE(start
, 0400);
99 static struct kobj_attribute damon_sysfs_scheme_region_end_attr
=
100 __ATTR_RO_MODE(end
, 0400);
102 static struct kobj_attribute damon_sysfs_scheme_region_nr_accesses_attr
=
103 __ATTR_RO_MODE(nr_accesses
, 0400);
105 static struct kobj_attribute damon_sysfs_scheme_region_age_attr
=
106 __ATTR_RO_MODE(age
, 0400);
108 static struct kobj_attribute damon_sysfs_scheme_region_sz_filter_passed_attr
=
109 __ATTR_RO_MODE(sz_filter_passed
, 0400);
111 static struct attribute
*damon_sysfs_scheme_region_attrs
[] = {
112 &damon_sysfs_scheme_region_start_attr
.attr
,
113 &damon_sysfs_scheme_region_end_attr
.attr
,
114 &damon_sysfs_scheme_region_nr_accesses_attr
.attr
,
115 &damon_sysfs_scheme_region_age_attr
.attr
,
116 &damon_sysfs_scheme_region_sz_filter_passed_attr
.attr
,
119 ATTRIBUTE_GROUPS(damon_sysfs_scheme_region
);
121 static const struct kobj_type damon_sysfs_scheme_region_ktype
= {
122 .release
= damon_sysfs_scheme_region_release
,
123 .sysfs_ops
= &kobj_sysfs_ops
,
124 .default_groups
= damon_sysfs_scheme_region_groups
,
128 * scheme regions directory
131 struct damon_sysfs_scheme_regions
{
133 struct list_head regions_list
;
135 unsigned long total_bytes
;
138 static struct damon_sysfs_scheme_regions
*
139 damon_sysfs_scheme_regions_alloc(void)
141 struct damon_sysfs_scheme_regions
*regions
= kmalloc(sizeof(*regions
),
147 regions
->kobj
= (struct kobject
){};
148 INIT_LIST_HEAD(®ions
->regions_list
);
149 regions
->nr_regions
= 0;
150 regions
->total_bytes
= 0;
154 static ssize_t
total_bytes_show(struct kobject
*kobj
,
155 struct kobj_attribute
*attr
, char *buf
)
157 struct damon_sysfs_scheme_regions
*regions
= container_of(kobj
,
158 struct damon_sysfs_scheme_regions
, kobj
);
160 return sysfs_emit(buf
, "%lu\n", regions
->total_bytes
);
163 static void damon_sysfs_scheme_regions_rm_dirs(
164 struct damon_sysfs_scheme_regions
*regions
)
166 struct damon_sysfs_scheme_region
*r
, *next
;
168 list_for_each_entry_safe(r
, next
, ®ions
->regions_list
, list
) {
169 /* release function deletes it from the list */
170 kobject_put(&r
->kobj
);
171 regions
->nr_regions
--;
175 static void damon_sysfs_scheme_regions_release(struct kobject
*kobj
)
177 kfree(container_of(kobj
, struct damon_sysfs_scheme_regions
, kobj
));
180 static struct kobj_attribute damon_sysfs_scheme_regions_total_bytes_attr
=
181 __ATTR_RO_MODE(total_bytes
, 0400);
183 static struct attribute
*damon_sysfs_scheme_regions_attrs
[] = {
184 &damon_sysfs_scheme_regions_total_bytes_attr
.attr
,
187 ATTRIBUTE_GROUPS(damon_sysfs_scheme_regions
);
189 static const struct kobj_type damon_sysfs_scheme_regions_ktype
= {
190 .release
= damon_sysfs_scheme_regions_release
,
191 .sysfs_ops
= &kobj_sysfs_ops
,
192 .default_groups
= damon_sysfs_scheme_regions_groups
,
196 * schemes/stats directory
199 struct damon_sysfs_stats
{
201 unsigned long nr_tried
;
202 unsigned long sz_tried
;
203 unsigned long nr_applied
;
204 unsigned long sz_applied
;
205 unsigned long sz_ops_filter_passed
;
206 unsigned long qt_exceeds
;
209 static struct damon_sysfs_stats
*damon_sysfs_stats_alloc(void)
211 return kzalloc(sizeof(struct damon_sysfs_stats
), GFP_KERNEL
);
214 static ssize_t
nr_tried_show(struct kobject
*kobj
, struct kobj_attribute
*attr
,
217 struct damon_sysfs_stats
*stats
= container_of(kobj
,
218 struct damon_sysfs_stats
, kobj
);
220 return sysfs_emit(buf
, "%lu\n", stats
->nr_tried
);
223 static ssize_t
sz_tried_show(struct kobject
*kobj
, struct kobj_attribute
*attr
,
226 struct damon_sysfs_stats
*stats
= container_of(kobj
,
227 struct damon_sysfs_stats
, kobj
);
229 return sysfs_emit(buf
, "%lu\n", stats
->sz_tried
);
232 static ssize_t
nr_applied_show(struct kobject
*kobj
,
233 struct kobj_attribute
*attr
, char *buf
)
235 struct damon_sysfs_stats
*stats
= container_of(kobj
,
236 struct damon_sysfs_stats
, kobj
);
238 return sysfs_emit(buf
, "%lu\n", stats
->nr_applied
);
241 static ssize_t
sz_applied_show(struct kobject
*kobj
,
242 struct kobj_attribute
*attr
, char *buf
)
244 struct damon_sysfs_stats
*stats
= container_of(kobj
,
245 struct damon_sysfs_stats
, kobj
);
247 return sysfs_emit(buf
, "%lu\n", stats
->sz_applied
);
250 static ssize_t
sz_ops_filter_passed_show(struct kobject
*kobj
,
251 struct kobj_attribute
*attr
, char *buf
)
253 struct damon_sysfs_stats
*stats
= container_of(kobj
,
254 struct damon_sysfs_stats
, kobj
);
256 return sysfs_emit(buf
, "%lu\n", stats
->sz_ops_filter_passed
);
259 static ssize_t
qt_exceeds_show(struct kobject
*kobj
,
260 struct kobj_attribute
*attr
, char *buf
)
262 struct damon_sysfs_stats
*stats
= container_of(kobj
,
263 struct damon_sysfs_stats
, kobj
);
265 return sysfs_emit(buf
, "%lu\n", stats
->qt_exceeds
);
268 static void damon_sysfs_stats_release(struct kobject
*kobj
)
270 kfree(container_of(kobj
, struct damon_sysfs_stats
, kobj
));
273 static struct kobj_attribute damon_sysfs_stats_nr_tried_attr
=
274 __ATTR_RO_MODE(nr_tried
, 0400);
276 static struct kobj_attribute damon_sysfs_stats_sz_tried_attr
=
277 __ATTR_RO_MODE(sz_tried
, 0400);
279 static struct kobj_attribute damon_sysfs_stats_nr_applied_attr
=
280 __ATTR_RO_MODE(nr_applied
, 0400);
282 static struct kobj_attribute damon_sysfs_stats_sz_applied_attr
=
283 __ATTR_RO_MODE(sz_applied
, 0400);
285 static struct kobj_attribute damon_sysfs_stats_sz_ops_filter_passed_attr
=
286 __ATTR_RO_MODE(sz_ops_filter_passed
, 0400);
288 static struct kobj_attribute damon_sysfs_stats_qt_exceeds_attr
=
289 __ATTR_RO_MODE(qt_exceeds
, 0400);
291 static struct attribute
*damon_sysfs_stats_attrs
[] = {
292 &damon_sysfs_stats_nr_tried_attr
.attr
,
293 &damon_sysfs_stats_sz_tried_attr
.attr
,
294 &damon_sysfs_stats_nr_applied_attr
.attr
,
295 &damon_sysfs_stats_sz_applied_attr
.attr
,
296 &damon_sysfs_stats_sz_ops_filter_passed_attr
.attr
,
297 &damon_sysfs_stats_qt_exceeds_attr
.attr
,
300 ATTRIBUTE_GROUPS(damon_sysfs_stats
);
302 static const struct kobj_type damon_sysfs_stats_ktype
= {
303 .release
= damon_sysfs_stats_release
,
304 .sysfs_ops
= &kobj_sysfs_ops
,
305 .default_groups
= damon_sysfs_stats_groups
,
312 struct damon_sysfs_scheme_filter
{
314 enum damos_filter_type type
;
318 struct damon_addr_range addr_range
;
322 static struct damon_sysfs_scheme_filter
*damon_sysfs_scheme_filter_alloc(void)
324 return kzalloc(sizeof(struct damon_sysfs_scheme_filter
), GFP_KERNEL
);
327 /* Should match with enum damos_filter_type */
328 static const char * const damon_sysfs_scheme_filter_type_strs
[] = {
336 static ssize_t
type_show(struct kobject
*kobj
,
337 struct kobj_attribute
*attr
, char *buf
)
339 struct damon_sysfs_scheme_filter
*filter
= container_of(kobj
,
340 struct damon_sysfs_scheme_filter
, kobj
);
342 return sysfs_emit(buf
, "%s\n",
343 damon_sysfs_scheme_filter_type_strs
[filter
->type
]);
346 static ssize_t
type_store(struct kobject
*kobj
,
347 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
349 struct damon_sysfs_scheme_filter
*filter
= container_of(kobj
,
350 struct damon_sysfs_scheme_filter
, kobj
);
351 enum damos_filter_type type
;
352 ssize_t ret
= -EINVAL
;
354 for (type
= 0; type
< NR_DAMOS_FILTER_TYPES
; type
++) {
355 if (sysfs_streq(buf
, damon_sysfs_scheme_filter_type_strs
[
365 static ssize_t
matching_show(struct kobject
*kobj
,
366 struct kobj_attribute
*attr
, char *buf
)
368 struct damon_sysfs_scheme_filter
*filter
= container_of(kobj
,
369 struct damon_sysfs_scheme_filter
, kobj
);
371 return sysfs_emit(buf
, "%c\n", filter
->matching
? 'Y' : 'N');
374 static ssize_t
matching_store(struct kobject
*kobj
,
375 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
377 struct damon_sysfs_scheme_filter
*filter
= container_of(kobj
,
378 struct damon_sysfs_scheme_filter
, kobj
);
380 int err
= kstrtobool(buf
, &matching
);
385 filter
->matching
= matching
;
389 static ssize_t
allow_show(struct kobject
*kobj
,
390 struct kobj_attribute
*attr
, char *buf
)
392 struct damon_sysfs_scheme_filter
*filter
= container_of(kobj
,
393 struct damon_sysfs_scheme_filter
, kobj
);
395 return sysfs_emit(buf
, "%c\n", filter
->allow
? 'Y' : 'N');
398 static ssize_t
allow_store(struct kobject
*kobj
,
399 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
401 struct damon_sysfs_scheme_filter
*filter
= container_of(kobj
,
402 struct damon_sysfs_scheme_filter
, kobj
);
404 int err
= kstrtobool(buf
, &allow
);
409 filter
->allow
= allow
;
413 static ssize_t
memcg_path_show(struct kobject
*kobj
,
414 struct kobj_attribute
*attr
, char *buf
)
416 struct damon_sysfs_scheme_filter
*filter
= container_of(kobj
,
417 struct damon_sysfs_scheme_filter
, kobj
);
419 return sysfs_emit(buf
, "%s\n",
420 filter
->memcg_path
? filter
->memcg_path
: "");
423 static ssize_t
memcg_path_store(struct kobject
*kobj
,
424 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
426 struct damon_sysfs_scheme_filter
*filter
= container_of(kobj
,
427 struct damon_sysfs_scheme_filter
, kobj
);
428 char *path
= kmalloc(sizeof(*path
) * (count
+ 1), GFP_KERNEL
);
433 strscpy(path
, buf
, count
+ 1);
434 filter
->memcg_path
= path
;
438 static ssize_t
addr_start_show(struct kobject
*kobj
,
439 struct kobj_attribute
*attr
, char *buf
)
441 struct damon_sysfs_scheme_filter
*filter
= container_of(kobj
,
442 struct damon_sysfs_scheme_filter
, kobj
);
444 return sysfs_emit(buf
, "%lu\n", filter
->addr_range
.start
);
447 static ssize_t
addr_start_store(struct kobject
*kobj
,
448 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
450 struct damon_sysfs_scheme_filter
*filter
= container_of(kobj
,
451 struct damon_sysfs_scheme_filter
, kobj
);
452 int err
= kstrtoul(buf
, 0, &filter
->addr_range
.start
);
454 return err
? err
: count
;
457 static ssize_t
addr_end_show(struct kobject
*kobj
,
458 struct kobj_attribute
*attr
, char *buf
)
460 struct damon_sysfs_scheme_filter
*filter
= container_of(kobj
,
461 struct damon_sysfs_scheme_filter
, kobj
);
463 return sysfs_emit(buf
, "%lu\n", filter
->addr_range
.end
);
466 static ssize_t
addr_end_store(struct kobject
*kobj
,
467 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
469 struct damon_sysfs_scheme_filter
*filter
= container_of(kobj
,
470 struct damon_sysfs_scheme_filter
, kobj
);
471 int err
= kstrtoul(buf
, 0, &filter
->addr_range
.end
);
473 return err
? err
: count
;
476 static ssize_t
damon_target_idx_show(struct kobject
*kobj
,
477 struct kobj_attribute
*attr
, char *buf
)
479 struct damon_sysfs_scheme_filter
*filter
= container_of(kobj
,
480 struct damon_sysfs_scheme_filter
, kobj
);
482 return sysfs_emit(buf
, "%d\n", filter
->target_idx
);
485 static ssize_t
damon_target_idx_store(struct kobject
*kobj
,
486 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
488 struct damon_sysfs_scheme_filter
*filter
= container_of(kobj
,
489 struct damon_sysfs_scheme_filter
, kobj
);
490 int err
= kstrtoint(buf
, 0, &filter
->target_idx
);
492 return err
? err
: count
;
495 static void damon_sysfs_scheme_filter_release(struct kobject
*kobj
)
497 struct damon_sysfs_scheme_filter
*filter
= container_of(kobj
,
498 struct damon_sysfs_scheme_filter
, kobj
);
500 kfree(filter
->memcg_path
);
504 static struct kobj_attribute damon_sysfs_scheme_filter_type_attr
=
505 __ATTR_RW_MODE(type
, 0600);
507 static struct kobj_attribute damon_sysfs_scheme_filter_matching_attr
=
508 __ATTR_RW_MODE(matching
, 0600);
510 static struct kobj_attribute damon_sysfs_scheme_filter_allow_attr
=
511 __ATTR_RW_MODE(allow
, 0600);
513 static struct kobj_attribute damon_sysfs_scheme_filter_memcg_path_attr
=
514 __ATTR_RW_MODE(memcg_path
, 0600);
516 static struct kobj_attribute damon_sysfs_scheme_filter_addr_start_attr
=
517 __ATTR_RW_MODE(addr_start
, 0600);
519 static struct kobj_attribute damon_sysfs_scheme_filter_addr_end_attr
=
520 __ATTR_RW_MODE(addr_end
, 0600);
522 static struct kobj_attribute damon_sysfs_scheme_filter_damon_target_idx_attr
=
523 __ATTR_RW_MODE(damon_target_idx
, 0600);
525 static struct attribute
*damon_sysfs_scheme_filter_attrs
[] = {
526 &damon_sysfs_scheme_filter_type_attr
.attr
,
527 &damon_sysfs_scheme_filter_matching_attr
.attr
,
528 &damon_sysfs_scheme_filter_allow_attr
.attr
,
529 &damon_sysfs_scheme_filter_memcg_path_attr
.attr
,
530 &damon_sysfs_scheme_filter_addr_start_attr
.attr
,
531 &damon_sysfs_scheme_filter_addr_end_attr
.attr
,
532 &damon_sysfs_scheme_filter_damon_target_idx_attr
.attr
,
535 ATTRIBUTE_GROUPS(damon_sysfs_scheme_filter
);
537 static const struct kobj_type damon_sysfs_scheme_filter_ktype
= {
538 .release
= damon_sysfs_scheme_filter_release
,
539 .sysfs_ops
= &kobj_sysfs_ops
,
540 .default_groups
= damon_sysfs_scheme_filter_groups
,
547 struct damon_sysfs_scheme_filters
{
549 struct damon_sysfs_scheme_filter
**filters_arr
;
553 static struct damon_sysfs_scheme_filters
*
554 damon_sysfs_scheme_filters_alloc(void)
556 return kzalloc(sizeof(struct damon_sysfs_scheme_filters
), GFP_KERNEL
);
559 static void damon_sysfs_scheme_filters_rm_dirs(
560 struct damon_sysfs_scheme_filters
*filters
)
562 struct damon_sysfs_scheme_filter
**filters_arr
= filters
->filters_arr
;
565 for (i
= 0; i
< filters
->nr
; i
++)
566 kobject_put(&filters_arr
[i
]->kobj
);
569 filters
->filters_arr
= NULL
;
572 static int damon_sysfs_scheme_filters_add_dirs(
573 struct damon_sysfs_scheme_filters
*filters
, int nr_filters
)
575 struct damon_sysfs_scheme_filter
**filters_arr
, *filter
;
578 damon_sysfs_scheme_filters_rm_dirs(filters
);
582 filters_arr
= kmalloc_array(nr_filters
, sizeof(*filters_arr
),
583 GFP_KERNEL
| __GFP_NOWARN
);
586 filters
->filters_arr
= filters_arr
;
588 for (i
= 0; i
< nr_filters
; i
++) {
589 filter
= damon_sysfs_scheme_filter_alloc();
591 damon_sysfs_scheme_filters_rm_dirs(filters
);
595 err
= kobject_init_and_add(&filter
->kobj
,
596 &damon_sysfs_scheme_filter_ktype
,
597 &filters
->kobj
, "%d", i
);
599 kobject_put(&filter
->kobj
);
600 damon_sysfs_scheme_filters_rm_dirs(filters
);
604 filters_arr
[i
] = filter
;
610 static ssize_t
nr_filters_show(struct kobject
*kobj
,
611 struct kobj_attribute
*attr
, char *buf
)
613 struct damon_sysfs_scheme_filters
*filters
= container_of(kobj
,
614 struct damon_sysfs_scheme_filters
, kobj
);
616 return sysfs_emit(buf
, "%d\n", filters
->nr
);
619 static ssize_t
nr_filters_store(struct kobject
*kobj
,
620 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
622 struct damon_sysfs_scheme_filters
*filters
;
623 int nr
, err
= kstrtoint(buf
, 0, &nr
);
630 filters
= container_of(kobj
, struct damon_sysfs_scheme_filters
, kobj
);
632 if (!mutex_trylock(&damon_sysfs_lock
))
634 err
= damon_sysfs_scheme_filters_add_dirs(filters
, nr
);
635 mutex_unlock(&damon_sysfs_lock
);
642 static void damon_sysfs_scheme_filters_release(struct kobject
*kobj
)
644 kfree(container_of(kobj
, struct damon_sysfs_scheme_filters
, kobj
));
647 static struct kobj_attribute damon_sysfs_scheme_filters_nr_attr
=
648 __ATTR_RW_MODE(nr_filters
, 0600);
650 static struct attribute
*damon_sysfs_scheme_filters_attrs
[] = {
651 &damon_sysfs_scheme_filters_nr_attr
.attr
,
654 ATTRIBUTE_GROUPS(damon_sysfs_scheme_filters
);
656 static const struct kobj_type damon_sysfs_scheme_filters_ktype
= {
657 .release
= damon_sysfs_scheme_filters_release
,
658 .sysfs_ops
= &kobj_sysfs_ops
,
659 .default_groups
= damon_sysfs_scheme_filters_groups
,
663 * watermarks directory
666 struct damon_sysfs_watermarks
{
668 enum damos_wmark_metric metric
;
669 unsigned long interval_us
;
675 static struct damon_sysfs_watermarks
*damon_sysfs_watermarks_alloc(
676 enum damos_wmark_metric metric
, unsigned long interval_us
,
677 unsigned long high
, unsigned long mid
, unsigned long low
)
679 struct damon_sysfs_watermarks
*watermarks
= kmalloc(
680 sizeof(*watermarks
), GFP_KERNEL
);
684 watermarks
->kobj
= (struct kobject
){};
685 watermarks
->metric
= metric
;
686 watermarks
->interval_us
= interval_us
;
687 watermarks
->high
= high
;
688 watermarks
->mid
= mid
;
689 watermarks
->low
= low
;
693 /* Should match with enum damos_wmark_metric */
694 static const char * const damon_sysfs_wmark_metric_strs
[] = {
699 static ssize_t
metric_show(struct kobject
*kobj
, struct kobj_attribute
*attr
,
702 struct damon_sysfs_watermarks
*watermarks
= container_of(kobj
,
703 struct damon_sysfs_watermarks
, kobj
);
705 return sysfs_emit(buf
, "%s\n",
706 damon_sysfs_wmark_metric_strs
[watermarks
->metric
]);
709 static ssize_t
metric_store(struct kobject
*kobj
, struct kobj_attribute
*attr
,
710 const char *buf
, size_t count
)
712 struct damon_sysfs_watermarks
*watermarks
= container_of(kobj
,
713 struct damon_sysfs_watermarks
, kobj
);
714 enum damos_wmark_metric metric
;
716 for (metric
= 0; metric
< NR_DAMOS_WMARK_METRICS
; metric
++) {
717 if (sysfs_streq(buf
, damon_sysfs_wmark_metric_strs
[metric
])) {
718 watermarks
->metric
= metric
;
725 static ssize_t
interval_us_show(struct kobject
*kobj
,
726 struct kobj_attribute
*attr
, char *buf
)
728 struct damon_sysfs_watermarks
*watermarks
= container_of(kobj
,
729 struct damon_sysfs_watermarks
, kobj
);
731 return sysfs_emit(buf
, "%lu\n", watermarks
->interval_us
);
734 static ssize_t
interval_us_store(struct kobject
*kobj
,
735 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
737 struct damon_sysfs_watermarks
*watermarks
= container_of(kobj
,
738 struct damon_sysfs_watermarks
, kobj
);
739 int err
= kstrtoul(buf
, 0, &watermarks
->interval_us
);
741 return err
? err
: count
;
744 static ssize_t
high_show(struct kobject
*kobj
,
745 struct kobj_attribute
*attr
, char *buf
)
747 struct damon_sysfs_watermarks
*watermarks
= container_of(kobj
,
748 struct damon_sysfs_watermarks
, kobj
);
750 return sysfs_emit(buf
, "%lu\n", watermarks
->high
);
753 static ssize_t
high_store(struct kobject
*kobj
,
754 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
756 struct damon_sysfs_watermarks
*watermarks
= container_of(kobj
,
757 struct damon_sysfs_watermarks
, kobj
);
758 int err
= kstrtoul(buf
, 0, &watermarks
->high
);
760 return err
? err
: count
;
763 static ssize_t
mid_show(struct kobject
*kobj
,
764 struct kobj_attribute
*attr
, char *buf
)
766 struct damon_sysfs_watermarks
*watermarks
= container_of(kobj
,
767 struct damon_sysfs_watermarks
, kobj
);
769 return sysfs_emit(buf
, "%lu\n", watermarks
->mid
);
772 static ssize_t
mid_store(struct kobject
*kobj
,
773 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
775 struct damon_sysfs_watermarks
*watermarks
= container_of(kobj
,
776 struct damon_sysfs_watermarks
, kobj
);
777 int err
= kstrtoul(buf
, 0, &watermarks
->mid
);
779 return err
? err
: count
;
782 static ssize_t
low_show(struct kobject
*kobj
,
783 struct kobj_attribute
*attr
, char *buf
)
785 struct damon_sysfs_watermarks
*watermarks
= container_of(kobj
,
786 struct damon_sysfs_watermarks
, kobj
);
788 return sysfs_emit(buf
, "%lu\n", watermarks
->low
);
791 static ssize_t
low_store(struct kobject
*kobj
,
792 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
794 struct damon_sysfs_watermarks
*watermarks
= container_of(kobj
,
795 struct damon_sysfs_watermarks
, kobj
);
796 int err
= kstrtoul(buf
, 0, &watermarks
->low
);
798 return err
? err
: count
;
801 static void damon_sysfs_watermarks_release(struct kobject
*kobj
)
803 kfree(container_of(kobj
, struct damon_sysfs_watermarks
, kobj
));
806 static struct kobj_attribute damon_sysfs_watermarks_metric_attr
=
807 __ATTR_RW_MODE(metric
, 0600);
809 static struct kobj_attribute damon_sysfs_watermarks_interval_us_attr
=
810 __ATTR_RW_MODE(interval_us
, 0600);
812 static struct kobj_attribute damon_sysfs_watermarks_high_attr
=
813 __ATTR_RW_MODE(high
, 0600);
815 static struct kobj_attribute damon_sysfs_watermarks_mid_attr
=
816 __ATTR_RW_MODE(mid
, 0600);
818 static struct kobj_attribute damon_sysfs_watermarks_low_attr
=
819 __ATTR_RW_MODE(low
, 0600);
821 static struct attribute
*damon_sysfs_watermarks_attrs
[] = {
822 &damon_sysfs_watermarks_metric_attr
.attr
,
823 &damon_sysfs_watermarks_interval_us_attr
.attr
,
824 &damon_sysfs_watermarks_high_attr
.attr
,
825 &damon_sysfs_watermarks_mid_attr
.attr
,
826 &damon_sysfs_watermarks_low_attr
.attr
,
829 ATTRIBUTE_GROUPS(damon_sysfs_watermarks
);
831 static const struct kobj_type damon_sysfs_watermarks_ktype
= {
832 .release
= damon_sysfs_watermarks_release
,
833 .sysfs_ops
= &kobj_sysfs_ops
,
834 .default_groups
= damon_sysfs_watermarks_groups
,
838 * quota goal directory
841 struct damos_sysfs_quota_goal
{
843 enum damos_quota_goal_metric metric
;
844 unsigned long target_value
;
845 unsigned long current_value
;
848 /* This should match with enum damos_action */
849 static const char * const damos_sysfs_quota_goal_metric_strs
[] = {
854 static struct damos_sysfs_quota_goal
*damos_sysfs_quota_goal_alloc(void)
856 return kzalloc(sizeof(struct damos_sysfs_quota_goal
), GFP_KERNEL
);
859 static ssize_t
target_metric_show(struct kobject
*kobj
,
860 struct kobj_attribute
*attr
, char *buf
)
862 struct damos_sysfs_quota_goal
*goal
= container_of(kobj
,
863 struct damos_sysfs_quota_goal
, kobj
);
865 return sysfs_emit(buf
, "%s\n",
866 damos_sysfs_quota_goal_metric_strs
[goal
->metric
]);
869 static ssize_t
target_metric_store(struct kobject
*kobj
,
870 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
872 struct damos_sysfs_quota_goal
*goal
= container_of(kobj
,
873 struct damos_sysfs_quota_goal
, kobj
);
874 enum damos_quota_goal_metric m
;
876 for (m
= 0; m
< NR_DAMOS_QUOTA_GOAL_METRICS
; m
++) {
877 if (sysfs_streq(buf
, damos_sysfs_quota_goal_metric_strs
[m
])) {
885 static ssize_t
target_value_show(struct kobject
*kobj
,
886 struct kobj_attribute
*attr
, char *buf
)
888 struct damos_sysfs_quota_goal
*goal
= container_of(kobj
, struct
889 damos_sysfs_quota_goal
, kobj
);
891 return sysfs_emit(buf
, "%lu\n", goal
->target_value
);
894 static ssize_t
target_value_store(struct kobject
*kobj
,
895 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
897 struct damos_sysfs_quota_goal
*goal
= container_of(kobj
, struct
898 damos_sysfs_quota_goal
, kobj
);
899 int err
= kstrtoul(buf
, 0, &goal
->target_value
);
901 return err
? err
: count
;
904 static ssize_t
current_value_show(struct kobject
*kobj
,
905 struct kobj_attribute
*attr
, char *buf
)
907 struct damos_sysfs_quota_goal
*goal
= container_of(kobj
, struct
908 damos_sysfs_quota_goal
, kobj
);
910 return sysfs_emit(buf
, "%lu\n", goal
->current_value
);
913 static ssize_t
current_value_store(struct kobject
*kobj
,
914 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
916 struct damos_sysfs_quota_goal
*goal
= container_of(kobj
, struct
917 damos_sysfs_quota_goal
, kobj
);
918 int err
= kstrtoul(buf
, 0, &goal
->current_value
);
920 /* feed callback should check existence of this file and read value */
921 return err
? err
: count
;
924 static void damos_sysfs_quota_goal_release(struct kobject
*kobj
)
926 /* or, notify this release to the feed callback */
927 kfree(container_of(kobj
, struct damos_sysfs_quota_goal
, kobj
));
930 static struct kobj_attribute damos_sysfs_quota_goal_target_metric_attr
=
931 __ATTR_RW_MODE(target_metric
, 0600);
933 static struct kobj_attribute damos_sysfs_quota_goal_target_value_attr
=
934 __ATTR_RW_MODE(target_value
, 0600);
936 static struct kobj_attribute damos_sysfs_quota_goal_current_value_attr
=
937 __ATTR_RW_MODE(current_value
, 0600);
939 static struct attribute
*damos_sysfs_quota_goal_attrs
[] = {
940 &damos_sysfs_quota_goal_target_metric_attr
.attr
,
941 &damos_sysfs_quota_goal_target_value_attr
.attr
,
942 &damos_sysfs_quota_goal_current_value_attr
.attr
,
945 ATTRIBUTE_GROUPS(damos_sysfs_quota_goal
);
947 static const struct kobj_type damos_sysfs_quota_goal_ktype
= {
948 .release
= damos_sysfs_quota_goal_release
,
949 .sysfs_ops
= &kobj_sysfs_ops
,
950 .default_groups
= damos_sysfs_quota_goal_groups
,
954 * quota goals directory
957 struct damos_sysfs_quota_goals
{
959 struct damos_sysfs_quota_goal
**goals_arr
; /* counted by nr */
963 static struct damos_sysfs_quota_goals
*damos_sysfs_quota_goals_alloc(void)
965 return kzalloc(sizeof(struct damos_sysfs_quota_goals
), GFP_KERNEL
);
968 static void damos_sysfs_quota_goals_rm_dirs(
969 struct damos_sysfs_quota_goals
*goals
)
971 struct damos_sysfs_quota_goal
**goals_arr
= goals
->goals_arr
;
974 for (i
= 0; i
< goals
->nr
; i
++)
975 kobject_put(&goals_arr
[i
]->kobj
);
978 goals
->goals_arr
= NULL
;
981 static int damos_sysfs_quota_goals_add_dirs(
982 struct damos_sysfs_quota_goals
*goals
, int nr_goals
)
984 struct damos_sysfs_quota_goal
**goals_arr
, *goal
;
987 damos_sysfs_quota_goals_rm_dirs(goals
);
991 goals_arr
= kmalloc_array(nr_goals
, sizeof(*goals_arr
),
992 GFP_KERNEL
| __GFP_NOWARN
);
995 goals
->goals_arr
= goals_arr
;
997 for (i
= 0; i
< nr_goals
; i
++) {
998 goal
= damos_sysfs_quota_goal_alloc();
1000 damos_sysfs_quota_goals_rm_dirs(goals
);
1004 err
= kobject_init_and_add(&goal
->kobj
,
1005 &damos_sysfs_quota_goal_ktype
, &goals
->kobj
,
1008 kobject_put(&goal
->kobj
);
1009 damos_sysfs_quota_goals_rm_dirs(goals
);
1013 goals_arr
[i
] = goal
;
1019 static ssize_t
nr_goals_show(struct kobject
*kobj
,
1020 struct kobj_attribute
*attr
, char *buf
)
1022 struct damos_sysfs_quota_goals
*goals
= container_of(kobj
,
1023 struct damos_sysfs_quota_goals
, kobj
);
1025 return sysfs_emit(buf
, "%d\n", goals
->nr
);
1028 static ssize_t
nr_goals_store(struct kobject
*kobj
,
1029 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
1031 struct damos_sysfs_quota_goals
*goals
;
1032 int nr
, err
= kstrtoint(buf
, 0, &nr
);
1039 goals
= container_of(kobj
, struct damos_sysfs_quota_goals
, kobj
);
1041 if (!mutex_trylock(&damon_sysfs_lock
))
1043 err
= damos_sysfs_quota_goals_add_dirs(goals
, nr
);
1044 mutex_unlock(&damon_sysfs_lock
);
1051 static void damos_sysfs_quota_goals_release(struct kobject
*kobj
)
1053 kfree(container_of(kobj
, struct damos_sysfs_quota_goals
, kobj
));
1056 static struct kobj_attribute damos_sysfs_quota_goals_nr_attr
=
1057 __ATTR_RW_MODE(nr_goals
, 0600);
1059 static struct attribute
*damos_sysfs_quota_goals_attrs
[] = {
1060 &damos_sysfs_quota_goals_nr_attr
.attr
,
1063 ATTRIBUTE_GROUPS(damos_sysfs_quota_goals
);
1065 static const struct kobj_type damos_sysfs_quota_goals_ktype
= {
1066 .release
= damos_sysfs_quota_goals_release
,
1067 .sysfs_ops
= &kobj_sysfs_ops
,
1068 .default_groups
= damos_sysfs_quota_goals_groups
,
1072 * scheme/weights directory
1075 struct damon_sysfs_weights
{
1076 struct kobject kobj
;
1078 unsigned int nr_accesses
;
1082 static struct damon_sysfs_weights
*damon_sysfs_weights_alloc(unsigned int sz
,
1083 unsigned int nr_accesses
, unsigned int age
)
1085 struct damon_sysfs_weights
*weights
= kmalloc(sizeof(*weights
),
1090 weights
->kobj
= (struct kobject
){};
1092 weights
->nr_accesses
= nr_accesses
;
1097 static ssize_t
sz_permil_show(struct kobject
*kobj
,
1098 struct kobj_attribute
*attr
, char *buf
)
1100 struct damon_sysfs_weights
*weights
= container_of(kobj
,
1101 struct damon_sysfs_weights
, kobj
);
1103 return sysfs_emit(buf
, "%u\n", weights
->sz
);
1106 static ssize_t
sz_permil_store(struct kobject
*kobj
,
1107 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
1109 struct damon_sysfs_weights
*weights
= container_of(kobj
,
1110 struct damon_sysfs_weights
, kobj
);
1111 int err
= kstrtouint(buf
, 0, &weights
->sz
);
1113 return err
? err
: count
;
1116 static ssize_t
nr_accesses_permil_show(struct kobject
*kobj
,
1117 struct kobj_attribute
*attr
, char *buf
)
1119 struct damon_sysfs_weights
*weights
= container_of(kobj
,
1120 struct damon_sysfs_weights
, kobj
);
1122 return sysfs_emit(buf
, "%u\n", weights
->nr_accesses
);
1125 static ssize_t
nr_accesses_permil_store(struct kobject
*kobj
,
1126 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
1128 struct damon_sysfs_weights
*weights
= container_of(kobj
,
1129 struct damon_sysfs_weights
, kobj
);
1130 int err
= kstrtouint(buf
, 0, &weights
->nr_accesses
);
1132 return err
? err
: count
;
1135 static ssize_t
age_permil_show(struct kobject
*kobj
,
1136 struct kobj_attribute
*attr
, char *buf
)
1138 struct damon_sysfs_weights
*weights
= container_of(kobj
,
1139 struct damon_sysfs_weights
, kobj
);
1141 return sysfs_emit(buf
, "%u\n", weights
->age
);
1144 static ssize_t
age_permil_store(struct kobject
*kobj
,
1145 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
1147 struct damon_sysfs_weights
*weights
= container_of(kobj
,
1148 struct damon_sysfs_weights
, kobj
);
1149 int err
= kstrtouint(buf
, 0, &weights
->age
);
1151 return err
? err
: count
;
1154 static void damon_sysfs_weights_release(struct kobject
*kobj
)
1156 kfree(container_of(kobj
, struct damon_sysfs_weights
, kobj
));
1159 static struct kobj_attribute damon_sysfs_weights_sz_attr
=
1160 __ATTR_RW_MODE(sz_permil
, 0600);
1162 static struct kobj_attribute damon_sysfs_weights_nr_accesses_attr
=
1163 __ATTR_RW_MODE(nr_accesses_permil
, 0600);
1165 static struct kobj_attribute damon_sysfs_weights_age_attr
=
1166 __ATTR_RW_MODE(age_permil
, 0600);
1168 static struct attribute
*damon_sysfs_weights_attrs
[] = {
1169 &damon_sysfs_weights_sz_attr
.attr
,
1170 &damon_sysfs_weights_nr_accesses_attr
.attr
,
1171 &damon_sysfs_weights_age_attr
.attr
,
1174 ATTRIBUTE_GROUPS(damon_sysfs_weights
);
1176 static const struct kobj_type damon_sysfs_weights_ktype
= {
1177 .release
= damon_sysfs_weights_release
,
1178 .sysfs_ops
= &kobj_sysfs_ops
,
1179 .default_groups
= damon_sysfs_weights_groups
,
1186 struct damon_sysfs_quotas
{
1187 struct kobject kobj
;
1188 struct damon_sysfs_weights
*weights
;
1189 struct damos_sysfs_quota_goals
*goals
;
1192 unsigned long reset_interval_ms
;
1193 unsigned long effective_sz
; /* Effective size quota in bytes */
1196 static struct damon_sysfs_quotas
*damon_sysfs_quotas_alloc(void)
1198 return kzalloc(sizeof(struct damon_sysfs_quotas
), GFP_KERNEL
);
1201 static int damon_sysfs_quotas_add_dirs(struct damon_sysfs_quotas
*quotas
)
1203 struct damon_sysfs_weights
*weights
;
1204 struct damos_sysfs_quota_goals
*goals
;
1207 weights
= damon_sysfs_weights_alloc(0, 0, 0);
1211 err
= kobject_init_and_add(&weights
->kobj
, &damon_sysfs_weights_ktype
,
1212 "as
->kobj
, "weights");
1214 kobject_put(&weights
->kobj
);
1217 quotas
->weights
= weights
;
1219 goals
= damos_sysfs_quota_goals_alloc();
1221 kobject_put(&weights
->kobj
);
1224 err
= kobject_init_and_add(&goals
->kobj
,
1225 &damos_sysfs_quota_goals_ktype
, "as
->kobj
,
1228 kobject_put(&weights
->kobj
);
1229 kobject_put(&goals
->kobj
);
1231 quotas
->goals
= goals
;
1237 static void damon_sysfs_quotas_rm_dirs(struct damon_sysfs_quotas
*quotas
)
1239 kobject_put("as
->weights
->kobj
);
1240 damos_sysfs_quota_goals_rm_dirs(quotas
->goals
);
1241 kobject_put("as
->goals
->kobj
);
1244 static ssize_t
ms_show(struct kobject
*kobj
, struct kobj_attribute
*attr
,
1247 struct damon_sysfs_quotas
*quotas
= container_of(kobj
,
1248 struct damon_sysfs_quotas
, kobj
);
1250 return sysfs_emit(buf
, "%lu\n", quotas
->ms
);
1253 static ssize_t
ms_store(struct kobject
*kobj
, struct kobj_attribute
*attr
,
1254 const char *buf
, size_t count
)
1256 struct damon_sysfs_quotas
*quotas
= container_of(kobj
,
1257 struct damon_sysfs_quotas
, kobj
);
1258 int err
= kstrtoul(buf
, 0, "as
->ms
);
1265 static ssize_t
bytes_show(struct kobject
*kobj
, struct kobj_attribute
*attr
,
1268 struct damon_sysfs_quotas
*quotas
= container_of(kobj
,
1269 struct damon_sysfs_quotas
, kobj
);
1271 return sysfs_emit(buf
, "%lu\n", quotas
->sz
);
1274 static ssize_t
bytes_store(struct kobject
*kobj
,
1275 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
1277 struct damon_sysfs_quotas
*quotas
= container_of(kobj
,
1278 struct damon_sysfs_quotas
, kobj
);
1279 int err
= kstrtoul(buf
, 0, "as
->sz
);
1286 static ssize_t
reset_interval_ms_show(struct kobject
*kobj
,
1287 struct kobj_attribute
*attr
, char *buf
)
1289 struct damon_sysfs_quotas
*quotas
= container_of(kobj
,
1290 struct damon_sysfs_quotas
, kobj
);
1292 return sysfs_emit(buf
, "%lu\n", quotas
->reset_interval_ms
);
1295 static ssize_t
reset_interval_ms_store(struct kobject
*kobj
,
1296 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
1298 struct damon_sysfs_quotas
*quotas
= container_of(kobj
,
1299 struct damon_sysfs_quotas
, kobj
);
1300 int err
= kstrtoul(buf
, 0, "as
->reset_interval_ms
);
1307 static ssize_t
effective_bytes_show(struct kobject
*kobj
,
1308 struct kobj_attribute
*attr
, char *buf
)
1310 struct damon_sysfs_quotas
*quotas
= container_of(kobj
,
1311 struct damon_sysfs_quotas
, kobj
);
1313 return sysfs_emit(buf
, "%lu\n", quotas
->effective_sz
);
1316 static void damon_sysfs_quotas_release(struct kobject
*kobj
)
1318 kfree(container_of(kobj
, struct damon_sysfs_quotas
, kobj
));
1321 static struct kobj_attribute damon_sysfs_quotas_ms_attr
=
1322 __ATTR_RW_MODE(ms
, 0600);
1324 static struct kobj_attribute damon_sysfs_quotas_sz_attr
=
1325 __ATTR_RW_MODE(bytes
, 0600);
1327 static struct kobj_attribute damon_sysfs_quotas_reset_interval_ms_attr
=
1328 __ATTR_RW_MODE(reset_interval_ms
, 0600);
1330 static struct kobj_attribute damon_sysfs_quotas_effective_bytes_attr
=
1331 __ATTR_RO_MODE(effective_bytes
, 0400);
1333 static struct attribute
*damon_sysfs_quotas_attrs
[] = {
1334 &damon_sysfs_quotas_ms_attr
.attr
,
1335 &damon_sysfs_quotas_sz_attr
.attr
,
1336 &damon_sysfs_quotas_reset_interval_ms_attr
.attr
,
1337 &damon_sysfs_quotas_effective_bytes_attr
.attr
,
1340 ATTRIBUTE_GROUPS(damon_sysfs_quotas
);
1342 static const struct kobj_type damon_sysfs_quotas_ktype
= {
1343 .release
= damon_sysfs_quotas_release
,
1344 .sysfs_ops
= &kobj_sysfs_ops
,
1345 .default_groups
= damon_sysfs_quotas_groups
,
1349 * access_pattern directory
1352 struct damon_sysfs_access_pattern
{
1353 struct kobject kobj
;
1354 struct damon_sysfs_ul_range
*sz
;
1355 struct damon_sysfs_ul_range
*nr_accesses
;
1356 struct damon_sysfs_ul_range
*age
;
1360 struct damon_sysfs_access_pattern
*damon_sysfs_access_pattern_alloc(void)
1362 struct damon_sysfs_access_pattern
*access_pattern
=
1363 kmalloc(sizeof(*access_pattern
), GFP_KERNEL
);
1365 if (!access_pattern
)
1367 access_pattern
->kobj
= (struct kobject
){};
1368 return access_pattern
;
1371 static int damon_sysfs_access_pattern_add_range_dir(
1372 struct damon_sysfs_access_pattern
*access_pattern
,
1373 struct damon_sysfs_ul_range
**range_dir_ptr
,
1376 struct damon_sysfs_ul_range
*range
= damon_sysfs_ul_range_alloc(0, 0);
1381 err
= kobject_init_and_add(&range
->kobj
, &damon_sysfs_ul_range_ktype
,
1382 &access_pattern
->kobj
, name
);
1384 kobject_put(&range
->kobj
);
1386 *range_dir_ptr
= range
;
1390 static int damon_sysfs_access_pattern_add_dirs(
1391 struct damon_sysfs_access_pattern
*access_pattern
)
1395 err
= damon_sysfs_access_pattern_add_range_dir(access_pattern
,
1396 &access_pattern
->sz
, "sz");
1400 err
= damon_sysfs_access_pattern_add_range_dir(access_pattern
,
1401 &access_pattern
->nr_accesses
, "nr_accesses");
1403 goto put_nr_accesses_sz_out
;
1405 err
= damon_sysfs_access_pattern_add_range_dir(access_pattern
,
1406 &access_pattern
->age
, "age");
1408 goto put_age_nr_accesses_sz_out
;
1411 put_age_nr_accesses_sz_out
:
1412 kobject_put(&access_pattern
->age
->kobj
);
1413 access_pattern
->age
= NULL
;
1414 put_nr_accesses_sz_out
:
1415 kobject_put(&access_pattern
->nr_accesses
->kobj
);
1416 access_pattern
->nr_accesses
= NULL
;
1418 kobject_put(&access_pattern
->sz
->kobj
);
1419 access_pattern
->sz
= NULL
;
1423 static void damon_sysfs_access_pattern_rm_dirs(
1424 struct damon_sysfs_access_pattern
*access_pattern
)
1426 kobject_put(&access_pattern
->sz
->kobj
);
1427 kobject_put(&access_pattern
->nr_accesses
->kobj
);
1428 kobject_put(&access_pattern
->age
->kobj
);
1431 static void damon_sysfs_access_pattern_release(struct kobject
*kobj
)
1433 kfree(container_of(kobj
, struct damon_sysfs_access_pattern
, kobj
));
1436 static struct attribute
*damon_sysfs_access_pattern_attrs
[] = {
1439 ATTRIBUTE_GROUPS(damon_sysfs_access_pattern
);
1441 static const struct kobj_type damon_sysfs_access_pattern_ktype
= {
1442 .release
= damon_sysfs_access_pattern_release
,
1443 .sysfs_ops
= &kobj_sysfs_ops
,
1444 .default_groups
= damon_sysfs_access_pattern_groups
,
1451 struct damon_sysfs_scheme
{
1452 struct kobject kobj
;
1453 enum damos_action action
;
1454 struct damon_sysfs_access_pattern
*access_pattern
;
1455 unsigned long apply_interval_us
;
1456 struct damon_sysfs_quotas
*quotas
;
1457 struct damon_sysfs_watermarks
*watermarks
;
1458 struct damon_sysfs_scheme_filters
*filters
;
1459 struct damon_sysfs_stats
*stats
;
1460 struct damon_sysfs_scheme_regions
*tried_regions
;
1464 /* This should match with enum damos_action */
1465 static const char * const damon_sysfs_damos_action_strs
[] = {
1478 static struct damon_sysfs_scheme
*damon_sysfs_scheme_alloc(
1479 enum damos_action action
, unsigned long apply_interval_us
)
1481 struct damon_sysfs_scheme
*scheme
= kmalloc(sizeof(*scheme
),
1486 scheme
->kobj
= (struct kobject
){};
1487 scheme
->action
= action
;
1488 scheme
->apply_interval_us
= apply_interval_us
;
1489 scheme
->target_nid
= NUMA_NO_NODE
;
1493 static int damon_sysfs_scheme_set_access_pattern(
1494 struct damon_sysfs_scheme
*scheme
)
1496 struct damon_sysfs_access_pattern
*access_pattern
;
1499 access_pattern
= damon_sysfs_access_pattern_alloc();
1500 if (!access_pattern
)
1502 err
= kobject_init_and_add(&access_pattern
->kobj
,
1503 &damon_sysfs_access_pattern_ktype
, &scheme
->kobj
,
1507 err
= damon_sysfs_access_pattern_add_dirs(access_pattern
);
1510 scheme
->access_pattern
= access_pattern
;
1514 kobject_put(&access_pattern
->kobj
);
1518 static int damon_sysfs_scheme_set_quotas(struct damon_sysfs_scheme
*scheme
)
1520 struct damon_sysfs_quotas
*quotas
= damon_sysfs_quotas_alloc();
1525 err
= kobject_init_and_add("as
->kobj
, &damon_sysfs_quotas_ktype
,
1526 &scheme
->kobj
, "quotas");
1529 err
= damon_sysfs_quotas_add_dirs(quotas
);
1532 scheme
->quotas
= quotas
;
1536 kobject_put("as
->kobj
);
1540 static int damon_sysfs_scheme_set_watermarks(struct damon_sysfs_scheme
*scheme
)
1542 struct damon_sysfs_watermarks
*watermarks
=
1543 damon_sysfs_watermarks_alloc(DAMOS_WMARK_NONE
, 0, 0, 0, 0);
1548 err
= kobject_init_and_add(&watermarks
->kobj
,
1549 &damon_sysfs_watermarks_ktype
, &scheme
->kobj
,
1552 kobject_put(&watermarks
->kobj
);
1554 scheme
->watermarks
= watermarks
;
1558 static int damon_sysfs_scheme_set_filters(struct damon_sysfs_scheme
*scheme
)
1560 struct damon_sysfs_scheme_filters
*filters
=
1561 damon_sysfs_scheme_filters_alloc();
1566 err
= kobject_init_and_add(&filters
->kobj
,
1567 &damon_sysfs_scheme_filters_ktype
, &scheme
->kobj
,
1570 kobject_put(&filters
->kobj
);
1572 scheme
->filters
= filters
;
1576 static int damon_sysfs_scheme_set_stats(struct damon_sysfs_scheme
*scheme
)
1578 struct damon_sysfs_stats
*stats
= damon_sysfs_stats_alloc();
1583 err
= kobject_init_and_add(&stats
->kobj
, &damon_sysfs_stats_ktype
,
1584 &scheme
->kobj
, "stats");
1586 kobject_put(&stats
->kobj
);
1588 scheme
->stats
= stats
;
1592 static int damon_sysfs_scheme_set_tried_regions(
1593 struct damon_sysfs_scheme
*scheme
)
1595 struct damon_sysfs_scheme_regions
*tried_regions
=
1596 damon_sysfs_scheme_regions_alloc();
1601 err
= kobject_init_and_add(&tried_regions
->kobj
,
1602 &damon_sysfs_scheme_regions_ktype
, &scheme
->kobj
,
1605 kobject_put(&tried_regions
->kobj
);
1607 scheme
->tried_regions
= tried_regions
;
1611 static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme
*scheme
)
1615 err
= damon_sysfs_scheme_set_access_pattern(scheme
);
1618 err
= damon_sysfs_scheme_set_quotas(scheme
);
1620 goto put_access_pattern_out
;
1621 err
= damon_sysfs_scheme_set_watermarks(scheme
);
1623 goto put_quotas_access_pattern_out
;
1624 err
= damon_sysfs_scheme_set_filters(scheme
);
1626 goto put_watermarks_quotas_access_pattern_out
;
1627 err
= damon_sysfs_scheme_set_stats(scheme
);
1629 goto put_filters_watermarks_quotas_access_pattern_out
;
1630 err
= damon_sysfs_scheme_set_tried_regions(scheme
);
1632 goto put_tried_regions_out
;
1635 put_tried_regions_out
:
1636 kobject_put(&scheme
->tried_regions
->kobj
);
1637 scheme
->tried_regions
= NULL
;
1638 put_filters_watermarks_quotas_access_pattern_out
:
1639 kobject_put(&scheme
->filters
->kobj
);
1640 scheme
->filters
= NULL
;
1641 put_watermarks_quotas_access_pattern_out
:
1642 kobject_put(&scheme
->watermarks
->kobj
);
1643 scheme
->watermarks
= NULL
;
1644 put_quotas_access_pattern_out
:
1645 kobject_put(&scheme
->quotas
->kobj
);
1646 scheme
->quotas
= NULL
;
1647 put_access_pattern_out
:
1648 kobject_put(&scheme
->access_pattern
->kobj
);
1649 scheme
->access_pattern
= NULL
;
1653 static void damon_sysfs_scheme_rm_dirs(struct damon_sysfs_scheme
*scheme
)
1655 damon_sysfs_access_pattern_rm_dirs(scheme
->access_pattern
);
1656 kobject_put(&scheme
->access_pattern
->kobj
);
1657 damon_sysfs_quotas_rm_dirs(scheme
->quotas
);
1658 kobject_put(&scheme
->quotas
->kobj
);
1659 kobject_put(&scheme
->watermarks
->kobj
);
1660 damon_sysfs_scheme_filters_rm_dirs(scheme
->filters
);
1661 kobject_put(&scheme
->filters
->kobj
);
1662 kobject_put(&scheme
->stats
->kobj
);
1663 damon_sysfs_scheme_regions_rm_dirs(scheme
->tried_regions
);
1664 kobject_put(&scheme
->tried_regions
->kobj
);
1667 static ssize_t
action_show(struct kobject
*kobj
, struct kobj_attribute
*attr
,
1670 struct damon_sysfs_scheme
*scheme
= container_of(kobj
,
1671 struct damon_sysfs_scheme
, kobj
);
1673 return sysfs_emit(buf
, "%s\n",
1674 damon_sysfs_damos_action_strs
[scheme
->action
]);
1677 static ssize_t
action_store(struct kobject
*kobj
, struct kobj_attribute
*attr
,
1678 const char *buf
, size_t count
)
1680 struct damon_sysfs_scheme
*scheme
= container_of(kobj
,
1681 struct damon_sysfs_scheme
, kobj
);
1682 enum damos_action action
;
1684 for (action
= 0; action
< NR_DAMOS_ACTIONS
; action
++) {
1685 if (sysfs_streq(buf
, damon_sysfs_damos_action_strs
[action
])) {
1686 scheme
->action
= action
;
1693 static ssize_t
apply_interval_us_show(struct kobject
*kobj
,
1694 struct kobj_attribute
*attr
, char *buf
)
1696 struct damon_sysfs_scheme
*scheme
= container_of(kobj
,
1697 struct damon_sysfs_scheme
, kobj
);
1699 return sysfs_emit(buf
, "%lu\n", scheme
->apply_interval_us
);
1702 static ssize_t
apply_interval_us_store(struct kobject
*kobj
,
1703 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
1705 struct damon_sysfs_scheme
*scheme
= container_of(kobj
,
1706 struct damon_sysfs_scheme
, kobj
);
1707 int err
= kstrtoul(buf
, 0, &scheme
->apply_interval_us
);
1709 return err
? err
: count
;
1712 static ssize_t
target_nid_show(struct kobject
*kobj
,
1713 struct kobj_attribute
*attr
, char *buf
)
1715 struct damon_sysfs_scheme
*scheme
= container_of(kobj
,
1716 struct damon_sysfs_scheme
, kobj
);
1718 return sysfs_emit(buf
, "%d\n", scheme
->target_nid
);
1721 static ssize_t
target_nid_store(struct kobject
*kobj
,
1722 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
1724 struct damon_sysfs_scheme
*scheme
= container_of(kobj
,
1725 struct damon_sysfs_scheme
, kobj
);
1728 /* TODO: error handling for target_nid range. */
1729 err
= kstrtoint(buf
, 0, &scheme
->target_nid
);
1731 return err
? err
: count
;
1734 static void damon_sysfs_scheme_release(struct kobject
*kobj
)
1736 kfree(container_of(kobj
, struct damon_sysfs_scheme
, kobj
));
1739 static struct kobj_attribute damon_sysfs_scheme_action_attr
=
1740 __ATTR_RW_MODE(action
, 0600);
1742 static struct kobj_attribute damon_sysfs_scheme_apply_interval_us_attr
=
1743 __ATTR_RW_MODE(apply_interval_us
, 0600);
1745 static struct kobj_attribute damon_sysfs_scheme_target_nid_attr
=
1746 __ATTR_RW_MODE(target_nid
, 0600);
1748 static struct attribute
*damon_sysfs_scheme_attrs
[] = {
1749 &damon_sysfs_scheme_action_attr
.attr
,
1750 &damon_sysfs_scheme_apply_interval_us_attr
.attr
,
1751 &damon_sysfs_scheme_target_nid_attr
.attr
,
1754 ATTRIBUTE_GROUPS(damon_sysfs_scheme
);
1756 static const struct kobj_type damon_sysfs_scheme_ktype
= {
1757 .release
= damon_sysfs_scheme_release
,
1758 .sysfs_ops
= &kobj_sysfs_ops
,
1759 .default_groups
= damon_sysfs_scheme_groups
,
1766 struct damon_sysfs_schemes
*damon_sysfs_schemes_alloc(void)
1768 return kzalloc(sizeof(struct damon_sysfs_schemes
), GFP_KERNEL
);
1771 void damon_sysfs_schemes_rm_dirs(struct damon_sysfs_schemes
*schemes
)
1773 struct damon_sysfs_scheme
**schemes_arr
= schemes
->schemes_arr
;
1776 for (i
= 0; i
< schemes
->nr
; i
++) {
1777 damon_sysfs_scheme_rm_dirs(schemes_arr
[i
]);
1778 kobject_put(&schemes_arr
[i
]->kobj
);
1782 schemes
->schemes_arr
= NULL
;
1785 static int damon_sysfs_schemes_add_dirs(struct damon_sysfs_schemes
*schemes
,
1788 struct damon_sysfs_scheme
**schemes_arr
, *scheme
;
1791 damon_sysfs_schemes_rm_dirs(schemes
);
1795 schemes_arr
= kmalloc_array(nr_schemes
, sizeof(*schemes_arr
),
1796 GFP_KERNEL
| __GFP_NOWARN
);
1799 schemes
->schemes_arr
= schemes_arr
;
1801 for (i
= 0; i
< nr_schemes
; i
++) {
1803 * apply_interval_us as 0 means same to aggregation interval
1804 * (same to before-apply_interval behavior)
1806 scheme
= damon_sysfs_scheme_alloc(DAMOS_STAT
, 0);
1808 damon_sysfs_schemes_rm_dirs(schemes
);
1812 err
= kobject_init_and_add(&scheme
->kobj
,
1813 &damon_sysfs_scheme_ktype
, &schemes
->kobj
,
1817 err
= damon_sysfs_scheme_add_dirs(scheme
);
1821 schemes_arr
[i
] = scheme
;
1827 damon_sysfs_schemes_rm_dirs(schemes
);
1828 kobject_put(&scheme
->kobj
);
1832 static ssize_t
nr_schemes_show(struct kobject
*kobj
,
1833 struct kobj_attribute
*attr
, char *buf
)
1835 struct damon_sysfs_schemes
*schemes
= container_of(kobj
,
1836 struct damon_sysfs_schemes
, kobj
);
1838 return sysfs_emit(buf
, "%d\n", schemes
->nr
);
1841 static ssize_t
nr_schemes_store(struct kobject
*kobj
,
1842 struct kobj_attribute
*attr
, const char *buf
, size_t count
)
1844 struct damon_sysfs_schemes
*schemes
;
1845 int nr
, err
= kstrtoint(buf
, 0, &nr
);
1852 schemes
= container_of(kobj
, struct damon_sysfs_schemes
, kobj
);
1854 if (!mutex_trylock(&damon_sysfs_lock
))
1856 err
= damon_sysfs_schemes_add_dirs(schemes
, nr
);
1857 mutex_unlock(&damon_sysfs_lock
);
1863 static void damon_sysfs_schemes_release(struct kobject
*kobj
)
1865 kfree(container_of(kobj
, struct damon_sysfs_schemes
, kobj
));
1868 static struct kobj_attribute damon_sysfs_schemes_nr_attr
=
1869 __ATTR_RW_MODE(nr_schemes
, 0600);
1871 static struct attribute
*damon_sysfs_schemes_attrs
[] = {
1872 &damon_sysfs_schemes_nr_attr
.attr
,
1875 ATTRIBUTE_GROUPS(damon_sysfs_schemes
);
1877 const struct kobj_type damon_sysfs_schemes_ktype
= {
1878 .release
= damon_sysfs_schemes_release
,
1879 .sysfs_ops
= &kobj_sysfs_ops
,
1880 .default_groups
= damon_sysfs_schemes_groups
,
1883 static bool damon_sysfs_memcg_path_eq(struct mem_cgroup
*memcg
,
1884 char *memcg_path_buf
, char *path
)
1887 cgroup_path(memcg
->css
.cgroup
, memcg_path_buf
, PATH_MAX
);
1888 if (sysfs_streq(memcg_path_buf
, path
))
1890 #endif /* CONFIG_MEMCG */
1894 static int damon_sysfs_memcg_path_to_id(char *memcg_path
, unsigned short *id
)
1896 struct mem_cgroup
*memcg
;
1903 path
= kmalloc(sizeof(*path
) * PATH_MAX
, GFP_KERNEL
);
1907 for (memcg
= mem_cgroup_iter(NULL
, NULL
, NULL
); memcg
;
1908 memcg
= mem_cgroup_iter(NULL
, memcg
, NULL
)) {
1909 /* skip removed memcg */
1910 if (!mem_cgroup_id(memcg
))
1912 if (damon_sysfs_memcg_path_eq(memcg
, path
, memcg_path
)) {
1913 *id
= mem_cgroup_id(memcg
);
1920 return found
? 0 : -EINVAL
;
1923 static int damon_sysfs_add_scheme_filters(struct damos
*scheme
,
1924 struct damon_sysfs_scheme_filters
*sysfs_filters
)
1928 for (i
= 0; i
< sysfs_filters
->nr
; i
++) {
1929 struct damon_sysfs_scheme_filter
*sysfs_filter
=
1930 sysfs_filters
->filters_arr
[i
];
1931 struct damos_filter
*filter
=
1932 damos_new_filter(sysfs_filter
->type
,
1933 sysfs_filter
->matching
,
1934 sysfs_filter
->allow
);
1939 if (filter
->type
== DAMOS_FILTER_TYPE_MEMCG
) {
1940 err
= damon_sysfs_memcg_path_to_id(
1941 sysfs_filter
->memcg_path
,
1944 damos_destroy_filter(filter
);
1947 } else if (filter
->type
== DAMOS_FILTER_TYPE_ADDR
) {
1948 if (sysfs_filter
->addr_range
.end
<
1949 sysfs_filter
->addr_range
.start
) {
1950 damos_destroy_filter(filter
);
1953 filter
->addr_range
= sysfs_filter
->addr_range
;
1954 } else if (filter
->type
== DAMOS_FILTER_TYPE_TARGET
) {
1955 filter
->target_idx
= sysfs_filter
->target_idx
;
1958 damos_add_filter(scheme
, filter
);
1963 static int damos_sysfs_add_quota_score(
1964 struct damos_sysfs_quota_goals
*sysfs_goals
,
1965 struct damos_quota
*quota
)
1967 struct damos_quota_goal
*goal
;
1970 for (i
= 0; i
< sysfs_goals
->nr
; i
++) {
1971 struct damos_sysfs_quota_goal
*sysfs_goal
=
1972 sysfs_goals
->goals_arr
[i
];
1974 if (!sysfs_goal
->target_value
)
1977 goal
= damos_new_quota_goal(sysfs_goal
->metric
,
1978 sysfs_goal
->target_value
);
1981 if (sysfs_goal
->metric
== DAMOS_QUOTA_USER_INPUT
)
1982 goal
->current_value
= sysfs_goal
->current_value
;
1983 damos_add_quota_goal(quota
, goal
);
1988 int damos_sysfs_set_quota_scores(struct damon_sysfs_schemes
*sysfs_schemes
,
1989 struct damon_ctx
*ctx
)
1991 struct damos
*scheme
;
1992 struct damos_quota quota
= {};
1995 INIT_LIST_HEAD("a
.goals
);
1996 damon_for_each_scheme(scheme
, ctx
) {
1997 struct damon_sysfs_scheme
*sysfs_scheme
;
1998 struct damos_quota_goal
*g
, *g_next
;
2001 /* user could have removed the scheme sysfs dir */
2002 if (i
>= sysfs_schemes
->nr
)
2005 sysfs_scheme
= sysfs_schemes
->schemes_arr
[i
];
2006 err
= damos_sysfs_add_quota_score(sysfs_scheme
->quotas
->goals
,
2009 damos_for_each_quota_goal_safe(g
, g_next
, "a
)
2010 damos_destroy_quota_goal(g
);
2013 err
= damos_commit_quota_goals(&scheme
->quota
, "a
);
2014 damos_for_each_quota_goal_safe(g
, g_next
, "a
)
2015 damos_destroy_quota_goal(g
);
2023 void damos_sysfs_update_effective_quotas(
2024 struct damon_sysfs_schemes
*sysfs_schemes
,
2025 struct damon_ctx
*ctx
)
2027 struct damos
*scheme
;
2028 int schemes_idx
= 0;
2030 damon_for_each_scheme(scheme
, ctx
) {
2031 struct damon_sysfs_quotas
*sysfs_quotas
;
2033 /* user could have removed the scheme sysfs dir */
2034 if (schemes_idx
>= sysfs_schemes
->nr
)
2038 sysfs_schemes
->schemes_arr
[schemes_idx
++]->quotas
;
2039 sysfs_quotas
->effective_sz
= scheme
->quota
.esz
;
2043 static struct damos
*damon_sysfs_mk_scheme(
2044 struct damon_sysfs_scheme
*sysfs_scheme
)
2046 struct damon_sysfs_access_pattern
*access_pattern
=
2047 sysfs_scheme
->access_pattern
;
2048 struct damon_sysfs_quotas
*sysfs_quotas
= sysfs_scheme
->quotas
;
2049 struct damon_sysfs_weights
*sysfs_weights
= sysfs_quotas
->weights
;
2050 struct damon_sysfs_watermarks
*sysfs_wmarks
= sysfs_scheme
->watermarks
;
2051 struct damon_sysfs_scheme_filters
*sysfs_filters
=
2052 sysfs_scheme
->filters
;
2053 struct damos
*scheme
;
2056 struct damos_access_pattern pattern
= {
2057 .min_sz_region
= access_pattern
->sz
->min
,
2058 .max_sz_region
= access_pattern
->sz
->max
,
2059 .min_nr_accesses
= access_pattern
->nr_accesses
->min
,
2060 .max_nr_accesses
= access_pattern
->nr_accesses
->max
,
2061 .min_age_region
= access_pattern
->age
->min
,
2062 .max_age_region
= access_pattern
->age
->max
,
2064 struct damos_quota quota
= {
2065 .ms
= sysfs_quotas
->ms
,
2066 .sz
= sysfs_quotas
->sz
,
2067 .reset_interval
= sysfs_quotas
->reset_interval_ms
,
2068 .weight_sz
= sysfs_weights
->sz
,
2069 .weight_nr_accesses
= sysfs_weights
->nr_accesses
,
2070 .weight_age
= sysfs_weights
->age
,
2072 struct damos_watermarks wmarks
= {
2073 .metric
= sysfs_wmarks
->metric
,
2074 .interval
= sysfs_wmarks
->interval_us
,
2075 .high
= sysfs_wmarks
->high
,
2076 .mid
= sysfs_wmarks
->mid
,
2077 .low
= sysfs_wmarks
->low
,
2080 scheme
= damon_new_scheme(&pattern
, sysfs_scheme
->action
,
2081 sysfs_scheme
->apply_interval_us
, "a
, &wmarks
,
2082 sysfs_scheme
->target_nid
);
2086 err
= damos_sysfs_add_quota_score(sysfs_quotas
->goals
, &scheme
->quota
);
2088 damon_destroy_scheme(scheme
);
2092 err
= damon_sysfs_add_scheme_filters(scheme
, sysfs_filters
);
2094 damon_destroy_scheme(scheme
);
2100 int damon_sysfs_add_schemes(struct damon_ctx
*ctx
,
2101 struct damon_sysfs_schemes
*sysfs_schemes
)
2105 for (i
= 0; i
< sysfs_schemes
->nr
; i
++) {
2106 struct damos
*scheme
, *next
;
2108 scheme
= damon_sysfs_mk_scheme(sysfs_schemes
->schemes_arr
[i
]);
2110 damon_for_each_scheme_safe(scheme
, next
, ctx
)
2111 damon_destroy_scheme(scheme
);
2114 damon_add_scheme(ctx
, scheme
);
2119 void damon_sysfs_schemes_update_stats(
2120 struct damon_sysfs_schemes
*sysfs_schemes
,
2121 struct damon_ctx
*ctx
)
2123 struct damos
*scheme
;
2124 int schemes_idx
= 0;
2126 damon_for_each_scheme(scheme
, ctx
) {
2127 struct damon_sysfs_stats
*sysfs_stats
;
2129 /* user could have removed the scheme sysfs dir */
2130 if (schemes_idx
>= sysfs_schemes
->nr
)
2133 sysfs_stats
= sysfs_schemes
->schemes_arr
[schemes_idx
++]->stats
;
2134 sysfs_stats
->nr_tried
= scheme
->stat
.nr_tried
;
2135 sysfs_stats
->sz_tried
= scheme
->stat
.sz_tried
;
2136 sysfs_stats
->nr_applied
= scheme
->stat
.nr_applied
;
2137 sysfs_stats
->sz_applied
= scheme
->stat
.sz_applied
;
2138 sysfs_stats
->sz_ops_filter_passed
=
2139 scheme
->stat
.sz_ops_filter_passed
;
2140 sysfs_stats
->qt_exceeds
= scheme
->stat
.qt_exceeds
;
2145 * damos_sysfs_populate_region_dir() - Populate a schemes tried region dir.
2146 * @sysfs_schemes: Schemes directory to populate regions directory.
2147 * @ctx: Corresponding DAMON context.
2148 * @t: DAMON target of @r.
2149 * @r: DAMON region to populate the directory for.
2150 * @s: Corresponding scheme.
2151 * @total_bytes_only: Whether the request is for bytes update only.
2152 * @sz_filter_passed: Bytes of @r that passed filters of @s.
2154 * Called from DAMOS walk callback while holding damon_sysfs_lock.
2156 void damos_sysfs_populate_region_dir(struct damon_sysfs_schemes
*sysfs_schemes
,
2157 struct damon_ctx
*ctx
, struct damon_target
*t
,
2158 struct damon_region
*r
, struct damos
*s
, bool total_bytes_only
,
2159 unsigned long sz_filter_passed
)
2161 struct damos
*scheme
;
2162 struct damon_sysfs_scheme_regions
*sysfs_regions
;
2163 struct damon_sysfs_scheme_region
*region
;
2164 int schemes_idx
= 0;
2166 damon_for_each_scheme(scheme
, ctx
) {
2172 /* user could have removed the scheme sysfs dir */
2173 if (schemes_idx
>= sysfs_schemes
->nr
)
2176 sysfs_regions
= sysfs_schemes
->schemes_arr
[schemes_idx
]->tried_regions
;
2177 sysfs_regions
->total_bytes
+= r
->ar
.end
- r
->ar
.start
;
2178 if (total_bytes_only
)
2181 region
= damon_sysfs_scheme_region_alloc(r
);
2184 region
->sz_filter_passed
= sz_filter_passed
;
2185 list_add_tail(®ion
->list
, &sysfs_regions
->regions_list
);
2186 sysfs_regions
->nr_regions
++;
2187 if (kobject_init_and_add(®ion
->kobj
,
2188 &damon_sysfs_scheme_region_ktype
,
2189 &sysfs_regions
->kobj
, "%d",
2190 sysfs_regions
->nr_regions
++)) {
2191 kobject_put(®ion
->kobj
);
2195 /* Called from damon_sysfs_cmd_request_callback under damon_sysfs_lock */
2196 int damon_sysfs_schemes_clear_regions(
2197 struct damon_sysfs_schemes
*sysfs_schemes
)
2201 for (i
= 0; i
< sysfs_schemes
->nr
; i
++) {
2202 struct damon_sysfs_scheme
*sysfs_scheme
;
2204 sysfs_scheme
= sysfs_schemes
->schemes_arr
[i
];
2205 damon_sysfs_scheme_regions_rm_dirs(
2206 sysfs_scheme
->tried_regions
);
2207 sysfs_scheme
->tried_regions
->total_bytes
= 0;