1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Data Access Monitor
4 *
5 * Author: SeongJae Park <sj@kernel.org>
6 */
7
8 #define pr_fmt(fmt) "damon: " fmt
9
10 #include <linux/damon.h>
11 #include <linux/delay.h>
12 #include <linux/kthread.h>
13 #include <linux/memcontrol.h>
14 #include <linux/mm.h>
15 #include <linux/psi.h>
16 #include <linux/slab.h>
17 #include <linux/string.h>
18 #include <linux/string_choices.h>
19
20 #define CREATE_TRACE_POINTS
21 #include <trace/events/damon.h>
22
23 static DEFINE_MUTEX(damon_lock);
24 static int nr_running_ctxs;
25 static bool running_exclusive_ctxs;
26
27 static DEFINE_MUTEX(damon_ops_lock);
28 static struct damon_operations damon_registered_ops[NR_DAMON_OPS];
29
30 static struct kmem_cache *damon_region_cache __ro_after_init;
31
32 /* Should be called under damon_ops_lock with id smaller than NR_DAMON_OPS */
__damon_is_registered_ops(enum damon_ops_id id)33 static bool __damon_is_registered_ops(enum damon_ops_id id)
34 {
35 struct damon_operations empty_ops = {};
36
37 if (!memcmp(&empty_ops, &damon_registered_ops[id], sizeof(empty_ops)))
38 return false;
39 return true;
40 }
41
42 /**
43 * damon_is_registered_ops() - Check if a given damon_operations is registered.
44 * @id: Id of the damon_operations to check if registered.
45 *
46 * Return: true if the ops is set, false otherwise.
47 */
damon_is_registered_ops(enum damon_ops_id id)48 bool damon_is_registered_ops(enum damon_ops_id id)
49 {
50 bool registered;
51
52 if (id >= NR_DAMON_OPS)
53 return false;
54 mutex_lock(&damon_ops_lock);
55 registered = __damon_is_registered_ops(id);
56 mutex_unlock(&damon_ops_lock);
57 return registered;
58 }
59
60 /**
61 * damon_register_ops() - Register a monitoring operations set to DAMON.
62 * @ops: monitoring operations set to register.
63 *
64 * This function registers a monitoring operations set of valid &struct
65 * damon_operations->id so that others can find and use them later.
66 *
67 * Return: 0 on success, negative error code otherwise.
68 */
damon_register_ops(struct damon_operations * ops)69 int damon_register_ops(struct damon_operations *ops)
70 {
71 int err = 0;
72
73 if (ops->id >= NR_DAMON_OPS)
74 return -EINVAL;
75
76 mutex_lock(&damon_ops_lock);
77 /* Fail for already registered ops */
78 if (__damon_is_registered_ops(ops->id))
79 err = -EINVAL;
80 else
81 damon_registered_ops[ops->id] = *ops;
82 mutex_unlock(&damon_ops_lock);
83 return err;
84 }
85
86 /**
87 * damon_select_ops() - Select a monitoring operations to use with the context.
88 * @ctx: monitoring context to use the operations.
89 * @id: id of the registered monitoring operations to select.
90 *
91 * This function finds registered monitoring operations set of @id and make
92 * @ctx to use it.
93 *
94 * Return: 0 on success, negative error code otherwise.
95 */
damon_select_ops(struct damon_ctx * ctx,enum damon_ops_id id)96 int damon_select_ops(struct damon_ctx *ctx, enum damon_ops_id id)
97 {
98 int err = 0;
99
100 if (id >= NR_DAMON_OPS)
101 return -EINVAL;
102
103 mutex_lock(&damon_ops_lock);
104 if (!__damon_is_registered_ops(id))
105 err = -EINVAL;
106 else
107 ctx->ops = damon_registered_ops[id];
108 mutex_unlock(&damon_ops_lock);
109 return err;
110 }
111
112 #ifdef CONFIG_DAMON_DEBUG_SANITY
damon_verify_new_region(unsigned long start,unsigned long end)113 static void damon_verify_new_region(unsigned long start, unsigned long end)
114 {
115 WARN_ONCE(start >= end, "start %lu >= end %lu\n", start, end);
116 }
117 #else
damon_verify_new_region(unsigned long start,unsigned long end)118 static void damon_verify_new_region(unsigned long start, unsigned long end)
119 {
120 }
121 #endif
122
123 /*
124 * Construct a damon_region struct
125 *
126 * Returns the pointer to the new struct if success, or NULL otherwise
127 */
damon_new_region(unsigned long start,unsigned long end)128 struct damon_region *damon_new_region(unsigned long start, unsigned long end)
129 {
130 struct damon_region *region;
131
132 damon_verify_new_region(start, end);
133 region = kmem_cache_alloc(damon_region_cache, GFP_KERNEL);
134 if (!region)
135 return NULL;
136
137 region->ar.start = start;
138 region->ar.end = end;
139 region->nr_accesses = 0;
140 region->nr_accesses_bp = 0;
141 INIT_LIST_HEAD(®ion->list);
142
143 region->age = 0;
144 region->last_nr_accesses = 0;
145
146 return region;
147 }
148
damon_add_region(struct damon_region * r,struct damon_target * t)149 void damon_add_region(struct damon_region *r, struct damon_target *t)
150 {
151 list_add_tail(&r->list, &t->regions_list);
152 t->nr_regions++;
153 }
154
155 #ifdef CONFIG_DAMON_DEBUG_SANITY
damon_verify_del_region(struct damon_target * t)156 static void damon_verify_del_region(struct damon_target *t)
157 {
158 WARN_ONCE(t->nr_regions == 0, "t->nr_regions == 0\n");
159 }
160 #else
damon_verify_del_region(struct damon_target * t)161 static void damon_verify_del_region(struct damon_target *t)
162 {
163 }
164 #endif
165
damon_del_region(struct damon_region * r,struct damon_target * t)166 static void damon_del_region(struct damon_region *r, struct damon_target *t)
167 {
168 damon_verify_del_region(t);
169
170 list_del(&r->list);
171 t->nr_regions--;
172 }
173
damon_free_region(struct damon_region * r)174 static void damon_free_region(struct damon_region *r)
175 {
176 kmem_cache_free(damon_region_cache, r);
177 }
178
damon_destroy_region(struct damon_region * r,struct damon_target * t)179 void damon_destroy_region(struct damon_region *r, struct damon_target *t)
180 {
181 damon_del_region(r, t);
182 damon_free_region(r);
183 }
184
damon_is_last_region(struct damon_region * r,struct damon_target * t)185 static bool damon_is_last_region(struct damon_region *r,
186 struct damon_target *t)
187 {
188 return list_is_last(&r->list, &t->regions_list);
189 }
190
191 /*
192 * Check whether a region is intersecting an address range
193 *
194 * Returns true if it is.
195 */
damon_intersect(struct damon_region * r,struct damon_addr_range * re)196 static bool damon_intersect(struct damon_region *r,
197 struct damon_addr_range *re)
198 {
199 return !(r->ar.end <= re->start || re->end <= r->ar.start);
200 }
201
202 /*
203 * Fill holes in regions with new regions.
204 */
damon_fill_regions_holes(struct damon_region * first,struct damon_region * last,struct damon_target * t)205 static int damon_fill_regions_holes(struct damon_region *first,
206 struct damon_region *last, struct damon_target *t)
207 {
208 struct damon_region *r = first;
209
210 damon_for_each_region_from(r, t) {
211 struct damon_region *next, *newr;
212
213 if (r == last)
214 break;
215 next = damon_next_region(r);
216 if (r->ar.end != next->ar.start) {
217 newr = damon_new_region(r->ar.end, next->ar.start);
218 if (!newr)
219 return -ENOMEM;
220 damon_insert_region(newr, r, next, t);
221 }
222 }
223 return 0;
224 }
225
226 /*
227 * damon_set_regions() - Set regions of a target for given address ranges.
228 * @t: the given target.
229 * @ranges: array of new monitoring target ranges.
230 * @nr_ranges: length of @ranges.
231 * @min_region_sz: minimum region size.
232 *
233 * This function adds new regions to, or modify existing regions of a
234 * monitoring target to fit in specific ranges.
235 *
236 * Return: 0 if success, or negative error code otherwise.
237 */
damon_set_regions(struct damon_target * t,struct damon_addr_range * ranges,unsigned int nr_ranges,unsigned long min_region_sz)238 int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges,
239 unsigned int nr_ranges, unsigned long min_region_sz)
240 {
241 struct damon_region *r, *next;
242 unsigned int i;
243 int err;
244
245 /* Remove regions which are not in the new ranges */
246 damon_for_each_region_safe(r, next, t) {
247 for (i = 0; i < nr_ranges; i++) {
248 if (damon_intersect(r, &ranges[i]))
249 break;
250 }
251 if (i == nr_ranges)
252 damon_destroy_region(r, t);
253 }
254
255 r = damon_first_region(t);
256 /* Add new regions or resize existing regions to fit in the ranges */
257 for (i = 0; i < nr_ranges; i++) {
258 struct damon_region *first = NULL, *last, *newr;
259 struct damon_addr_range *range;
260
261 range = &ranges[i];
262 /* Get the first/last regions intersecting with the range */
263 damon_for_each_region_from(r, t) {
264 if (damon_intersect(r, range)) {
265 if (!first)
266 first = r;
267 last = r;
268 }
269 if (r->ar.start >= range->end)
270 break;
271 }
272 if (!first) {
273 /* no region intersects with this range */
274 newr = damon_new_region(
275 ALIGN_DOWN(range->start,
276 min_region_sz),
277 ALIGN(range->end, min_region_sz));
278 if (!newr)
279 return -ENOMEM;
280 damon_insert_region(newr, damon_prev_region(r), r, t);
281 } else {
282 /* resize intersecting regions to fit in this range */
283 first->ar.start = ALIGN_DOWN(range->start,
284 min_region_sz);
285 last->ar.end = ALIGN(range->end, min_region_sz);
286
287 /* fill possible holes in the range */
288 err = damon_fill_regions_holes(first, last, t);
289 if (err)
290 return err;
291 }
292 }
293 return 0;
294 }
295
damos_new_filter(enum damos_filter_type type,bool matching,bool allow)296 struct damos_filter *damos_new_filter(enum damos_filter_type type,
297 bool matching, bool allow)
298 {
299 struct damos_filter *filter;
300
301 filter = kmalloc_obj(*filter);
302 if (!filter)
303 return NULL;
304 filter->type = type;
305 filter->matching = matching;
306 filter->allow = allow;
307 INIT_LIST_HEAD(&filter->list);
308 return filter;
309 }
310
311 /**
312 * damos_filter_for_ops() - Return if the filter is ops-handled one.
313 * @type: type of the filter.
314 *
315 * Return: true if the filter of @type needs to be handled by ops layer, false
316 * otherwise.
317 */
damos_filter_for_ops(enum damos_filter_type type)318 bool damos_filter_for_ops(enum damos_filter_type type)
319 {
320 switch (type) {
321 case DAMOS_FILTER_TYPE_ADDR:
322 case DAMOS_FILTER_TYPE_TARGET:
323 return false;
324 default:
325 break;
326 }
327 return true;
328 }
329
damos_add_filter(struct damos * s,struct damos_filter * f)330 void damos_add_filter(struct damos *s, struct damos_filter *f)
331 {
332 if (damos_filter_for_ops(f->type))
333 list_add_tail(&f->list, &s->ops_filters);
334 else
335 list_add_tail(&f->list, &s->core_filters);
336 }
337
damos_del_filter(struct damos_filter * f)338 static void damos_del_filter(struct damos_filter *f)
339 {
340 list_del(&f->list);
341 }
342
damos_free_filter(struct damos_filter * f)343 static void damos_free_filter(struct damos_filter *f)
344 {
345 kfree(f);
346 }
347
damos_destroy_filter(struct damos_filter * f)348 void damos_destroy_filter(struct damos_filter *f)
349 {
350 damos_del_filter(f);
351 damos_free_filter(f);
352 }
353
damos_new_quota_goal(enum damos_quota_goal_metric metric,unsigned long target_value)354 struct damos_quota_goal *damos_new_quota_goal(
355 enum damos_quota_goal_metric metric,
356 unsigned long target_value)
357 {
358 struct damos_quota_goal *goal;
359
360 goal = kmalloc_obj(*goal);
361 if (!goal)
362 return NULL;
363 goal->metric = metric;
364 goal->target_value = target_value;
365 INIT_LIST_HEAD(&goal->list);
366 return goal;
367 }
368
damos_add_quota_goal(struct damos_quota * q,struct damos_quota_goal * g)369 void damos_add_quota_goal(struct damos_quota *q, struct damos_quota_goal *g)
370 {
371 list_add_tail(&g->list, &q->goals);
372 }
373
damos_del_quota_goal(struct damos_quota_goal * g)374 static void damos_del_quota_goal(struct damos_quota_goal *g)
375 {
376 list_del(&g->list);
377 }
378
damos_free_quota_goal(struct damos_quota_goal * g)379 static void damos_free_quota_goal(struct damos_quota_goal *g)
380 {
381 kfree(g);
382 }
383
damos_destroy_quota_goal(struct damos_quota_goal * g)384 void damos_destroy_quota_goal(struct damos_quota_goal *g)
385 {
386 damos_del_quota_goal(g);
387 damos_free_quota_goal(g);
388 }
389
damos_quota_goals_empty(struct damos_quota * q)390 static bool damos_quota_goals_empty(struct damos_quota *q)
391 {
392 return list_empty(&q->goals);
393 }
394
395 /* initialize fields of @quota that normally API users wouldn't set */
damos_quota_init(struct damos_quota * quota)396 static struct damos_quota *damos_quota_init(struct damos_quota *quota)
397 {
398 quota->esz = 0;
399 quota->total_charged_sz = 0;
400 quota->total_charged_ns = 0;
401 quota->charged_sz = 0;
402 quota->charged_from = 0;
403 quota->charge_target_from = NULL;
404 quota->charge_addr_from = 0;
405 quota->esz_bp = 0;
406 return quota;
407 }
408
damon_new_scheme(struct damos_access_pattern * pattern,enum damos_action action,unsigned long apply_interval_us,struct damos_quota * quota,struct damos_watermarks * wmarks,int target_nid)409 struct damos *damon_new_scheme(struct damos_access_pattern *pattern,
410 enum damos_action action,
411 unsigned long apply_interval_us,
412 struct damos_quota *quota,
413 struct damos_watermarks *wmarks,
414 int target_nid)
415 {
416 struct damos *scheme;
417
418 scheme = kmalloc_obj(*scheme);
419 if (!scheme)
420 return NULL;
421 scheme->pattern = *pattern;
422 scheme->action = action;
423 scheme->apply_interval_us = apply_interval_us;
424 /*
425 * next_apply_sis will be set when kdamond starts. While kdamond is
426 * running, it will also updated when it is added to the DAMON context,
427 * or damon_attrs are updated.
428 */
429 scheme->next_apply_sis = 0;
430 scheme->walk_completed = false;
431 INIT_LIST_HEAD(&scheme->core_filters);
432 INIT_LIST_HEAD(&scheme->ops_filters);
433 scheme->stat = (struct damos_stat){};
434 scheme->max_nr_snapshots = 0;
435 INIT_LIST_HEAD(&scheme->list);
436
437 scheme->quota = *(damos_quota_init(quota));
438 /* quota.goals should be separately set by caller */
439 INIT_LIST_HEAD(&scheme->quota.goals);
440
441 scheme->wmarks = *wmarks;
442 scheme->wmarks.activated = true;
443
444 scheme->migrate_dests = (struct damos_migrate_dests){};
445 scheme->target_nid = target_nid;
446
447 return scheme;
448 }
449
damos_set_next_apply_sis(struct damos * s,struct damon_ctx * ctx)450 static void damos_set_next_apply_sis(struct damos *s, struct damon_ctx *ctx)
451 {
452 unsigned long sample_interval = ctx->attrs.sample_interval ?
453 ctx->attrs.sample_interval : 1;
454 unsigned long apply_interval = s->apply_interval_us ?
455 s->apply_interval_us : ctx->attrs.aggr_interval;
456
457 s->next_apply_sis = ctx->passed_sample_intervals +
458 apply_interval / sample_interval;
459 }
460
damon_add_scheme(struct damon_ctx * ctx,struct damos * s)461 void damon_add_scheme(struct damon_ctx *ctx, struct damos *s)
462 {
463 list_add_tail(&s->list, &ctx->schemes);
464 damos_set_next_apply_sis(s, ctx);
465 }
466
damon_del_scheme(struct damos * s)467 static void damon_del_scheme(struct damos *s)
468 {
469 list_del(&s->list);
470 }
471
damon_free_scheme(struct damos * s)472 static void damon_free_scheme(struct damos *s)
473 {
474 kfree(s);
475 }
476
damon_destroy_scheme(struct damos * s)477 void damon_destroy_scheme(struct damos *s)
478 {
479 struct damos_quota_goal *g, *g_next;
480 struct damos_filter *f, *next;
481
482 damos_for_each_quota_goal_safe(g, g_next, &s->quota)
483 damos_destroy_quota_goal(g);
484
485 damos_for_each_core_filter_safe(f, next, s)
486 damos_destroy_filter(f);
487
488 damos_for_each_ops_filter_safe(f, next, s)
489 damos_destroy_filter(f);
490
491 kfree(s->migrate_dests.node_id_arr);
492 kfree(s->migrate_dests.weight_arr);
493 damon_del_scheme(s);
494 damon_free_scheme(s);
495 }
496
497 /*
498 * Construct a damon_target struct
499 *
500 * Returns the pointer to the new struct if success, or NULL otherwise
501 */
damon_new_target(void)502 struct damon_target *damon_new_target(void)
503 {
504 struct damon_target *t;
505
506 t = kmalloc_obj(*t);
507 if (!t)
508 return NULL;
509
510 t->pid = NULL;
511 t->nr_regions = 0;
512 INIT_LIST_HEAD(&t->regions_list);
513 INIT_LIST_HEAD(&t->list);
514 t->obsolete = false;
515
516 return t;
517 }
518
damon_add_target(struct damon_ctx * ctx,struct damon_target * t)519 void damon_add_target(struct damon_ctx *ctx, struct damon_target *t)
520 {
521 list_add_tail(&t->list, &ctx->adaptive_targets);
522 }
523
damon_targets_empty(struct damon_ctx * ctx)524 bool damon_targets_empty(struct damon_ctx *ctx)
525 {
526 return list_empty(&ctx->adaptive_targets);
527 }
528
damon_del_target(struct damon_target * t)529 static void damon_del_target(struct damon_target *t)
530 {
531 list_del(&t->list);
532 }
533
damon_free_target(struct damon_target * t)534 void damon_free_target(struct damon_target *t)
535 {
536 struct damon_region *r, *next;
537
538 damon_for_each_region_safe(r, next, t)
539 damon_free_region(r);
540 kfree(t);
541 }
542
damon_destroy_target(struct damon_target * t,struct damon_ctx * ctx)543 void damon_destroy_target(struct damon_target *t, struct damon_ctx *ctx)
544 {
545
546 if (ctx && ctx->ops.cleanup_target)
547 ctx->ops.cleanup_target(t);
548
549 damon_del_target(t);
550 damon_free_target(t);
551 }
552
553 #ifdef CONFIG_DAMON_DEBUG_SANITY
damon_verify_nr_regions(struct damon_target * t)554 static void damon_verify_nr_regions(struct damon_target *t)
555 {
556 struct damon_region *r;
557 unsigned int count = 0;
558
559 damon_for_each_region(r, t)
560 count++;
561 WARN_ONCE(count != t->nr_regions, "t->nr_regions (%u) != count (%u)\n",
562 t->nr_regions, count);
563 }
564 #else
damon_verify_nr_regions(struct damon_target * t)565 static void damon_verify_nr_regions(struct damon_target *t)
566 {
567 }
568 #endif
569
damon_nr_regions(struct damon_target * t)570 unsigned int damon_nr_regions(struct damon_target *t)
571 {
572 damon_verify_nr_regions(t);
573
574 return t->nr_regions;
575 }
576
damon_new_ctx(void)577 struct damon_ctx *damon_new_ctx(void)
578 {
579 struct damon_ctx *ctx;
580
581 ctx = kzalloc_obj(*ctx);
582 if (!ctx)
583 return NULL;
584
585 init_completion(&ctx->kdamond_started);
586
587 ctx->attrs.sample_interval = 5 * 1000;
588 ctx->attrs.aggr_interval = 100 * 1000;
589 ctx->attrs.ops_update_interval = 60 * 1000 * 1000;
590
591 ctx->passed_sample_intervals = 0;
592 /* These will be set from kdamond_init_ctx() */
593 ctx->next_aggregation_sis = 0;
594 ctx->next_ops_update_sis = 0;
595
596 mutex_init(&ctx->kdamond_lock);
597 INIT_LIST_HEAD(&ctx->call_controls);
598 mutex_init(&ctx->call_controls_lock);
599 mutex_init(&ctx->walk_control_lock);
600
601 ctx->attrs.min_nr_regions = 10;
602 ctx->attrs.max_nr_regions = 1000;
603
604 ctx->addr_unit = 1;
605 ctx->min_region_sz = DAMON_MIN_REGION_SZ;
606
607 INIT_LIST_HEAD(&ctx->adaptive_targets);
608 INIT_LIST_HEAD(&ctx->schemes);
609
610 return ctx;
611 }
612
damon_destroy_targets(struct damon_ctx * ctx)613 static void damon_destroy_targets(struct damon_ctx *ctx)
614 {
615 struct damon_target *t, *next_t;
616
617 damon_for_each_target_safe(t, next_t, ctx)
618 damon_destroy_target(t, ctx);
619 }
620
damon_destroy_ctx(struct damon_ctx * ctx)621 void damon_destroy_ctx(struct damon_ctx *ctx)
622 {
623 struct damos *s, *next_s;
624
625 damon_destroy_targets(ctx);
626
627 damon_for_each_scheme_safe(s, next_s, ctx)
628 damon_destroy_scheme(s);
629
630 kfree(ctx);
631 }
632
damon_attrs_equals(const struct damon_attrs * attrs1,const struct damon_attrs * attrs2)633 static bool damon_attrs_equals(const struct damon_attrs *attrs1,
634 const struct damon_attrs *attrs2)
635 {
636 const struct damon_intervals_goal *ig1 = &attrs1->intervals_goal;
637 const struct damon_intervals_goal *ig2 = &attrs2->intervals_goal;
638
639 return attrs1->sample_interval == attrs2->sample_interval &&
640 attrs1->aggr_interval == attrs2->aggr_interval &&
641 attrs1->ops_update_interval == attrs2->ops_update_interval &&
642 attrs1->min_nr_regions == attrs2->min_nr_regions &&
643 attrs1->max_nr_regions == attrs2->max_nr_regions &&
644 ig1->access_bp == ig2->access_bp &&
645 ig1->aggrs == ig2->aggrs &&
646 ig1->min_sample_us == ig2->min_sample_us &&
647 ig1->max_sample_us == ig2->max_sample_us;
648 }
649
damon_age_for_new_attrs(unsigned int age,struct damon_attrs * old_attrs,struct damon_attrs * new_attrs)650 static unsigned int damon_age_for_new_attrs(unsigned int age,
651 struct damon_attrs *old_attrs, struct damon_attrs *new_attrs)
652 {
653 return age * old_attrs->aggr_interval / new_attrs->aggr_interval;
654 }
655
656 /* convert access ratio in bp (per 10,000) to nr_accesses */
damon_accesses_bp_to_nr_accesses(unsigned int accesses_bp,struct damon_attrs * attrs)657 static unsigned int damon_accesses_bp_to_nr_accesses(
658 unsigned int accesses_bp, struct damon_attrs *attrs)
659 {
660 return accesses_bp * damon_max_nr_accesses(attrs) / 10000;
661 }
662
663 /*
664 * Convert nr_accesses to access ratio in bp (per 10,000).
665 *
666 * Callers should ensure attrs.aggr_interval is not zero, like
667 * damon_update_monitoring_results() does . Otherwise, divide-by-zero would
668 * happen.
669 */
damon_nr_accesses_to_accesses_bp(unsigned int nr_accesses,struct damon_attrs * attrs)670 static unsigned int damon_nr_accesses_to_accesses_bp(
671 unsigned int nr_accesses, struct damon_attrs *attrs)
672 {
673 return mult_frac(nr_accesses, 10000, damon_max_nr_accesses(attrs));
674 }
675
damon_nr_accesses_for_new_attrs(unsigned int nr_accesses,struct damon_attrs * old_attrs,struct damon_attrs * new_attrs)676 static unsigned int damon_nr_accesses_for_new_attrs(unsigned int nr_accesses,
677 struct damon_attrs *old_attrs, struct damon_attrs *new_attrs)
678 {
679 return damon_accesses_bp_to_nr_accesses(
680 damon_nr_accesses_to_accesses_bp(
681 nr_accesses, old_attrs),
682 new_attrs);
683 }
684
damon_update_monitoring_result(struct damon_region * r,struct damon_attrs * old_attrs,struct damon_attrs * new_attrs,bool aggregating)685 static void damon_update_monitoring_result(struct damon_region *r,
686 struct damon_attrs *old_attrs, struct damon_attrs *new_attrs,
687 bool aggregating)
688 {
689 if (!aggregating) {
690 r->nr_accesses = damon_nr_accesses_for_new_attrs(
691 r->nr_accesses, old_attrs, new_attrs);
692 r->nr_accesses_bp = r->nr_accesses * 10000;
693 } else {
694 /*
695 * if this is called in the middle of the aggregation, reset
696 * the aggregations we made so far for this aggregation
697 * interval. In other words, make the status like
698 * kdamond_reset_aggregated() is called.
699 */
700 r->last_nr_accesses = damon_nr_accesses_for_new_attrs(
701 r->last_nr_accesses, old_attrs, new_attrs);
702 r->nr_accesses_bp = r->last_nr_accesses * 10000;
703 r->nr_accesses = 0;
704 }
705 r->age = damon_age_for_new_attrs(r->age, old_attrs, new_attrs);
706 }
707
708 /*
709 * region->nr_accesses is the number of sampling intervals in the last
710 * aggregation interval that access to the region has found, and region->age is
711 * the number of aggregation intervals that its access pattern has maintained.
712 * For the reason, the real meaning of the two fields depend on current
713 * sampling interval and aggregation interval. This function updates
714 * ->nr_accesses and ->age of given damon_ctx's regions for new damon_attrs.
715 */
damon_update_monitoring_results(struct damon_ctx * ctx,struct damon_attrs * new_attrs,bool aggregating)716 static void damon_update_monitoring_results(struct damon_ctx *ctx,
717 struct damon_attrs *new_attrs, bool aggregating)
718 {
719 struct damon_attrs *old_attrs = &ctx->attrs;
720 struct damon_target *t;
721 struct damon_region *r;
722
723 /* if any interval is zero, simply forgive conversion */
724 if (!old_attrs->sample_interval || !old_attrs->aggr_interval ||
725 !new_attrs->sample_interval ||
726 !new_attrs->aggr_interval)
727 return;
728
729 damon_for_each_target(t, ctx)
730 damon_for_each_region(r, t)
731 damon_update_monitoring_result(
732 r, old_attrs, new_attrs, aggregating);
733 }
734
735 /*
736 * damon_valid_intervals_goal() - return if the intervals goal of @attrs is
737 * valid.
738 */
damon_valid_intervals_goal(struct damon_attrs * attrs)739 static bool damon_valid_intervals_goal(struct damon_attrs *attrs)
740 {
741 struct damon_intervals_goal *goal = &attrs->intervals_goal;
742
743 /* tuning is disabled */
744 if (!goal->aggrs)
745 return true;
746 if (goal->min_sample_us > goal->max_sample_us)
747 return false;
748 if (attrs->sample_interval < goal->min_sample_us ||
749 goal->max_sample_us < attrs->sample_interval)
750 return false;
751 return true;
752 }
753
754 /**
755 * damon_set_attrs() - Set attributes for the monitoring.
756 * @ctx: monitoring context
757 * @attrs: monitoring attributes
758 *
759 * This function updates monitoring results and next monitoring/damos operation
760 * schedules. Because those are periodically updated by kdamond, this should
761 * be called from a safe contexts. Such contexts include damon_ctx setup time
762 * while the kdamond is not yet started, and inside of kdamond_fn().
763 *
764 * In detail, all DAMON API callers directly call this function for initial
765 * setup of damon_ctx before calling damon_start(). Some of the API callers
766 * also indirectly call this function via damon_call() -> damon_commit() for
767 * online parameters updates. Finally, kdamond_fn() itself use this for
768 * applying auto-tuned monitoring intervals.
769 *
770 * Every time interval is in micro-seconds.
771 *
772 * Return: 0 on success, negative error code otherwise.
773 */
damon_set_attrs(struct damon_ctx * ctx,struct damon_attrs * attrs)774 int damon_set_attrs(struct damon_ctx *ctx, struct damon_attrs *attrs)
775 {
776 unsigned long sample_interval = attrs->sample_interval ?
777 attrs->sample_interval : 1;
778 struct damos *s;
779 bool aggregating = ctx->passed_sample_intervals <
780 ctx->next_aggregation_sis;
781
782 if (!damon_valid_intervals_goal(attrs))
783 return -EINVAL;
784
785 if (attrs->min_nr_regions < 3)
786 return -EINVAL;
787 if (attrs->min_nr_regions > attrs->max_nr_regions)
788 return -EINVAL;
789 if (attrs->sample_interval > attrs->aggr_interval)
790 return -EINVAL;
791
792 /* calls from core-external doesn't set this. */
793 if (!attrs->aggr_samples)
794 attrs->aggr_samples = attrs->aggr_interval / sample_interval;
795
796 ctx->next_aggregation_sis = ctx->passed_sample_intervals +
797 attrs->aggr_interval / sample_interval;
798 ctx->next_ops_update_sis = ctx->passed_sample_intervals +
799 attrs->ops_update_interval / sample_interval;
800
801 damon_update_monitoring_results(ctx, attrs, aggregating);
802 ctx->attrs = *attrs;
803
804 damon_for_each_scheme(s, ctx)
805 damos_set_next_apply_sis(s, ctx);
806
807 return 0;
808 }
809
810 /**
811 * damon_set_schemes() - Set data access monitoring based operation schemes.
812 * @ctx: monitoring context
813 * @schemes: array of the schemes
814 * @nr_schemes: number of entries in @schemes
815 *
816 * This function should not be called while the kdamond of the context is
817 * running.
818 */
damon_set_schemes(struct damon_ctx * ctx,struct damos ** schemes,ssize_t nr_schemes)819 void damon_set_schemes(struct damon_ctx *ctx, struct damos **schemes,
820 ssize_t nr_schemes)
821 {
822 struct damos *s, *next;
823 ssize_t i;
824
825 damon_for_each_scheme_safe(s, next, ctx)
826 damon_destroy_scheme(s);
827 for (i = 0; i < nr_schemes; i++)
828 damon_add_scheme(ctx, schemes[i]);
829 }
830
damos_nth_quota_goal(int n,struct damos_quota * q)831 static struct damos_quota_goal *damos_nth_quota_goal(
832 int n, struct damos_quota *q)
833 {
834 struct damos_quota_goal *goal;
835 int i = 0;
836
837 damos_for_each_quota_goal(goal, q) {
838 if (i++ == n)
839 return goal;
840 }
841 return NULL;
842 }
843
damos_commit_quota_goal_union(struct damos_quota_goal * dst,struct damos_quota_goal * src)844 static void damos_commit_quota_goal_union(
845 struct damos_quota_goal *dst, struct damos_quota_goal *src)
846 {
847 switch (dst->metric) {
848 case DAMOS_QUOTA_NODE_MEM_USED_BP:
849 case DAMOS_QUOTA_NODE_MEM_FREE_BP:
850 dst->nid = src->nid;
851 break;
852 case DAMOS_QUOTA_NODE_MEMCG_USED_BP:
853 case DAMOS_QUOTA_NODE_MEMCG_FREE_BP:
854 dst->nid = src->nid;
855 dst->memcg_id = src->memcg_id;
856 break;
857 default:
858 break;
859 }
860 }
861
damos_commit_quota_goal(struct damos_quota_goal * dst,struct damos_quota_goal * src)862 static void damos_commit_quota_goal(
863 struct damos_quota_goal *dst, struct damos_quota_goal *src)
864 {
865 dst->metric = src->metric;
866 dst->target_value = src->target_value;
867 if (dst->metric == DAMOS_QUOTA_USER_INPUT)
868 dst->current_value = src->current_value;
869 /* keep last_psi_total as is, since it will be updated in next cycle */
870 damos_commit_quota_goal_union(dst, src);
871 }
872
873 /**
874 * damos_commit_quota_goals() - Commit DAMOS quota goals to another quota.
875 * @dst: The commit destination DAMOS quota.
876 * @src: The commit source DAMOS quota.
877 *
878 * Copies user-specified parameters for quota goals from @src to @dst. Users
879 * should use this function for quota goals-level parameters update of running
880 * DAMON contexts, instead of manual in-place updates.
881 *
882 * This function should be called from parameters-update safe context, like
883 * damon_call().
884 */
damos_commit_quota_goals(struct damos_quota * dst,struct damos_quota * src)885 int damos_commit_quota_goals(struct damos_quota *dst, struct damos_quota *src)
886 {
887 struct damos_quota_goal *dst_goal, *next, *src_goal, *new_goal;
888 int i = 0, j = 0;
889
890 damos_for_each_quota_goal_safe(dst_goal, next, dst) {
891 src_goal = damos_nth_quota_goal(i++, src);
892 if (src_goal)
893 damos_commit_quota_goal(dst_goal, src_goal);
894 else
895 damos_destroy_quota_goal(dst_goal);
896 }
897 damos_for_each_quota_goal_safe(src_goal, next, src) {
898 if (j++ < i)
899 continue;
900 new_goal = damos_new_quota_goal(
901 src_goal->metric, src_goal->target_value);
902 if (!new_goal)
903 return -ENOMEM;
904 damos_commit_quota_goal(new_goal, src_goal);
905 damos_add_quota_goal(dst, new_goal);
906 }
907 return 0;
908 }
909
damos_commit_quota(struct damos_quota * dst,struct damos_quota * src)910 static int damos_commit_quota(struct damos_quota *dst, struct damos_quota *src)
911 {
912 int err;
913
914 dst->reset_interval = src->reset_interval;
915 dst->ms = src->ms;
916 dst->sz = src->sz;
917 err = damos_commit_quota_goals(dst, src);
918 if (err)
919 return err;
920 dst->goal_tuner = src->goal_tuner;
921 dst->weight_sz = src->weight_sz;
922 dst->weight_nr_accesses = src->weight_nr_accesses;
923 dst->weight_age = src->weight_age;
924 return 0;
925 }
926
damos_nth_core_filter(int n,struct damos * s)927 static struct damos_filter *damos_nth_core_filter(int n, struct damos *s)
928 {
929 struct damos_filter *filter;
930 int i = 0;
931
932 damos_for_each_core_filter(filter, s) {
933 if (i++ == n)
934 return filter;
935 }
936 return NULL;
937 }
938
damos_nth_ops_filter(int n,struct damos * s)939 static struct damos_filter *damos_nth_ops_filter(int n, struct damos *s)
940 {
941 struct damos_filter *filter;
942 int i = 0;
943
944 damos_for_each_ops_filter(filter, s) {
945 if (i++ == n)
946 return filter;
947 }
948 return NULL;
949 }
950
damos_commit_filter_arg(struct damos_filter * dst,struct damos_filter * src)951 static void damos_commit_filter_arg(
952 struct damos_filter *dst, struct damos_filter *src)
953 {
954 switch (dst->type) {
955 case DAMOS_FILTER_TYPE_MEMCG:
956 dst->memcg_id = src->memcg_id;
957 break;
958 case DAMOS_FILTER_TYPE_ADDR:
959 dst->addr_range = src->addr_range;
960 break;
961 case DAMOS_FILTER_TYPE_TARGET:
962 dst->target_idx = src->target_idx;
963 break;
964 case DAMOS_FILTER_TYPE_HUGEPAGE_SIZE:
965 dst->sz_range = src->sz_range;
966 break;
967 default:
968 break;
969 }
970 }
971
damos_commit_filter(struct damos_filter * dst,struct damos_filter * src)972 static void damos_commit_filter(
973 struct damos_filter *dst, struct damos_filter *src)
974 {
975 dst->type = src->type;
976 dst->matching = src->matching;
977 dst->allow = src->allow;
978 damos_commit_filter_arg(dst, src);
979 }
980
damos_commit_core_filters(struct damos * dst,struct damos * src)981 static int damos_commit_core_filters(struct damos *dst, struct damos *src)
982 {
983 struct damos_filter *dst_filter, *next, *src_filter, *new_filter;
984 int i = 0, j = 0;
985
986 damos_for_each_core_filter_safe(dst_filter, next, dst) {
987 src_filter = damos_nth_core_filter(i++, src);
988 if (src_filter)
989 damos_commit_filter(dst_filter, src_filter);
990 else
991 damos_destroy_filter(dst_filter);
992 }
993
994 damos_for_each_core_filter_safe(src_filter, next, src) {
995 if (j++ < i)
996 continue;
997
998 new_filter = damos_new_filter(
999 src_filter->type, src_filter->matching,
1000 src_filter->allow);
1001 if (!new_filter)
1002 return -ENOMEM;
1003 damos_commit_filter_arg(new_filter, src_filter);
1004 damos_add_filter(dst, new_filter);
1005 }
1006 return 0;
1007 }
1008
damos_commit_ops_filters(struct damos * dst,struct damos * src)1009 static int damos_commit_ops_filters(struct damos *dst, struct damos *src)
1010 {
1011 struct damos_filter *dst_filter, *next, *src_filter, *new_filter;
1012 int i = 0, j = 0;
1013
1014 damos_for_each_ops_filter_safe(dst_filter, next, dst) {
1015 src_filter = damos_nth_ops_filter(i++, src);
1016 if (src_filter)
1017 damos_commit_filter(dst_filter, src_filter);
1018 else
1019 damos_destroy_filter(dst_filter);
1020 }
1021
1022 damos_for_each_ops_filter_safe(src_filter, next, src) {
1023 if (j++ < i)
1024 continue;
1025
1026 new_filter = damos_new_filter(
1027 src_filter->type, src_filter->matching,
1028 src_filter->allow);
1029 if (!new_filter)
1030 return -ENOMEM;
1031 damos_commit_filter_arg(new_filter, src_filter);
1032 damos_add_filter(dst, new_filter);
1033 }
1034 return 0;
1035 }
1036
1037 /**
1038 * damos_filters_default_reject() - decide whether to reject memory that didn't
1039 * match with any given filter.
1040 * @filters: Given DAMOS filters of a group.
1041 */
damos_filters_default_reject(struct list_head * filters)1042 static bool damos_filters_default_reject(struct list_head *filters)
1043 {
1044 struct damos_filter *last_filter;
1045
1046 if (list_empty(filters))
1047 return false;
1048 last_filter = list_last_entry(filters, struct damos_filter, list);
1049 return last_filter->allow;
1050 }
1051
damos_set_filters_default_reject(struct damos * s)1052 static void damos_set_filters_default_reject(struct damos *s)
1053 {
1054 if (!list_empty(&s->ops_filters))
1055 s->core_filters_default_reject = false;
1056 else
1057 s->core_filters_default_reject =
1058 damos_filters_default_reject(&s->core_filters);
1059 s->ops_filters_default_reject =
1060 damos_filters_default_reject(&s->ops_filters);
1061 }
1062
1063 /*
1064 * damos_commit_dests() - Copy migration destinations from @src to @dst.
1065 * @dst: Destination structure to update.
1066 * @src: Source structure to copy from.
1067 *
1068 * If the number of destinations has changed, the old arrays in @dst are freed
1069 * and new ones are allocated. On success, @dst contains a full copy of
1070 * @src's arrays and count.
1071 *
1072 * On allocation failure, @dst is left in a partially torn-down state: its
1073 * arrays may be NULL and @nr_dests may not reflect the actual allocation
1074 * sizes. The structure remains safe to deallocate via damon_destroy_scheme(),
1075 * but callers must not reuse @dst for further commits — it should be
1076 * discarded.
1077 *
1078 * Return: 0 on success, -ENOMEM on allocation failure.
1079 */
damos_commit_dests(struct damos_migrate_dests * dst,struct damos_migrate_dests * src)1080 static int damos_commit_dests(struct damos_migrate_dests *dst,
1081 struct damos_migrate_dests *src)
1082 {
1083 if (dst->nr_dests != src->nr_dests) {
1084 kfree(dst->node_id_arr);
1085 kfree(dst->weight_arr);
1086
1087 dst->node_id_arr = kmalloc_array(src->nr_dests,
1088 sizeof(*dst->node_id_arr), GFP_KERNEL);
1089 if (!dst->node_id_arr) {
1090 dst->weight_arr = NULL;
1091 return -ENOMEM;
1092 }
1093
1094 dst->weight_arr = kmalloc_array(src->nr_dests,
1095 sizeof(*dst->weight_arr), GFP_KERNEL);
1096 if (!dst->weight_arr) {
1097 /* ->node_id_arr will be freed by scheme destruction */
1098 return -ENOMEM;
1099 }
1100 }
1101
1102 dst->nr_dests = src->nr_dests;
1103 for (int i = 0; i < src->nr_dests; i++) {
1104 dst->node_id_arr[i] = src->node_id_arr[i];
1105 dst->weight_arr[i] = src->weight_arr[i];
1106 }
1107
1108 return 0;
1109 }
1110
damos_commit_filters(struct damos * dst,struct damos * src)1111 static int damos_commit_filters(struct damos *dst, struct damos *src)
1112 {
1113 int err;
1114
1115 err = damos_commit_core_filters(dst, src);
1116 if (err)
1117 return err;
1118 err = damos_commit_ops_filters(dst, src);
1119 if (err)
1120 return err;
1121 damos_set_filters_default_reject(dst);
1122 return 0;
1123 }
1124
damon_nth_scheme(int n,struct damon_ctx * ctx)1125 static struct damos *damon_nth_scheme(int n, struct damon_ctx *ctx)
1126 {
1127 struct damos *s;
1128 int i = 0;
1129
1130 damon_for_each_scheme(s, ctx) {
1131 if (i++ == n)
1132 return s;
1133 }
1134 return NULL;
1135 }
1136
damos_commit(struct damos * dst,struct damos * src)1137 static int damos_commit(struct damos *dst, struct damos *src)
1138 {
1139 int err;
1140
1141 dst->pattern = src->pattern;
1142 dst->action = src->action;
1143 dst->apply_interval_us = src->apply_interval_us;
1144
1145 err = damos_commit_quota(&dst->quota, &src->quota);
1146 if (err)
1147 return err;
1148
1149 dst->wmarks = src->wmarks;
1150 dst->target_nid = src->target_nid;
1151
1152 err = damos_commit_dests(&dst->migrate_dests, &src->migrate_dests);
1153 if (err)
1154 return err;
1155
1156 err = damos_commit_filters(dst, src);
1157 if (err)
1158 return err;
1159
1160 dst->max_nr_snapshots = src->max_nr_snapshots;
1161 return 0;
1162 }
1163
damon_commit_schemes(struct damon_ctx * dst,struct damon_ctx * src)1164 static int damon_commit_schemes(struct damon_ctx *dst, struct damon_ctx *src)
1165 {
1166 struct damos *dst_scheme, *next, *src_scheme, *new_scheme;
1167 int i = 0, j = 0, err;
1168
1169 damon_for_each_scheme_safe(dst_scheme, next, dst) {
1170 src_scheme = damon_nth_scheme(i++, src);
1171 if (src_scheme) {
1172 err = damos_commit(dst_scheme, src_scheme);
1173 if (err)
1174 return err;
1175 } else {
1176 damon_destroy_scheme(dst_scheme);
1177 }
1178 }
1179
1180 damon_for_each_scheme_safe(src_scheme, next, src) {
1181 if (j++ < i)
1182 continue;
1183 new_scheme = damon_new_scheme(&src_scheme->pattern,
1184 src_scheme->action,
1185 src_scheme->apply_interval_us,
1186 &src_scheme->quota, &src_scheme->wmarks,
1187 NUMA_NO_NODE);
1188 if (!new_scheme)
1189 return -ENOMEM;
1190 err = damos_commit(new_scheme, src_scheme);
1191 if (err) {
1192 damon_destroy_scheme(new_scheme);
1193 return err;
1194 }
1195 damon_add_scheme(dst, new_scheme);
1196 }
1197 return 0;
1198 }
1199
damon_nth_target(int n,struct damon_ctx * ctx)1200 static struct damon_target *damon_nth_target(int n, struct damon_ctx *ctx)
1201 {
1202 struct damon_target *t;
1203 int i = 0;
1204
1205 damon_for_each_target(t, ctx) {
1206 if (i++ == n)
1207 return t;
1208 }
1209 return NULL;
1210 }
1211
1212 /*
1213 * The caller should ensure the regions of @src are
1214 * 1. valid (end >= src) and
1215 * 2. sorted by starting address.
1216 *
1217 * If @src has no region, @dst keeps current regions.
1218 */
damon_commit_target_regions(struct damon_target * dst,struct damon_target * src,unsigned long src_min_region_sz)1219 static int damon_commit_target_regions(struct damon_target *dst,
1220 struct damon_target *src, unsigned long src_min_region_sz)
1221 {
1222 struct damon_region *src_region;
1223 struct damon_addr_range *ranges;
1224 int i = 0, err;
1225
1226 damon_for_each_region(src_region, src)
1227 i++;
1228 if (!i)
1229 return 0;
1230
1231 ranges = kmalloc_objs(*ranges, i, GFP_KERNEL | __GFP_NOWARN);
1232 if (!ranges)
1233 return -ENOMEM;
1234 i = 0;
1235 damon_for_each_region(src_region, src)
1236 ranges[i++] = src_region->ar;
1237 err = damon_set_regions(dst, ranges, i, src_min_region_sz);
1238 kfree(ranges);
1239 return err;
1240 }
1241
damon_commit_target(struct damon_target * dst,bool dst_has_pid,struct damon_target * src,bool src_has_pid,unsigned long src_min_region_sz)1242 static int damon_commit_target(
1243 struct damon_target *dst, bool dst_has_pid,
1244 struct damon_target *src, bool src_has_pid,
1245 unsigned long src_min_region_sz)
1246 {
1247 int err;
1248
1249 err = damon_commit_target_regions(dst, src, src_min_region_sz);
1250 if (err)
1251 return err;
1252 if (dst_has_pid)
1253 put_pid(dst->pid);
1254 if (src_has_pid)
1255 get_pid(src->pid);
1256 dst->pid = src->pid;
1257 return 0;
1258 }
1259
damon_commit_targets(struct damon_ctx * dst,struct damon_ctx * src)1260 static int damon_commit_targets(
1261 struct damon_ctx *dst, struct damon_ctx *src)
1262 {
1263 struct damon_target *dst_target, *next, *src_target, *new_target;
1264 int i = 0, j = 0, err;
1265
1266 damon_for_each_target_safe(dst_target, next, dst) {
1267 src_target = damon_nth_target(i++, src);
1268 /*
1269 * If src target is obsolete, do not commit the parameters to
1270 * the dst target, and further remove the dst target.
1271 */
1272 if (src_target && !src_target->obsolete) {
1273 err = damon_commit_target(
1274 dst_target, damon_target_has_pid(dst),
1275 src_target, damon_target_has_pid(src),
1276 src->min_region_sz);
1277 if (err)
1278 return err;
1279 } else {
1280 struct damos *s;
1281
1282 damon_destroy_target(dst_target, dst);
1283 damon_for_each_scheme(s, dst) {
1284 if (s->quota.charge_target_from == dst_target) {
1285 s->quota.charge_target_from = NULL;
1286 s->quota.charge_addr_from = 0;
1287 }
1288 }
1289 }
1290 }
1291
1292 damon_for_each_target_safe(src_target, next, src) {
1293 if (j++ < i)
1294 continue;
1295 /* target to remove has no matching dst */
1296 if (src_target->obsolete)
1297 return -EINVAL;
1298 new_target = damon_new_target();
1299 if (!new_target)
1300 return -ENOMEM;
1301 err = damon_commit_target(new_target, false,
1302 src_target, damon_target_has_pid(src),
1303 src->min_region_sz);
1304 if (err) {
1305 damon_destroy_target(new_target, NULL);
1306 return err;
1307 }
1308 damon_add_target(dst, new_target);
1309 }
1310 return 0;
1311 }
1312
1313 /**
1314 * damon_commit_ctx() - Commit parameters of a DAMON context to another.
1315 * @dst: The commit destination DAMON context.
1316 * @src: The commit source DAMON context.
1317 *
1318 * This function copies user-specified parameters from @src to @dst and update
1319 * the internal status and results accordingly. Users should use this function
1320 * for context-level parameters update of running context, instead of manual
1321 * in-place updates.
1322 *
1323 * This function should be called from parameters-update safe context, like
1324 * damon_call().
1325 */
damon_commit_ctx(struct damon_ctx * dst,struct damon_ctx * src)1326 int damon_commit_ctx(struct damon_ctx *dst, struct damon_ctx *src)
1327 {
1328 int err;
1329
1330 dst->maybe_corrupted = true;
1331 if (!is_power_of_2(src->min_region_sz))
1332 return -EINVAL;
1333
1334 err = damon_commit_schemes(dst, src);
1335 if (err)
1336 return err;
1337 err = damon_commit_targets(dst, src);
1338 if (err)
1339 return err;
1340 /*
1341 * schemes and targets should be updated first, since
1342 * 1. damon_set_attrs() updates monitoring results of targets and
1343 * next_apply_sis of schemes, and
1344 * 2. ops update should be done after pid handling is done (target
1345 * committing require putting pids).
1346 */
1347 if (!damon_attrs_equals(&dst->attrs, &src->attrs)) {
1348 err = damon_set_attrs(dst, &src->attrs);
1349 if (err)
1350 return err;
1351 }
1352 dst->ops = src->ops;
1353 dst->addr_unit = src->addr_unit;
1354 dst->min_region_sz = src->min_region_sz;
1355
1356 dst->maybe_corrupted = false;
1357 return 0;
1358 }
1359
1360 /**
1361 * damon_nr_running_ctxs() - Return number of currently running contexts.
1362 */
damon_nr_running_ctxs(void)1363 int damon_nr_running_ctxs(void)
1364 {
1365 int nr_ctxs;
1366
1367 mutex_lock(&damon_lock);
1368 nr_ctxs = nr_running_ctxs;
1369 mutex_unlock(&damon_lock);
1370
1371 return nr_ctxs;
1372 }
1373
1374 /* Returns the size upper limit for each monitoring region */
damon_region_sz_limit(struct damon_ctx * ctx)1375 static unsigned long damon_region_sz_limit(struct damon_ctx *ctx)
1376 {
1377 struct damon_target *t;
1378 struct damon_region *r;
1379 unsigned long sz = 0;
1380
1381 damon_for_each_target(t, ctx) {
1382 damon_for_each_region(r, t)
1383 sz += damon_sz_region(r);
1384 }
1385
1386 if (ctx->attrs.min_nr_regions)
1387 sz /= ctx->attrs.min_nr_regions;
1388 if (sz < ctx->min_region_sz)
1389 sz = ctx->min_region_sz;
1390
1391 return sz;
1392 }
1393
1394 static void damon_split_region_at(struct damon_target *t,
1395 struct damon_region *r, unsigned long sz_r);
1396
1397 /*
1398 * damon_apply_min_nr_regions() - Make effect of min_nr_regions parameter.
1399 * @ctx: monitoring context.
1400 *
1401 * This function implement min_nr_regions (minimum number of damon_region
1402 * objects in the given monitoring context) behavior. It first calculates
1403 * maximum size of each region for enforcing the min_nr_regions as total size
1404 * of the regions divided by the min_nr_regions. After that, this function
1405 * splits regions to ensure all regions are equal to or smaller than the size
1406 * limit. Finally, this function returns the maximum size limit.
1407 *
1408 * Returns: maximum size of each region for convincing min_nr_regions.
1409 */
damon_apply_min_nr_regions(struct damon_ctx * ctx)1410 static unsigned long damon_apply_min_nr_regions(struct damon_ctx *ctx)
1411 {
1412 unsigned long max_region_sz = damon_region_sz_limit(ctx);
1413 struct damon_target *t;
1414 struct damon_region *r, *next;
1415
1416 max_region_sz = ALIGN(max_region_sz, ctx->min_region_sz);
1417 damon_for_each_target(t, ctx) {
1418 damon_for_each_region_safe(r, next, t) {
1419 while (damon_sz_region(r) > max_region_sz) {
1420 damon_split_region_at(t, r, max_region_sz);
1421 r = damon_next_region(r);
1422 }
1423 }
1424 }
1425 return max_region_sz;
1426 }
1427
1428 static int kdamond_fn(void *data);
1429
1430 /*
1431 * __damon_start() - Starts monitoring with given context.
1432 * @ctx: monitoring context
1433 *
1434 * This function should be called while damon_lock is hold.
1435 *
1436 * Return: 0 on success, negative error code otherwise.
1437 */
__damon_start(struct damon_ctx * ctx)1438 static int __damon_start(struct damon_ctx *ctx)
1439 {
1440 int err = -EBUSY;
1441
1442 mutex_lock(&ctx->kdamond_lock);
1443 if (!ctx->kdamond) {
1444 err = 0;
1445 reinit_completion(&ctx->kdamond_started);
1446 ctx->kdamond = kthread_run(kdamond_fn, ctx, "kdamond.%d",
1447 nr_running_ctxs);
1448 if (IS_ERR(ctx->kdamond)) {
1449 err = PTR_ERR(ctx->kdamond);
1450 ctx->kdamond = NULL;
1451 } else {
1452 wait_for_completion(&ctx->kdamond_started);
1453 }
1454 }
1455 mutex_unlock(&ctx->kdamond_lock);
1456
1457 return err;
1458 }
1459
1460 /**
1461 * damon_start() - Starts the monitorings for a given group of contexts.
1462 * @ctxs: an array of the pointers for contexts to start monitoring
1463 * @nr_ctxs: size of @ctxs
1464 * @exclusive: exclusiveness of this contexts group
1465 *
1466 * This function starts a group of monitoring threads for a group of monitoring
1467 * contexts. One thread per each context is created and run in parallel. The
1468 * caller should handle synchronization between the threads by itself. If
1469 * @exclusive is true and a group of threads that created by other
1470 * 'damon_start()' call is currently running, this function does nothing but
1471 * returns -EBUSY.
1472 *
1473 * Return: 0 on success, negative error code otherwise.
1474 */
damon_start(struct damon_ctx ** ctxs,int nr_ctxs,bool exclusive)1475 int damon_start(struct damon_ctx **ctxs, int nr_ctxs, bool exclusive)
1476 {
1477 int i;
1478 int err = 0;
1479
1480 for (i = 0; i < nr_ctxs; i++) {
1481 if (!is_power_of_2(ctxs[i]->min_region_sz))
1482 return -EINVAL;
1483 }
1484
1485 mutex_lock(&damon_lock);
1486 if ((exclusive && nr_running_ctxs) ||
1487 (!exclusive && running_exclusive_ctxs)) {
1488 mutex_unlock(&damon_lock);
1489 return -EBUSY;
1490 }
1491
1492 for (i = 0; i < nr_ctxs; i++) {
1493 err = __damon_start(ctxs[i]);
1494 if (err)
1495 break;
1496 nr_running_ctxs++;
1497 }
1498 if (exclusive && nr_running_ctxs)
1499 running_exclusive_ctxs = true;
1500 mutex_unlock(&damon_lock);
1501
1502 return err;
1503 }
1504
1505 /*
1506 * __damon_stop() - Stops monitoring of a given context.
1507 * @ctx: monitoring context
1508 *
1509 * Return: 0 on success, negative error code otherwise.
1510 */
__damon_stop(struct damon_ctx * ctx)1511 static int __damon_stop(struct damon_ctx *ctx)
1512 {
1513 struct task_struct *tsk;
1514
1515 mutex_lock(&ctx->kdamond_lock);
1516 tsk = ctx->kdamond;
1517 if (tsk) {
1518 get_task_struct(tsk);
1519 mutex_unlock(&ctx->kdamond_lock);
1520 kthread_stop_put(tsk);
1521 return 0;
1522 }
1523 mutex_unlock(&ctx->kdamond_lock);
1524
1525 return -EPERM;
1526 }
1527
1528 /**
1529 * damon_stop() - Stops the monitorings for a given group of contexts.
1530 * @ctxs: an array of the pointers for contexts to stop monitoring
1531 * @nr_ctxs: size of @ctxs
1532 *
1533 * Return: 0 on success, negative error code otherwise.
1534 */
damon_stop(struct damon_ctx ** ctxs,int nr_ctxs)1535 int damon_stop(struct damon_ctx **ctxs, int nr_ctxs)
1536 {
1537 int i, err = 0;
1538
1539 for (i = 0; i < nr_ctxs; i++) {
1540 /* nr_running_ctxs is decremented in kdamond_fn */
1541 err = __damon_stop(ctxs[i]);
1542 if (err)
1543 break;
1544 }
1545 return err;
1546 }
1547
1548 /**
1549 * damon_is_running() - Returns if a given DAMON context is running.
1550 * @ctx: The DAMON context to see if running.
1551 *
1552 * Return: true if @ctx is running, false otherwise.
1553 */
damon_is_running(struct damon_ctx * ctx)1554 bool damon_is_running(struct damon_ctx *ctx)
1555 {
1556 bool running;
1557
1558 mutex_lock(&ctx->kdamond_lock);
1559 running = ctx->kdamond != NULL;
1560 mutex_unlock(&ctx->kdamond_lock);
1561 return running;
1562 }
1563
1564 /**
1565 * damon_kdamond_pid() - Return pid of a given DAMON context's worker thread.
1566 * @ctx: The DAMON context of the question.
1567 *
1568 * Return: pid if @ctx is running, negative error code otherwise.
1569 */
damon_kdamond_pid(struct damon_ctx * ctx)1570 int damon_kdamond_pid(struct damon_ctx *ctx)
1571 {
1572 int pid = -EINVAL;
1573
1574 mutex_lock(&ctx->kdamond_lock);
1575 if (ctx->kdamond)
1576 pid = ctx->kdamond->pid;
1577 mutex_unlock(&ctx->kdamond_lock);
1578 return pid;
1579 }
1580
1581 /**
1582 * damon_call() - Invoke a given function on DAMON worker thread (kdamond).
1583 * @ctx: DAMON context to call the function for.
1584 * @control: Control variable of the call request.
1585 *
1586 * Ask DAMON worker thread (kdamond) of @ctx to call a function with an
1587 * argument data that respectively passed via &damon_call_control->fn and
1588 * &damon_call_control->data of @control. If &damon_call_control->repeat of
1589 * @control is unset, further wait until the kdamond finishes handling of the
1590 * request. Otherwise, return as soon as the request is made.
1591 *
1592 * The kdamond executes the function with the argument in the main loop, just
1593 * after a sampling of the iteration is finished. The function can hence
1594 * safely access the internal data of the &struct damon_ctx without additional
1595 * synchronization. The return value of the function will be saved in
1596 * &damon_call_control->return_code.
1597 *
1598 * Note that this function should be called only after damon_start() with the
1599 * @ctx has succeeded. Otherwise, this function could fall into an indefinite
1600 * wait.
1601 *
1602 * Return: 0 on success, negative error code otherwise.
1603 */
damon_call(struct damon_ctx * ctx,struct damon_call_control * control)1604 int damon_call(struct damon_ctx *ctx, struct damon_call_control *control)
1605 {
1606 if (!control->repeat)
1607 init_completion(&control->completion);
1608 control->canceled = false;
1609 INIT_LIST_HEAD(&control->list);
1610
1611 mutex_lock(&ctx->call_controls_lock);
1612 if (ctx->call_controls_obsolete) {
1613 mutex_unlock(&ctx->call_controls_lock);
1614 return -ECANCELED;
1615 }
1616 list_add_tail(&control->list, &ctx->call_controls);
1617 mutex_unlock(&ctx->call_controls_lock);
1618 if (control->repeat)
1619 return 0;
1620 wait_for_completion(&control->completion);
1621 if (control->canceled)
1622 return -ECANCELED;
1623 return 0;
1624 }
1625
1626 /**
1627 * damos_walk() - Invoke a given functions while DAMOS walk regions.
1628 * @ctx: DAMON context to call the functions for.
1629 * @control: Control variable of the walk request.
1630 *
1631 * Ask DAMON worker thread (kdamond) of @ctx to call a function for each region
1632 * that the kdamond will apply DAMOS action to, and wait until the kdamond
1633 * finishes handling of the request.
1634 *
1635 * The kdamond executes the given function in the main loop, for each region
1636 * just after it applied any DAMOS actions of @ctx to it. The invocation is
1637 * made only within one &damos->apply_interval_us since damos_walk()
1638 * invocation, for each scheme. The given callback function can hence safely
1639 * access the internal data of &struct damon_ctx and &struct damon_region that
1640 * each of the scheme will apply the action for next interval, without
1641 * additional synchronizations against the kdamond. If every scheme of @ctx
1642 * passed at least one &damos->apply_interval_us, kdamond marks the request as
1643 * completed so that damos_walk() can wakeup and return.
1644 *
1645 * Note that this function should be called only after damon_start() with the
1646 * @ctx has succeeded. Otherwise, this function could fall into an indefinite
1647 * wait.
1648 *
1649 * Return: 0 on success, negative error code otherwise.
1650 */
damos_walk(struct damon_ctx * ctx,struct damos_walk_control * control)1651 int damos_walk(struct damon_ctx *ctx, struct damos_walk_control *control)
1652 {
1653 init_completion(&control->completion);
1654 control->canceled = false;
1655 mutex_lock(&ctx->walk_control_lock);
1656 if (ctx->walk_control_obsolete) {
1657 mutex_unlock(&ctx->walk_control_lock);
1658 return -ECANCELED;
1659 }
1660 if (ctx->walk_control) {
1661 mutex_unlock(&ctx->walk_control_lock);
1662 return -EBUSY;
1663 }
1664 ctx->walk_control = control;
1665 mutex_unlock(&ctx->walk_control_lock);
1666 wait_for_completion(&control->completion);
1667 if (control->canceled)
1668 return -ECANCELED;
1669 return 0;
1670 }
1671
1672 /*
1673 * Warn and fix corrupted ->nr_accesses[_bp] for investigations and preventing
1674 * the problem being propagated.
1675 */
damon_warn_fix_nr_accesses_corruption(struct damon_region * r)1676 static void damon_warn_fix_nr_accesses_corruption(struct damon_region *r)
1677 {
1678 if (r->nr_accesses_bp == r->nr_accesses * 10000)
1679 return;
1680 WARN_ONCE(true, "invalid nr_accesses_bp at reset: %u %u\n",
1681 r->nr_accesses_bp, r->nr_accesses);
1682 r->nr_accesses_bp = r->nr_accesses * 10000;
1683 }
1684
1685 #ifdef CONFIG_DAMON_DEBUG_SANITY
damon_verify_reset_aggregated(struct damon_region * r,struct damon_ctx * c)1686 static void damon_verify_reset_aggregated(struct damon_region *r,
1687 struct damon_ctx *c)
1688 {
1689 WARN_ONCE(r->nr_accesses_bp != r->last_nr_accesses * 10000,
1690 "nr_accesses_bp %u last_nr_accesses %u sis %lu %lu\n",
1691 r->nr_accesses_bp, r->last_nr_accesses,
1692 c->passed_sample_intervals, c->next_aggregation_sis);
1693 }
1694 #else
damon_verify_reset_aggregated(struct damon_region * r,struct damon_ctx * c)1695 static void damon_verify_reset_aggregated(struct damon_region *r,
1696 struct damon_ctx *c)
1697 {
1698 }
1699 #endif
1700
1701
1702 /*
1703 * Reset the aggregated monitoring results ('nr_accesses' of each region).
1704 */
kdamond_reset_aggregated(struct damon_ctx * c)1705 static void kdamond_reset_aggregated(struct damon_ctx *c)
1706 {
1707 struct damon_target *t;
1708 unsigned int ti = 0; /* target's index */
1709
1710 damon_for_each_target(t, c) {
1711 struct damon_region *r;
1712
1713 damon_for_each_region(r, t) {
1714 trace_damon_aggregated(ti, r, damon_nr_regions(t));
1715 damon_warn_fix_nr_accesses_corruption(r);
1716 r->last_nr_accesses = r->nr_accesses;
1717 r->nr_accesses = 0;
1718 damon_verify_reset_aggregated(r, c);
1719 }
1720 ti++;
1721 }
1722 }
1723
damon_get_intervals_score(struct damon_ctx * c)1724 static unsigned long damon_get_intervals_score(struct damon_ctx *c)
1725 {
1726 struct damon_target *t;
1727 struct damon_region *r;
1728 unsigned long sz_region, max_access_events = 0, access_events = 0;
1729 unsigned long target_access_events;
1730 unsigned long goal_bp = c->attrs.intervals_goal.access_bp;
1731
1732 damon_for_each_target(t, c) {
1733 damon_for_each_region(r, t) {
1734 sz_region = damon_sz_region(r);
1735 max_access_events += sz_region * c->attrs.aggr_samples;
1736 access_events += sz_region * r->nr_accesses;
1737 }
1738 }
1739 target_access_events = max_access_events * goal_bp / 10000;
1740 target_access_events = target_access_events ? : 1;
1741 return mult_frac(access_events, 10000, target_access_events);
1742 }
1743
1744 static unsigned long damon_feed_loop_next_input(unsigned long last_input,
1745 unsigned long score);
1746
damon_get_intervals_adaptation_bp(struct damon_ctx * c)1747 static unsigned long damon_get_intervals_adaptation_bp(struct damon_ctx *c)
1748 {
1749 unsigned long score_bp, adaptation_bp;
1750
1751 score_bp = damon_get_intervals_score(c);
1752 adaptation_bp = damon_feed_loop_next_input(100000000, score_bp) /
1753 10000;
1754 /*
1755 * adaptation_bp ranges from 1 to 20,000. Avoid too rapid reduction of
1756 * the intervals by rescaling [1,10,000] to [5000, 10,000].
1757 */
1758 if (adaptation_bp <= 10000)
1759 adaptation_bp = 5000 + adaptation_bp / 2;
1760 return adaptation_bp;
1761 }
1762
kdamond_tune_intervals(struct damon_ctx * c)1763 static void kdamond_tune_intervals(struct damon_ctx *c)
1764 {
1765 unsigned long adaptation_bp;
1766 struct damon_attrs new_attrs;
1767 struct damon_intervals_goal *goal;
1768
1769 adaptation_bp = damon_get_intervals_adaptation_bp(c);
1770 if (adaptation_bp == 10000)
1771 return;
1772
1773 new_attrs = c->attrs;
1774 goal = &c->attrs.intervals_goal;
1775 new_attrs.sample_interval = min(goal->max_sample_us,
1776 c->attrs.sample_interval * adaptation_bp / 10000);
1777 new_attrs.sample_interval = max(goal->min_sample_us,
1778 new_attrs.sample_interval);
1779 new_attrs.aggr_interval = new_attrs.sample_interval *
1780 c->attrs.aggr_samples;
1781 trace_damon_monitor_intervals_tune(new_attrs.sample_interval);
1782 damon_set_attrs(c, &new_attrs);
1783 }
1784
__damos_valid_target(struct damon_region * r,struct damos * s)1785 static bool __damos_valid_target(struct damon_region *r, struct damos *s)
1786 {
1787 unsigned long sz;
1788 unsigned int nr_accesses = r->nr_accesses_bp / 10000;
1789
1790 sz = damon_sz_region(r);
1791 return s->pattern.min_sz_region <= sz &&
1792 sz <= s->pattern.max_sz_region &&
1793 s->pattern.min_nr_accesses <= nr_accesses &&
1794 nr_accesses <= s->pattern.max_nr_accesses &&
1795 s->pattern.min_age_region <= r->age &&
1796 r->age <= s->pattern.max_age_region;
1797 }
1798
1799 /*
1800 * damos_quota_is_set() - Return if the given quota is actually set.
1801 * @quota: The quota to check.
1802 *
1803 * Returns true if the quota is set, false otherwise.
1804 */
damos_quota_is_set(struct damos_quota * quota)1805 static bool damos_quota_is_set(struct damos_quota *quota)
1806 {
1807 return quota->esz || quota->sz || quota->ms ||
1808 !damos_quota_goals_empty(quota);
1809 }
1810
damos_valid_target(struct damon_ctx * c,struct damon_region * r,struct damos * s)1811 static bool damos_valid_target(struct damon_ctx *c, struct damon_region *r,
1812 struct damos *s)
1813 {
1814 bool ret = __damos_valid_target(r, s);
1815
1816 if (!ret || !damos_quota_is_set(&s->quota) || !c->ops.get_scheme_score)
1817 return ret;
1818
1819 return c->ops.get_scheme_score(c, r, s) >= s->quota.min_score;
1820 }
1821
1822 /*
1823 * damos_skip_charged_region() - Check if the given region or starting part of
1824 * it is already charged for the DAMOS quota.
1825 * @t: The target of the region.
1826 * @rp: The pointer to the region.
1827 * @s: The scheme to be applied.
1828 * @min_region_sz: minimum region size.
1829 *
1830 * If a quota of a scheme has exceeded in a quota charge window, the scheme's
1831 * action would applied to only a part of the target access pattern fulfilling
1832 * regions. To avoid applying the scheme action to only already applied
1833 * regions, DAMON skips applying the scheme action to the regions that charged
1834 * in the previous charge window.
1835 *
1836 * This function checks if a given region should be skipped or not for the
1837 * reason. If only the starting part of the region has previously charged,
1838 * this function splits the region into two so that the second one covers the
1839 * area that not charged in the previous charge widnow, and return true. The
1840 * caller can see the second one on the next iteration of the region walk.
1841 * Note that this means the caller should use damon_for_each_region() instead
1842 * of damon_for_each_region_safe(). If damon_for_each_region_safe() is used,
1843 * the second region will just be ignored.
1844 *
1845 * Return: true if the region should be skipped, false otherwise.
1846 */
damos_skip_charged_region(struct damon_target * t,struct damon_region * r,struct damos * s,unsigned long min_region_sz)1847 static bool damos_skip_charged_region(struct damon_target *t,
1848 struct damon_region *r, struct damos *s,
1849 unsigned long min_region_sz)
1850 {
1851 struct damos_quota *quota = &s->quota;
1852 unsigned long sz_to_skip;
1853
1854 /* Skip previously charged regions */
1855 if (quota->charge_target_from) {
1856 if (t != quota->charge_target_from)
1857 return true;
1858 if (r == damon_last_region(t)) {
1859 quota->charge_target_from = NULL;
1860 quota->charge_addr_from = 0;
1861 return true;
1862 }
1863 if (quota->charge_addr_from &&
1864 r->ar.end <= quota->charge_addr_from)
1865 return true;
1866
1867 if (quota->charge_addr_from && r->ar.start <
1868 quota->charge_addr_from) {
1869 sz_to_skip = ALIGN_DOWN(quota->charge_addr_from -
1870 r->ar.start, min_region_sz);
1871 if (!sz_to_skip) {
1872 if (damon_sz_region(r) <= min_region_sz)
1873 return true;
1874 sz_to_skip = min_region_sz;
1875 }
1876 damon_split_region_at(t, r, sz_to_skip);
1877 return true;
1878 }
1879 quota->charge_target_from = NULL;
1880 quota->charge_addr_from = 0;
1881 }
1882 return false;
1883 }
1884
damos_update_stat(struct damos * s,unsigned long sz_tried,unsigned long sz_applied,unsigned long sz_ops_filter_passed)1885 static void damos_update_stat(struct damos *s,
1886 unsigned long sz_tried, unsigned long sz_applied,
1887 unsigned long sz_ops_filter_passed)
1888 {
1889 s->stat.nr_tried++;
1890 s->stat.sz_tried += sz_tried;
1891 if (sz_applied)
1892 s->stat.nr_applied++;
1893 s->stat.sz_applied += sz_applied;
1894 s->stat.sz_ops_filter_passed += sz_ops_filter_passed;
1895 }
1896
damos_filter_match(struct damon_ctx * ctx,struct damon_target * t,struct damon_region * r,struct damos_filter * filter,unsigned long min_region_sz)1897 static bool damos_filter_match(struct damon_ctx *ctx, struct damon_target *t,
1898 struct damon_region *r, struct damos_filter *filter,
1899 unsigned long min_region_sz)
1900 {
1901 bool matched = false;
1902 struct damon_target *ti;
1903 int target_idx = 0;
1904 unsigned long start, end;
1905
1906 switch (filter->type) {
1907 case DAMOS_FILTER_TYPE_TARGET:
1908 damon_for_each_target(ti, ctx) {
1909 if (ti == t)
1910 break;
1911 target_idx++;
1912 }
1913 matched = target_idx == filter->target_idx;
1914 break;
1915 case DAMOS_FILTER_TYPE_ADDR:
1916 start = ALIGN_DOWN(filter->addr_range.start, min_region_sz);
1917 end = ALIGN_DOWN(filter->addr_range.end, min_region_sz);
1918
1919 /* inside the range */
1920 if (start <= r->ar.start && r->ar.end <= end) {
1921 matched = true;
1922 break;
1923 }
1924 /* outside of the range */
1925 if (r->ar.end <= start || end <= r->ar.start) {
1926 matched = false;
1927 break;
1928 }
1929 /* start before the range and overlap */
1930 if (r->ar.start < start) {
1931 damon_split_region_at(t, r, start - r->ar.start);
1932 matched = false;
1933 break;
1934 }
1935 /* start inside the range */
1936 damon_split_region_at(t, r, end - r->ar.start);
1937 matched = true;
1938 break;
1939 default:
1940 return false;
1941 }
1942
1943 return matched == filter->matching;
1944 }
1945
damos_core_filter_out(struct damon_ctx * ctx,struct damon_target * t,struct damon_region * r,struct damos * s)1946 static bool damos_core_filter_out(struct damon_ctx *ctx, struct damon_target *t,
1947 struct damon_region *r, struct damos *s)
1948 {
1949 struct damos_filter *filter;
1950
1951 s->core_filters_allowed = false;
1952 damos_for_each_core_filter(filter, s) {
1953 if (damos_filter_match(ctx, t, r, filter, ctx->min_region_sz)) {
1954 if (filter->allow)
1955 s->core_filters_allowed = true;
1956 return !filter->allow;
1957 }
1958 }
1959 return s->core_filters_default_reject;
1960 }
1961
1962 /*
1963 * damos_walk_call_walk() - Call &damos_walk_control->walk_fn.
1964 * @ctx: The context of &damon_ctx->walk_control.
1965 * @t: The monitoring target of @r that @s will be applied.
1966 * @r: The region of @t that @s will be applied.
1967 * @s: The scheme of @ctx that will be applied to @r.
1968 *
1969 * This function is called from kdamond whenever it asked the operation set to
1970 * apply a DAMOS scheme action to a region. If a DAMOS walk request is
1971 * installed by damos_walk() and not yet uninstalled, invoke it.
1972 */
damos_walk_call_walk(struct damon_ctx * ctx,struct damon_target * t,struct damon_region * r,struct damos * s,unsigned long sz_filter_passed)1973 static void damos_walk_call_walk(struct damon_ctx *ctx, struct damon_target *t,
1974 struct damon_region *r, struct damos *s,
1975 unsigned long sz_filter_passed)
1976 {
1977 struct damos_walk_control *control;
1978
1979 if (s->walk_completed)
1980 return;
1981
1982 control = ctx->walk_control;
1983 if (!control)
1984 return;
1985
1986 control->walk_fn(control->data, ctx, t, r, s, sz_filter_passed);
1987 }
1988
1989 /*
1990 * damos_walk_complete() - Complete DAMOS walk request if all walks are done.
1991 * @ctx: The context of &damon_ctx->walk_control.
1992 * @s: A scheme of @ctx that all walks are now done.
1993 *
1994 * This function is called when kdamond finished applying the action of a DAMOS
1995 * scheme to all regions that eligible for the given &damos->apply_interval_us.
1996 * If every scheme of @ctx including @s now finished walking for at least one
1997 * &damos->apply_interval_us, this function makrs the handling of the given
1998 * DAMOS walk request is done, so that damos_walk() can wake up and return.
1999 */
damos_walk_complete(struct damon_ctx * ctx,struct damos * s)2000 static void damos_walk_complete(struct damon_ctx *ctx, struct damos *s)
2001 {
2002 struct damos *siter;
2003 struct damos_walk_control *control;
2004
2005 control = ctx->walk_control;
2006 if (!control)
2007 return;
2008
2009 s->walk_completed = true;
2010 /* if all schemes completed, signal completion to walker */
2011 damon_for_each_scheme(siter, ctx) {
2012 if (!siter->walk_completed)
2013 return;
2014 }
2015 damon_for_each_scheme(siter, ctx)
2016 siter->walk_completed = false;
2017
2018 complete(&control->completion);
2019 ctx->walk_control = NULL;
2020 }
2021
2022 /*
2023 * damos_walk_cancel() - Cancel the current DAMOS walk request.
2024 * @ctx: The context of &damon_ctx->walk_control.
2025 *
2026 * This function is called when @ctx is deactivated by DAMOS watermarks, DAMOS
2027 * walk is requested but there is no DAMOS scheme to walk for, or the kdamond
2028 * is already out of the main loop and therefore gonna be terminated, and hence
2029 * cannot continue the walks. This function therefore marks the walk request
2030 * as canceled, so that damos_walk() can wake up and return.
2031 */
damos_walk_cancel(struct damon_ctx * ctx)2032 static void damos_walk_cancel(struct damon_ctx *ctx)
2033 {
2034 struct damos_walk_control *control;
2035
2036 mutex_lock(&ctx->walk_control_lock);
2037 control = ctx->walk_control;
2038 mutex_unlock(&ctx->walk_control_lock);
2039
2040 if (!control)
2041 return;
2042 control->canceled = true;
2043 complete(&control->completion);
2044 mutex_lock(&ctx->walk_control_lock);
2045 ctx->walk_control = NULL;
2046 mutex_unlock(&ctx->walk_control_lock);
2047 }
2048
damos_apply_scheme(struct damon_ctx * c,struct damon_target * t,struct damon_region * r,struct damos * s)2049 static void damos_apply_scheme(struct damon_ctx *c, struct damon_target *t,
2050 struct damon_region *r, struct damos *s)
2051 {
2052 struct damos_quota *quota = &s->quota;
2053 unsigned long sz = damon_sz_region(r);
2054 struct timespec64 begin, end;
2055 unsigned long sz_applied = 0;
2056 unsigned long sz_ops_filter_passed = 0;
2057 /*
2058 * We plan to support multiple context per kdamond, as DAMON sysfs
2059 * implies with 'nr_contexts' file. Nevertheless, only single context
2060 * per kdamond is supported for now. So, we can simply use '0' context
2061 * index here.
2062 */
2063 unsigned int cidx = 0;
2064 struct damos *siter; /* schemes iterator */
2065 unsigned int sidx = 0;
2066 struct damon_target *titer; /* targets iterator */
2067 unsigned int tidx = 0;
2068 bool do_trace = false;
2069
2070 /* get indices for trace_damos_before_apply() */
2071 if (trace_damos_before_apply_enabled()) {
2072 damon_for_each_scheme(siter, c) {
2073 if (siter == s)
2074 break;
2075 sidx++;
2076 }
2077 damon_for_each_target(titer, c) {
2078 if (titer == t)
2079 break;
2080 tidx++;
2081 }
2082 do_trace = true;
2083 }
2084
2085 if (c->ops.apply_scheme) {
2086 if (damos_quota_is_set(quota) &&
2087 quota->charged_sz + sz > quota->esz) {
2088 sz = ALIGN_DOWN(quota->esz - quota->charged_sz,
2089 c->min_region_sz);
2090 if (!sz)
2091 goto update_stat;
2092 damon_split_region_at(t, r, sz);
2093 }
2094 if (damos_core_filter_out(c, t, r, s))
2095 return;
2096 ktime_get_coarse_ts64(&begin);
2097 trace_damos_before_apply(cidx, sidx, tidx, r,
2098 damon_nr_regions(t), do_trace);
2099 sz_applied = c->ops.apply_scheme(c, t, r, s,
2100 &sz_ops_filter_passed);
2101 damos_walk_call_walk(c, t, r, s, sz_ops_filter_passed);
2102 ktime_get_coarse_ts64(&end);
2103 quota->total_charged_ns += timespec64_to_ns(&end) -
2104 timespec64_to_ns(&begin);
2105 quota->charged_sz += sz;
2106 if (damos_quota_is_set(quota) &&
2107 quota->charged_sz >= quota->esz) {
2108 quota->charge_target_from = t;
2109 quota->charge_addr_from = r->ar.end + 1;
2110 }
2111 }
2112 if (s->action != DAMOS_STAT)
2113 r->age = 0;
2114
2115 update_stat:
2116 damos_update_stat(s, sz, sz_applied, sz_ops_filter_passed);
2117 }
2118
damon_do_apply_schemes(struct damon_ctx * c,struct damon_target * t,struct damon_region * r)2119 static void damon_do_apply_schemes(struct damon_ctx *c,
2120 struct damon_target *t,
2121 struct damon_region *r)
2122 {
2123 struct damos *s;
2124
2125 damon_for_each_scheme(s, c) {
2126 struct damos_quota *quota = &s->quota;
2127
2128 if (time_before(c->passed_sample_intervals, s->next_apply_sis))
2129 continue;
2130
2131 if (!s->wmarks.activated)
2132 continue;
2133
2134 /* Check the quota */
2135 if (damos_quota_is_set(quota) &&
2136 quota->charged_sz >= quota->esz)
2137 continue;
2138
2139 if (damos_skip_charged_region(t, r, s, c->min_region_sz))
2140 continue;
2141
2142 if (s->max_nr_snapshots &&
2143 s->max_nr_snapshots <= s->stat.nr_snapshots)
2144 continue;
2145
2146 if (damos_valid_target(c, r, s))
2147 damos_apply_scheme(c, t, r, s);
2148
2149 if (damon_is_last_region(r, t))
2150 s->stat.nr_snapshots++;
2151 }
2152 }
2153
2154 /*
2155 * damon_feed_loop_next_input() - get next input to achieve a target score.
2156 * @last_input The last input.
2157 * @score Current score that made with @last_input.
2158 *
2159 * Calculate next input to achieve the target score, based on the last input
2160 * and current score. Assuming the input and the score are positively
2161 * proportional, calculate how much compensation should be added to or
2162 * subtracted from the last input as a proportion of the last input. Avoid
2163 * next input always being zero by setting it non-zero always. In short form
2164 * (assuming support of float and signed calculations), the algorithm is as
2165 * below.
2166 *
2167 * next_input = max(last_input * ((goal - current) / goal + 1), 1)
2168 *
2169 * For simple implementation, we assume the target score is always 10,000. The
2170 * caller should adjust @score for this.
2171 *
2172 * Returns next input that assumed to achieve the target score.
2173 */
damon_feed_loop_next_input(unsigned long last_input,unsigned long score)2174 static unsigned long damon_feed_loop_next_input(unsigned long last_input,
2175 unsigned long score)
2176 {
2177 const unsigned long goal = 10000;
2178 /* Set minimum input as 10000 to avoid compensation be zero */
2179 const unsigned long min_input = 10000;
2180 unsigned long score_goal_diff, compensation;
2181 bool over_achieving = score > goal;
2182
2183 if (score == goal)
2184 return last_input;
2185 if (score >= goal * 2)
2186 return min_input;
2187
2188 if (over_achieving)
2189 score_goal_diff = score - goal;
2190 else
2191 score_goal_diff = goal - score;
2192
2193 if (last_input < ULONG_MAX / score_goal_diff)
2194 compensation = last_input * score_goal_diff / goal;
2195 else
2196 compensation = last_input / goal * score_goal_diff;
2197
2198 if (over_achieving)
2199 return max(last_input - compensation, min_input);
2200 if (last_input < ULONG_MAX - compensation)
2201 return last_input + compensation;
2202 return ULONG_MAX;
2203 }
2204
2205 #ifdef CONFIG_PSI
2206
damos_get_some_mem_psi_total(void)2207 static u64 damos_get_some_mem_psi_total(void)
2208 {
2209 if (static_branch_likely(&psi_disabled))
2210 return 0;
2211 return div_u64(psi_system.total[PSI_AVGS][PSI_MEM * 2],
2212 NSEC_PER_USEC);
2213 }
2214
2215 #else /* CONFIG_PSI */
2216
damos_get_some_mem_psi_total(void)2217 static inline u64 damos_get_some_mem_psi_total(void)
2218 {
2219 return 0;
2220 };
2221
2222 #endif /* CONFIG_PSI */
2223
2224 #ifdef CONFIG_NUMA
invalid_mem_node(int nid)2225 static bool invalid_mem_node(int nid)
2226 {
2227 return nid < 0 || nid >= MAX_NUMNODES || !node_state(nid, N_MEMORY);
2228 }
2229
damos_get_node_mem_bp(struct damos_quota_goal * goal)2230 static __kernel_ulong_t damos_get_node_mem_bp(
2231 struct damos_quota_goal *goal)
2232 {
2233 struct sysinfo i;
2234 __kernel_ulong_t numerator;
2235
2236 if (invalid_mem_node(goal->nid)) {
2237 if (goal->metric == DAMOS_QUOTA_NODE_MEM_USED_BP)
2238 return 0;
2239 else /* DAMOS_QUOTA_NODE_MEM_FREE_BP */
2240 return 10000;
2241 }
2242
2243 si_meminfo_node(&i, goal->nid);
2244 if (goal->metric == DAMOS_QUOTA_NODE_MEM_USED_BP)
2245 numerator = i.totalram - i.freeram;
2246 else /* DAMOS_QUOTA_NODE_MEM_FREE_BP */
2247 numerator = i.freeram;
2248 return mult_frac(numerator, 10000, i.totalram);
2249 }
2250
damos_get_node_memcg_used_bp(struct damos_quota_goal * goal)2251 static unsigned long damos_get_node_memcg_used_bp(
2252 struct damos_quota_goal *goal)
2253 {
2254 struct mem_cgroup *memcg;
2255 struct lruvec *lruvec;
2256 unsigned long used_pages, numerator;
2257 struct sysinfo i;
2258
2259 if (invalid_mem_node(goal->nid)) {
2260 if (goal->metric == DAMOS_QUOTA_NODE_MEMCG_USED_BP)
2261 return 0;
2262 else /* DAMOS_QUOTA_NODE_MEMCG_FREE_BP */
2263 return 10000;
2264 }
2265
2266 memcg = mem_cgroup_get_from_id(goal->memcg_id);
2267 if (!memcg) {
2268 if (goal->metric == DAMOS_QUOTA_NODE_MEMCG_USED_BP)
2269 return 0;
2270 else /* DAMOS_QUOTA_NODE_MEMCG_FREE_BP */
2271 return 10000;
2272 }
2273
2274 mem_cgroup_flush_stats(memcg);
2275 lruvec = mem_cgroup_lruvec(memcg, NODE_DATA(goal->nid));
2276 used_pages = lruvec_page_state(lruvec, NR_ACTIVE_ANON);
2277 used_pages += lruvec_page_state(lruvec, NR_INACTIVE_ANON);
2278 used_pages += lruvec_page_state(lruvec, NR_ACTIVE_FILE);
2279 used_pages += lruvec_page_state(lruvec, NR_INACTIVE_FILE);
2280
2281 mem_cgroup_put(memcg);
2282
2283 si_meminfo_node(&i, goal->nid);
2284 if (goal->metric == DAMOS_QUOTA_NODE_MEMCG_USED_BP)
2285 numerator = used_pages;
2286 else /* DAMOS_QUOTA_NODE_MEMCG_FREE_BP */
2287 numerator = i.totalram - used_pages;
2288 return mult_frac(numerator, 10000, i.totalram);
2289 }
2290 #else
damos_get_node_mem_bp(struct damos_quota_goal * goal)2291 static __kernel_ulong_t damos_get_node_mem_bp(
2292 struct damos_quota_goal *goal)
2293 {
2294 return 0;
2295 }
2296
damos_get_node_memcg_used_bp(struct damos_quota_goal * goal)2297 static unsigned long damos_get_node_memcg_used_bp(
2298 struct damos_quota_goal *goal)
2299 {
2300 return 0;
2301 }
2302 #endif
2303
2304 /*
2305 * Returns LRU-active or inactive memory to total LRU memory size ratio.
2306 */
damos_get_in_active_mem_bp(bool active_ratio)2307 static unsigned int damos_get_in_active_mem_bp(bool active_ratio)
2308 {
2309 unsigned long active, inactive, total;
2310
2311 /* This should align with /proc/meminfo output */
2312 active = global_node_page_state(NR_LRU_BASE + LRU_ACTIVE_ANON) +
2313 global_node_page_state(NR_LRU_BASE + LRU_ACTIVE_FILE);
2314 inactive = global_node_page_state(NR_LRU_BASE + LRU_INACTIVE_ANON) +
2315 global_node_page_state(NR_LRU_BASE + LRU_INACTIVE_FILE);
2316 total = active + inactive;
2317 if (active_ratio)
2318 return mult_frac(active, 10000, total);
2319 return mult_frac(inactive, 10000, total);
2320 }
2321
damos_set_quota_goal_current_value(struct damos_quota_goal * goal)2322 static void damos_set_quota_goal_current_value(struct damos_quota_goal *goal)
2323 {
2324 u64 now_psi_total;
2325
2326 switch (goal->metric) {
2327 case DAMOS_QUOTA_USER_INPUT:
2328 /* User should already set goal->current_value */
2329 break;
2330 case DAMOS_QUOTA_SOME_MEM_PSI_US:
2331 now_psi_total = damos_get_some_mem_psi_total();
2332 goal->current_value = now_psi_total - goal->last_psi_total;
2333 goal->last_psi_total = now_psi_total;
2334 break;
2335 case DAMOS_QUOTA_NODE_MEM_USED_BP:
2336 case DAMOS_QUOTA_NODE_MEM_FREE_BP:
2337 goal->current_value = damos_get_node_mem_bp(goal);
2338 break;
2339 case DAMOS_QUOTA_NODE_MEMCG_USED_BP:
2340 case DAMOS_QUOTA_NODE_MEMCG_FREE_BP:
2341 goal->current_value = damos_get_node_memcg_used_bp(goal);
2342 break;
2343 case DAMOS_QUOTA_ACTIVE_MEM_BP:
2344 case DAMOS_QUOTA_INACTIVE_MEM_BP:
2345 goal->current_value = damos_get_in_active_mem_bp(
2346 goal->metric == DAMOS_QUOTA_ACTIVE_MEM_BP);
2347 break;
2348 default:
2349 break;
2350 }
2351 }
2352
2353 /* Return the highest score since it makes schemes least aggressive */
damos_quota_score(struct damos_quota * quota)2354 static unsigned long damos_quota_score(struct damos_quota *quota)
2355 {
2356 struct damos_quota_goal *goal;
2357 unsigned long highest_score = 0;
2358
2359 damos_for_each_quota_goal(goal, quota) {
2360 damos_set_quota_goal_current_value(goal);
2361 highest_score = max(highest_score,
2362 mult_frac(goal->current_value, 10000,
2363 goal->target_value));
2364 }
2365
2366 return highest_score;
2367 }
2368
damos_goal_tune_esz_bp_consist(struct damos_quota * quota)2369 static void damos_goal_tune_esz_bp_consist(struct damos_quota *quota)
2370 {
2371 unsigned long score = damos_quota_score(quota);
2372
2373 quota->esz_bp = damon_feed_loop_next_input(
2374 max(quota->esz_bp, 10000UL), score);
2375 }
2376
damos_goal_tune_esz_bp_temporal(struct damos_quota * quota)2377 static void damos_goal_tune_esz_bp_temporal(struct damos_quota *quota)
2378 {
2379 unsigned long score = damos_quota_score(quota);
2380
2381 if (score >= 10000)
2382 quota->esz_bp = 0;
2383 else if (quota->sz)
2384 quota->esz_bp = quota->sz * 10000;
2385 else
2386 quota->esz_bp = ULONG_MAX;
2387 }
2388
2389 /*
2390 * Called only if quota->ms, or quota->sz are set, or quota->goals is not empty
2391 */
damos_set_effective_quota(struct damos_quota * quota,struct damon_ctx * ctx)2392 static void damos_set_effective_quota(struct damos_quota *quota,
2393 struct damon_ctx *ctx)
2394 {
2395 unsigned long throughput;
2396 unsigned long esz = ULONG_MAX;
2397
2398 if (!quota->ms && list_empty("a->goals)) {
2399 quota->esz = quota->sz;
2400 return;
2401 }
2402
2403 if (!list_empty("a->goals)) {
2404 if (quota->goal_tuner == DAMOS_QUOTA_GOAL_TUNER_CONSIST)
2405 damos_goal_tune_esz_bp_consist(quota);
2406 else if (quota->goal_tuner == DAMOS_QUOTA_GOAL_TUNER_TEMPORAL)
2407 damos_goal_tune_esz_bp_temporal(quota);
2408 esz = quota->esz_bp / 10000;
2409 }
2410
2411 if (quota->ms) {
2412 if (quota->total_charged_ns)
2413 throughput = mult_frac(quota->total_charged_sz,
2414 1000000, quota->total_charged_ns);
2415 else
2416 throughput = PAGE_SIZE * 1024;
2417 esz = min(throughput * quota->ms, esz);
2418 esz = max(ctx->min_region_sz, esz);
2419 }
2420
2421 if (quota->sz && quota->sz < esz)
2422 esz = quota->sz;
2423
2424 quota->esz = esz;
2425 }
2426
damos_trace_esz(struct damon_ctx * c,struct damos * s,struct damos_quota * quota)2427 static void damos_trace_esz(struct damon_ctx *c, struct damos *s,
2428 struct damos_quota *quota)
2429 {
2430 unsigned int cidx = 0, sidx = 0;
2431 struct damos *siter;
2432
2433 damon_for_each_scheme(siter, c) {
2434 if (siter == s)
2435 break;
2436 sidx++;
2437 }
2438 trace_damos_esz(cidx, sidx, quota->esz);
2439 }
2440
damos_adjust_quota(struct damon_ctx * c,struct damos * s)2441 static void damos_adjust_quota(struct damon_ctx *c, struct damos *s)
2442 {
2443 struct damos_quota *quota = &s->quota;
2444 struct damon_target *t;
2445 struct damon_region *r;
2446 unsigned long cumulated_sz, cached_esz;
2447 unsigned int score, max_score = 0;
2448
2449 if (!quota->ms && !quota->sz && list_empty("a->goals))
2450 return;
2451
2452 /* First charge window */
2453 if (!quota->total_charged_sz && !quota->charged_from) {
2454 quota->charged_from = jiffies;
2455 damos_set_effective_quota(quota, c);
2456 }
2457
2458 /* New charge window starts */
2459 if (!time_in_range_open(jiffies, quota->charged_from,
2460 quota->charged_from +
2461 msecs_to_jiffies(quota->reset_interval))) {
2462 if (damos_quota_is_set(quota) &&
2463 quota->charged_sz >= quota->esz)
2464 s->stat.qt_exceeds++;
2465 quota->total_charged_sz += quota->charged_sz;
2466 quota->charged_from = jiffies;
2467 quota->charged_sz = 0;
2468 if (trace_damos_esz_enabled())
2469 cached_esz = quota->esz;
2470 damos_set_effective_quota(quota, c);
2471 if (trace_damos_esz_enabled() && quota->esz != cached_esz)
2472 damos_trace_esz(c, s, quota);
2473 }
2474
2475 if (!c->ops.get_scheme_score)
2476 return;
2477
2478 /* Fill up the score histogram */
2479 memset(c->regions_score_histogram, 0,
2480 sizeof(*c->regions_score_histogram) *
2481 (DAMOS_MAX_SCORE + 1));
2482 damon_for_each_target(t, c) {
2483 damon_for_each_region(r, t) {
2484 if (!__damos_valid_target(r, s))
2485 continue;
2486 if (damos_core_filter_out(c, t, r, s))
2487 continue;
2488 score = c->ops.get_scheme_score(c, r, s);
2489 c->regions_score_histogram[score] +=
2490 damon_sz_region(r);
2491 if (score > max_score)
2492 max_score = score;
2493 }
2494 }
2495
2496 /* Set the min score limit */
2497 for (cumulated_sz = 0, score = max_score; ; score--) {
2498 cumulated_sz += c->regions_score_histogram[score];
2499 if (cumulated_sz >= quota->esz || !score)
2500 break;
2501 }
2502 quota->min_score = score;
2503 }
2504
damos_trace_stat(struct damon_ctx * c,struct damos * s)2505 static void damos_trace_stat(struct damon_ctx *c, struct damos *s)
2506 {
2507 unsigned int cidx = 0, sidx = 0;
2508 struct damos *siter;
2509
2510 if (!trace_damos_stat_after_apply_interval_enabled())
2511 return;
2512
2513 damon_for_each_scheme(siter, c) {
2514 if (siter == s)
2515 break;
2516 sidx++;
2517 }
2518 trace_call__damos_stat_after_apply_interval(cidx, sidx, &s->stat);
2519 }
2520
kdamond_apply_schemes(struct damon_ctx * c)2521 static void kdamond_apply_schemes(struct damon_ctx *c)
2522 {
2523 struct damon_target *t;
2524 struct damon_region *r;
2525 struct damos *s;
2526 bool has_schemes_to_apply = false;
2527
2528 damon_for_each_scheme(s, c) {
2529 if (time_before(c->passed_sample_intervals, s->next_apply_sis))
2530 continue;
2531
2532 if (!s->wmarks.activated)
2533 continue;
2534
2535 has_schemes_to_apply = true;
2536
2537 damos_adjust_quota(c, s);
2538 }
2539
2540 if (!has_schemes_to_apply)
2541 return;
2542
2543 mutex_lock(&c->walk_control_lock);
2544 damon_for_each_target(t, c) {
2545 if (c->ops.target_valid && c->ops.target_valid(t) == false)
2546 continue;
2547
2548 damon_for_each_region(r, t)
2549 damon_do_apply_schemes(c, t, r);
2550 }
2551
2552 damon_for_each_scheme(s, c) {
2553 if (time_before(c->passed_sample_intervals, s->next_apply_sis))
2554 continue;
2555 damos_walk_complete(c, s);
2556 damos_set_next_apply_sis(s, c);
2557 s->last_applied = NULL;
2558 damos_trace_stat(c, s);
2559 }
2560 mutex_unlock(&c->walk_control_lock);
2561 }
2562
2563 #ifdef CONFIG_DAMON_DEBUG_SANITY
damon_verify_merge_two_regions(struct damon_region * l,struct damon_region * r)2564 static void damon_verify_merge_two_regions(
2565 struct damon_region *l, struct damon_region *r)
2566 {
2567 /* damon_merge_two_regions() may created incorrect left region */
2568 WARN_ONCE(l->ar.start >= l->ar.end, "l: %lu-%lu, r: %lu-%lu\n",
2569 l->ar.start, l->ar.end, r->ar.start, r->ar.end);
2570 }
2571 #else
damon_verify_merge_two_regions(struct damon_region * l,struct damon_region * r)2572 static void damon_verify_merge_two_regions(
2573 struct damon_region *l, struct damon_region *r)
2574 {
2575 }
2576 #endif
2577
2578 /*
2579 * Merge two adjacent regions into one region
2580 */
damon_merge_two_regions(struct damon_target * t,struct damon_region * l,struct damon_region * r)2581 static void damon_merge_two_regions(struct damon_target *t,
2582 struct damon_region *l, struct damon_region *r)
2583 {
2584 unsigned long sz_l = damon_sz_region(l), sz_r = damon_sz_region(r);
2585
2586 l->nr_accesses = (l->nr_accesses * sz_l + r->nr_accesses * sz_r) /
2587 (sz_l + sz_r);
2588 l->nr_accesses_bp = l->nr_accesses * 10000;
2589 l->age = (l->age * sz_l + r->age * sz_r) / (sz_l + sz_r);
2590 l->ar.end = r->ar.end;
2591 damon_verify_merge_two_regions(l, r);
2592 damon_destroy_region(r, t);
2593 }
2594
2595 #ifdef CONFIG_DAMON_DEBUG_SANITY
damon_verify_merge_regions_of(struct damon_region * r)2596 static void damon_verify_merge_regions_of(struct damon_region *r)
2597 {
2598 WARN_ONCE(r->nr_accesses != r->nr_accesses_bp / 10000,
2599 "nr_accesses (%u) != nr_accesses_bp (%u)\n",
2600 r->nr_accesses, r->nr_accesses_bp);
2601 }
2602 #else
damon_verify_merge_regions_of(struct damon_region * r)2603 static void damon_verify_merge_regions_of(struct damon_region *r)
2604 {
2605 }
2606 #endif
2607
2608
2609 /*
2610 * Merge adjacent regions having similar access frequencies
2611 *
2612 * t target affected by this merge operation
2613 * thres '->nr_accesses' diff threshold for the merge
2614 * sz_limit size upper limit of each region
2615 */
damon_merge_regions_of(struct damon_target * t,unsigned int thres,unsigned long sz_limit)2616 static void damon_merge_regions_of(struct damon_target *t, unsigned int thres,
2617 unsigned long sz_limit)
2618 {
2619 struct damon_region *r, *prev = NULL, *next;
2620
2621 damon_for_each_region_safe(r, next, t) {
2622 damon_verify_merge_regions_of(r);
2623 if (abs(r->nr_accesses - r->last_nr_accesses) > thres)
2624 r->age = 0;
2625 else if ((r->nr_accesses == 0) != (r->last_nr_accesses == 0))
2626 r->age = 0;
2627 else
2628 r->age++;
2629
2630 if (prev && prev->ar.end == r->ar.start &&
2631 abs(prev->nr_accesses - r->nr_accesses) <= thres &&
2632 damon_sz_region(prev) + damon_sz_region(r) <= sz_limit)
2633 damon_merge_two_regions(t, prev, r);
2634 else
2635 prev = r;
2636 }
2637 }
2638
2639 /*
2640 * Merge adjacent regions having similar access frequencies
2641 *
2642 * threshold '->nr_accesses' diff threshold for the merge
2643 * sz_limit size upper limit of each region
2644 *
2645 * This function merges monitoring target regions which are adjacent and their
2646 * access frequencies are similar. This is for minimizing the monitoring
2647 * overhead under the dynamically changeable access pattern. If a merge was
2648 * unnecessarily made, later 'kdamond_split_regions()' will revert it.
2649 *
2650 * The total number of regions could be higher than the user-defined limit,
2651 * max_nr_regions for some cases. For example, the user can update
2652 * max_nr_regions to a number that lower than the current number of regions
2653 * while DAMON is running. For such a case, repeat merging until the limit is
2654 * met while increasing @threshold up to possible maximum level.
2655 */
kdamond_merge_regions(struct damon_ctx * c,unsigned int threshold,unsigned long sz_limit)2656 static void kdamond_merge_regions(struct damon_ctx *c, unsigned int threshold,
2657 unsigned long sz_limit)
2658 {
2659 struct damon_target *t;
2660 unsigned int nr_regions;
2661 unsigned int max_thres;
2662
2663 max_thres = c->attrs.aggr_interval /
2664 (c->attrs.sample_interval ? c->attrs.sample_interval : 1);
2665 do {
2666 nr_regions = 0;
2667 damon_for_each_target(t, c) {
2668 damon_merge_regions_of(t, threshold, sz_limit);
2669 nr_regions += damon_nr_regions(t);
2670 }
2671 threshold = max(1, threshold * 2);
2672 } while (nr_regions > c->attrs.max_nr_regions &&
2673 threshold / 2 < max_thres);
2674 }
2675
2676 #ifdef CONFIG_DAMON_DEBUG_SANITY
damon_verify_split_region_at(struct damon_region * r,unsigned long sz_r)2677 static void damon_verify_split_region_at(struct damon_region *r,
2678 unsigned long sz_r)
2679 {
2680 WARN_ONCE(sz_r == 0 || sz_r >= damon_sz_region(r),
2681 "sz_r: %lu r: %lu-%lu (%lu)\n",
2682 sz_r, r->ar.start, r->ar.end, damon_sz_region(r));
2683 }
2684 #else
damon_verify_split_region_at(struct damon_region * r,unsigned long sz_r)2685 static void damon_verify_split_region_at(struct damon_region *r,
2686 unsigned long sz_r)
2687 {
2688 }
2689 #endif
2690
2691 /*
2692 * Split a region in two
2693 *
2694 * r the region to be split
2695 * sz_r size of the first sub-region that will be made
2696 */
damon_split_region_at(struct damon_target * t,struct damon_region * r,unsigned long sz_r)2697 static void damon_split_region_at(struct damon_target *t,
2698 struct damon_region *r, unsigned long sz_r)
2699 {
2700 struct damon_region *new;
2701
2702 damon_verify_split_region_at(r, sz_r);
2703 new = damon_new_region(r->ar.start + sz_r, r->ar.end);
2704 if (!new)
2705 return;
2706
2707 r->ar.end = new->ar.start;
2708
2709 new->age = r->age;
2710 new->last_nr_accesses = r->last_nr_accesses;
2711 new->nr_accesses_bp = r->nr_accesses_bp;
2712 new->nr_accesses = r->nr_accesses;
2713
2714 damon_insert_region(new, r, damon_next_region(r), t);
2715 }
2716
2717 /* Split every region in the given target into 'nr_subs' regions */
damon_split_regions_of(struct damon_target * t,int nr_subs,unsigned long min_region_sz)2718 static void damon_split_regions_of(struct damon_target *t, int nr_subs,
2719 unsigned long min_region_sz)
2720 {
2721 struct damon_region *r, *next;
2722 unsigned long sz_region, sz_sub = 0;
2723 int i;
2724
2725 damon_for_each_region_safe(r, next, t) {
2726 sz_region = damon_sz_region(r);
2727
2728 for (i = 0; i < nr_subs - 1 &&
2729 sz_region > 2 * min_region_sz; i++) {
2730 /*
2731 * Randomly select size of left sub-region to be at
2732 * least 10 percent and at most 90% of original region
2733 */
2734 sz_sub = ALIGN_DOWN(damon_rand(1, 10) *
2735 sz_region / 10, min_region_sz);
2736 /* Do not allow blank region */
2737 if (sz_sub == 0 || sz_sub >= sz_region)
2738 continue;
2739
2740 damon_split_region_at(t, r, sz_sub);
2741 sz_region = sz_sub;
2742 }
2743 }
2744 }
2745
2746 /*
2747 * Split every target region into randomly-sized small regions
2748 *
2749 * This function splits every target region into random-sized small regions if
2750 * current total number of the regions is equal or smaller than half of the
2751 * user-specified maximum number of regions. This is for maximizing the
2752 * monitoring accuracy under the dynamically changeable access patterns. If a
2753 * split was unnecessarily made, later 'kdamond_merge_regions()' will revert
2754 * it.
2755 */
kdamond_split_regions(struct damon_ctx * ctx)2756 static void kdamond_split_regions(struct damon_ctx *ctx)
2757 {
2758 struct damon_target *t;
2759 unsigned int nr_regions = 0;
2760 static unsigned int last_nr_regions;
2761 int nr_subregions = 2;
2762
2763 damon_for_each_target(t, ctx)
2764 nr_regions += damon_nr_regions(t);
2765
2766 if (nr_regions > ctx->attrs.max_nr_regions / 2)
2767 return;
2768
2769 /* Maybe the middle of the region has different access frequency */
2770 if (last_nr_regions == nr_regions &&
2771 nr_regions < ctx->attrs.max_nr_regions / 3)
2772 nr_subregions = 3;
2773
2774 damon_for_each_target(t, ctx)
2775 damon_split_regions_of(t, nr_subregions, ctx->min_region_sz);
2776
2777 last_nr_regions = nr_regions;
2778 }
2779
2780 /*
2781 * Check whether current monitoring should be stopped
2782 *
2783 * The monitoring is stopped when either the user requested to stop, or all
2784 * monitoring targets are invalid.
2785 *
2786 * Returns true if need to stop current monitoring.
2787 */
kdamond_need_stop(struct damon_ctx * ctx)2788 static bool kdamond_need_stop(struct damon_ctx *ctx)
2789 {
2790 struct damon_target *t;
2791
2792 if (kthread_should_stop())
2793 return true;
2794
2795 if (!ctx->ops.target_valid)
2796 return false;
2797
2798 damon_for_each_target(t, ctx) {
2799 if (ctx->ops.target_valid(t))
2800 return false;
2801 }
2802
2803 return true;
2804 }
2805
damos_get_wmark_metric_value(enum damos_wmark_metric metric,unsigned long * metric_value)2806 static int damos_get_wmark_metric_value(enum damos_wmark_metric metric,
2807 unsigned long *metric_value)
2808 {
2809 switch (metric) {
2810 case DAMOS_WMARK_FREE_MEM_RATE:
2811 *metric_value = global_zone_page_state(NR_FREE_PAGES) * 1000 /
2812 totalram_pages();
2813 return 0;
2814 default:
2815 break;
2816 }
2817 return -EINVAL;
2818 }
2819
2820 /*
2821 * Returns zero if the scheme is active. Else, returns time to wait for next
2822 * watermark check in micro-seconds.
2823 */
damos_wmark_wait_us(struct damos * scheme)2824 static unsigned long damos_wmark_wait_us(struct damos *scheme)
2825 {
2826 unsigned long metric;
2827
2828 if (damos_get_wmark_metric_value(scheme->wmarks.metric, &metric))
2829 return 0;
2830
2831 /* higher than high watermark or lower than low watermark */
2832 if (metric > scheme->wmarks.high || scheme->wmarks.low > metric) {
2833 if (scheme->wmarks.activated)
2834 pr_debug("deactivate a scheme (%d) for %s wmark\n",
2835 scheme->action,
2836 str_high_low(metric > scheme->wmarks.high));
2837 scheme->wmarks.activated = false;
2838 return scheme->wmarks.interval;
2839 }
2840
2841 /* inactive and higher than middle watermark */
2842 if ((scheme->wmarks.high >= metric && metric >= scheme->wmarks.mid) &&
2843 !scheme->wmarks.activated)
2844 return scheme->wmarks.interval;
2845
2846 if (!scheme->wmarks.activated)
2847 pr_debug("activate a scheme (%d)\n", scheme->action);
2848 scheme->wmarks.activated = true;
2849 return 0;
2850 }
2851
kdamond_usleep(unsigned long usecs)2852 static void kdamond_usleep(unsigned long usecs)
2853 {
2854 if (usecs >= USLEEP_RANGE_UPPER_BOUND)
2855 schedule_timeout_idle(usecs_to_jiffies(usecs));
2856 else
2857 usleep_range_idle(usecs, usecs + 1);
2858 }
2859
2860 /*
2861 * kdamond_call() - handle damon_call_control objects.
2862 * @ctx: The &struct damon_ctx of the kdamond.
2863 * @cancel: Whether to cancel the invocation of the function.
2864 *
2865 * If there are &struct damon_call_control requests that registered via
2866 * &damon_call() on @ctx, do or cancel the invocation of the function depending
2867 * on @cancel. @cancel is set when the kdamond is already out of the main loop
2868 * and therefore will be terminated.
2869 */
kdamond_call(struct damon_ctx * ctx,bool cancel)2870 static void kdamond_call(struct damon_ctx *ctx, bool cancel)
2871 {
2872 struct damon_call_control *control, *next;
2873 LIST_HEAD(controls);
2874
2875 mutex_lock(&ctx->call_controls_lock);
2876 list_splice_tail_init(&ctx->call_controls, &controls);
2877 mutex_unlock(&ctx->call_controls_lock);
2878
2879 list_for_each_entry_safe(control, next, &controls, list) {
2880 if (!control->repeat || cancel)
2881 list_del(&control->list);
2882
2883 if (cancel)
2884 control->canceled = true;
2885 else
2886 control->return_code = control->fn(control->data);
2887
2888 if (!control->repeat)
2889 complete(&control->completion);
2890 else if (control->canceled && control->dealloc_on_cancel)
2891 kfree(control);
2892 if (!cancel && ctx->maybe_corrupted)
2893 break;
2894 }
2895
2896 mutex_lock(&ctx->call_controls_lock);
2897 list_splice_tail(&controls, &ctx->call_controls);
2898 mutex_unlock(&ctx->call_controls_lock);
2899 }
2900
2901 /* Returns negative error code if it's not activated but should return */
kdamond_wait_activation(struct damon_ctx * ctx)2902 static int kdamond_wait_activation(struct damon_ctx *ctx)
2903 {
2904 struct damos *s;
2905 unsigned long wait_time;
2906 unsigned long min_wait_time = 0;
2907 bool init_wait_time = false;
2908
2909 while (!kdamond_need_stop(ctx)) {
2910 damon_for_each_scheme(s, ctx) {
2911 wait_time = damos_wmark_wait_us(s);
2912 if (!init_wait_time || wait_time < min_wait_time) {
2913 init_wait_time = true;
2914 min_wait_time = wait_time;
2915 }
2916 }
2917 if (!min_wait_time)
2918 return 0;
2919
2920 kdamond_usleep(min_wait_time);
2921
2922 kdamond_call(ctx, false);
2923 if (ctx->maybe_corrupted)
2924 return -EINVAL;
2925 damos_walk_cancel(ctx);
2926 }
2927 return -EBUSY;
2928 }
2929
kdamond_init_ctx(struct damon_ctx * ctx)2930 static void kdamond_init_ctx(struct damon_ctx *ctx)
2931 {
2932 unsigned long sample_interval = ctx->attrs.sample_interval ?
2933 ctx->attrs.sample_interval : 1;
2934 struct damos *scheme;
2935
2936 ctx->passed_sample_intervals = 0;
2937 ctx->next_aggregation_sis = ctx->attrs.aggr_interval / sample_interval;
2938 ctx->next_ops_update_sis = ctx->attrs.ops_update_interval /
2939 sample_interval;
2940 ctx->next_intervals_tune_sis = ctx->next_aggregation_sis *
2941 ctx->attrs.intervals_goal.aggrs;
2942
2943 damon_for_each_scheme(scheme, ctx) {
2944 damos_set_next_apply_sis(scheme, ctx);
2945 damos_set_filters_default_reject(scheme);
2946 }
2947 }
2948
2949 /*
2950 * The monitoring daemon that runs as a kernel thread
2951 */
kdamond_fn(void * data)2952 static int kdamond_fn(void *data)
2953 {
2954 struct damon_ctx *ctx = data;
2955 unsigned int max_nr_accesses = 0;
2956 unsigned long sz_limit = 0;
2957
2958 pr_debug("kdamond (%d) starts\n", current->pid);
2959
2960 mutex_lock(&ctx->call_controls_lock);
2961 ctx->call_controls_obsolete = false;
2962 mutex_unlock(&ctx->call_controls_lock);
2963 mutex_lock(&ctx->walk_control_lock);
2964 ctx->walk_control_obsolete = false;
2965 mutex_unlock(&ctx->walk_control_lock);
2966 complete(&ctx->kdamond_started);
2967 kdamond_init_ctx(ctx);
2968
2969 if (ctx->ops.init)
2970 ctx->ops.init(ctx);
2971 ctx->regions_score_histogram = kmalloc_array(DAMOS_MAX_SCORE + 1,
2972 sizeof(*ctx->regions_score_histogram), GFP_KERNEL);
2973 if (!ctx->regions_score_histogram)
2974 goto done;
2975
2976 sz_limit = damon_apply_min_nr_regions(ctx);
2977
2978 while (!kdamond_need_stop(ctx)) {
2979 /*
2980 * ctx->attrs and ctx->next_{aggregation,ops_update}_sis could
2981 * be changed from kdamond_call(). Read the values here, and
2982 * use those for this iteration. That is, damon_set_attrs()
2983 * updated new values are respected from next iteration.
2984 */
2985 unsigned long next_aggregation_sis = ctx->next_aggregation_sis;
2986 unsigned long next_ops_update_sis = ctx->next_ops_update_sis;
2987 unsigned long sample_interval = ctx->attrs.sample_interval;
2988
2989 if (kdamond_wait_activation(ctx))
2990 break;
2991
2992 if (ctx->ops.prepare_access_checks)
2993 ctx->ops.prepare_access_checks(ctx);
2994
2995 kdamond_usleep(sample_interval);
2996 ctx->passed_sample_intervals++;
2997
2998 if (ctx->ops.check_accesses)
2999 max_nr_accesses = ctx->ops.check_accesses(ctx);
3000
3001 if (time_after_eq(ctx->passed_sample_intervals,
3002 next_aggregation_sis)) {
3003 kdamond_merge_regions(ctx,
3004 max_nr_accesses / 10,
3005 sz_limit);
3006 /* online updates might be made */
3007 sz_limit = damon_apply_min_nr_regions(ctx);
3008 }
3009
3010 /*
3011 * do kdamond_call() and kdamond_apply_schemes() after
3012 * kdamond_merge_regions() if possible, to reduce overhead
3013 */
3014 kdamond_call(ctx, false);
3015 if (ctx->maybe_corrupted)
3016 break;
3017 if (!list_empty(&ctx->schemes))
3018 kdamond_apply_schemes(ctx);
3019 else
3020 damos_walk_cancel(ctx);
3021
3022 sample_interval = ctx->attrs.sample_interval ?
3023 ctx->attrs.sample_interval : 1;
3024 if (time_after_eq(ctx->passed_sample_intervals,
3025 next_aggregation_sis)) {
3026 if (ctx->attrs.intervals_goal.aggrs &&
3027 time_after_eq(
3028 ctx->passed_sample_intervals,
3029 ctx->next_intervals_tune_sis)) {
3030 /*
3031 * ctx->next_aggregation_sis might be updated
3032 * from kdamond_call(). In the case,
3033 * damon_set_attrs() which will be called from
3034 * kdamond_tune_interval() may wrongly think
3035 * this is in the middle of the current
3036 * aggregation, and make aggregation
3037 * information reset for all regions. Then,
3038 * following kdamond_reset_aggregated() call
3039 * will make the region information invalid,
3040 * particularly for ->nr_accesses_bp.
3041 *
3042 * Reset ->next_aggregation_sis to avoid that.
3043 * It will anyway correctly updated after this
3044 * if clause.
3045 */
3046 ctx->next_aggregation_sis =
3047 next_aggregation_sis;
3048 ctx->next_intervals_tune_sis +=
3049 ctx->attrs.aggr_samples *
3050 ctx->attrs.intervals_goal.aggrs;
3051 kdamond_tune_intervals(ctx);
3052 sample_interval = ctx->attrs.sample_interval ?
3053 ctx->attrs.sample_interval : 1;
3054
3055 }
3056 ctx->next_aggregation_sis = next_aggregation_sis +
3057 ctx->attrs.aggr_interval / sample_interval;
3058
3059 kdamond_reset_aggregated(ctx);
3060 kdamond_split_regions(ctx);
3061 }
3062
3063 if (time_after_eq(ctx->passed_sample_intervals,
3064 next_ops_update_sis)) {
3065 ctx->next_ops_update_sis = next_ops_update_sis +
3066 ctx->attrs.ops_update_interval /
3067 sample_interval;
3068 if (ctx->ops.update)
3069 ctx->ops.update(ctx);
3070 }
3071 }
3072 done:
3073 damon_destroy_targets(ctx);
3074
3075 kfree(ctx->regions_score_histogram);
3076 mutex_lock(&ctx->call_controls_lock);
3077 ctx->call_controls_obsolete = true;
3078 mutex_unlock(&ctx->call_controls_lock);
3079 kdamond_call(ctx, true);
3080 mutex_lock(&ctx->walk_control_lock);
3081 ctx->walk_control_obsolete = true;
3082 mutex_unlock(&ctx->walk_control_lock);
3083 damos_walk_cancel(ctx);
3084
3085 pr_debug("kdamond (%d) finishes\n", current->pid);
3086 mutex_lock(&ctx->kdamond_lock);
3087 ctx->kdamond = NULL;
3088 mutex_unlock(&ctx->kdamond_lock);
3089
3090 mutex_lock(&damon_lock);
3091 nr_running_ctxs--;
3092 if (!nr_running_ctxs && running_exclusive_ctxs)
3093 running_exclusive_ctxs = false;
3094 mutex_unlock(&damon_lock);
3095
3096 return 0;
3097 }
3098
walk_system_ram(struct resource * res,void * arg)3099 static int walk_system_ram(struct resource *res, void *arg)
3100 {
3101 struct resource *a = arg;
3102
3103 if (resource_size(a) < resource_size(res)) {
3104 a->start = res->start;
3105 a->end = res->end;
3106 }
3107 return 0;
3108 }
3109
damon_res_to_core_addr(resource_size_t ra,unsigned long addr_unit)3110 static unsigned long damon_res_to_core_addr(resource_size_t ra,
3111 unsigned long addr_unit)
3112 {
3113 /*
3114 * Use div_u64() for avoiding linking errors related with __udivdi3,
3115 * __aeabi_uldivmod, or similar problems. This should also improve the
3116 * performance optimization (read div_u64() comment for the detail).
3117 */
3118 if (sizeof(ra) == 8 && sizeof(addr_unit) == 4)
3119 return div_u64(ra, addr_unit);
3120 return ra / addr_unit;
3121 }
3122
3123 /*
3124 * Find biggest 'System RAM' resource and store its start and end address in
3125 * @start and @end, respectively. If no System RAM is found, returns false.
3126 */
damon_find_biggest_system_ram(unsigned long * start,unsigned long * end,unsigned long addr_unit)3127 static bool damon_find_biggest_system_ram(unsigned long *start,
3128 unsigned long *end, unsigned long addr_unit)
3129
3130 {
3131 struct resource res = {};
3132
3133 walk_system_ram_res(0, -1, &res, walk_system_ram);
3134 *start = damon_res_to_core_addr(res.start, addr_unit);
3135 *end = damon_res_to_core_addr(res.end + 1, addr_unit);
3136 if (*end <= *start)
3137 return false;
3138 return true;
3139 }
3140
3141 /**
3142 * damon_set_region_biggest_system_ram_default() - Set the region of the given
3143 * monitoring target as requested, or biggest 'System RAM'.
3144 * @t: The monitoring target to set the region.
3145 * @start: The pointer to the start address of the region.
3146 * @end: The pointer to the end address of the region.
3147 * @addr_unit: The address unit for the damon_ctx of @t.
3148 * @min_region_sz: Minimum region size.
3149 *
3150 * This function sets the region of @t as requested by @start and @end. If the
3151 * values of @start and @end are zero, however, this function finds the biggest
3152 * 'System RAM' resource and sets the region to cover the resource. In the
3153 * latter case, this function saves the start and end addresses of the resource
3154 * in @start and @end, respectively.
3155 *
3156 * Return: 0 on success, negative error code otherwise.
3157 */
damon_set_region_biggest_system_ram_default(struct damon_target * t,unsigned long * start,unsigned long * end,unsigned long addr_unit,unsigned long min_region_sz)3158 int damon_set_region_biggest_system_ram_default(struct damon_target *t,
3159 unsigned long *start, unsigned long *end,
3160 unsigned long addr_unit, unsigned long min_region_sz)
3161 {
3162 struct damon_addr_range addr_range;
3163
3164 if (*start > *end)
3165 return -EINVAL;
3166
3167 if (!*start && !*end &&
3168 !damon_find_biggest_system_ram(start, end, addr_unit))
3169 return -EINVAL;
3170
3171 addr_range.start = *start;
3172 addr_range.end = *end;
3173 return damon_set_regions(t, &addr_range, 1, min_region_sz);
3174 }
3175
3176 /*
3177 * damon_moving_sum() - Calculate an inferred moving sum value.
3178 * @mvsum: Inferred sum of the last @len_window values.
3179 * @nomvsum: Non-moving sum of the last discrete @len_window window values.
3180 * @len_window: The number of last values to take care of.
3181 * @new_value: New value that will be added to the pseudo moving sum.
3182 *
3183 * Moving sum (moving average * window size) is good for handling noise, but
3184 * the cost of keeping past values can be high for arbitrary window size. This
3185 * function implements a lightweight pseudo moving sum function that doesn't
3186 * keep the past window values.
3187 *
3188 * It simply assumes there was no noise in the past, and get the no-noise
3189 * assumed past value to drop from @nomvsum and @len_window. @nomvsum is a
3190 * non-moving sum of the last window. For example, if @len_window is 10 and we
3191 * have 25 values, @nomvsum is the sum of the 11th to 20th values of the 25
3192 * values. Hence, this function simply drops @nomvsum / @len_window from
3193 * given @mvsum and add @new_value.
3194 *
3195 * For example, if @len_window is 10 and @nomvsum is 50, the last 10 values for
3196 * the last window could be vary, e.g., 0, 10, 0, 10, 0, 10, 0, 0, 0, 20. For
3197 * calculating next moving sum with a new value, we should drop 0 from 50 and
3198 * add the new value. However, this function assumes it got value 5 for each
3199 * of the last ten times. Based on the assumption, when the next value is
3200 * measured, it drops the assumed past value, 5 from the current sum, and add
3201 * the new value to get the updated pseduo-moving average.
3202 *
3203 * This means the value could have errors, but the errors will be disappeared
3204 * for every @len_window aligned calls. For example, if @len_window is 10, the
3205 * pseudo moving sum with 11th value to 19th value would have an error. But
3206 * the sum with 20th value will not have the error.
3207 *
3208 * Return: Pseudo-moving average after getting the @new_value.
3209 */
damon_moving_sum(unsigned int mvsum,unsigned int nomvsum,unsigned int len_window,unsigned int new_value)3210 static unsigned int damon_moving_sum(unsigned int mvsum, unsigned int nomvsum,
3211 unsigned int len_window, unsigned int new_value)
3212 {
3213 return mvsum - nomvsum / len_window + new_value;
3214 }
3215
3216 /**
3217 * damon_update_region_access_rate() - Update the access rate of a region.
3218 * @r: The DAMON region to update for its access check result.
3219 * @accessed: Whether the region has accessed during last sampling interval.
3220 * @attrs: The damon_attrs of the DAMON context.
3221 *
3222 * Update the access rate of a region with the region's last sampling interval
3223 * access check result.
3224 *
3225 * Usually this will be called by &damon_operations->check_accesses callback.
3226 */
damon_update_region_access_rate(struct damon_region * r,bool accessed,struct damon_attrs * attrs)3227 void damon_update_region_access_rate(struct damon_region *r, bool accessed,
3228 struct damon_attrs *attrs)
3229 {
3230 unsigned int len_window = 1;
3231
3232 /*
3233 * sample_interval can be zero, but cannot be larger than
3234 * aggr_interval, owing to validation of damon_set_attrs().
3235 */
3236 if (attrs->sample_interval)
3237 len_window = damon_max_nr_accesses(attrs);
3238 r->nr_accesses_bp = damon_moving_sum(r->nr_accesses_bp,
3239 r->last_nr_accesses * 10000, len_window,
3240 accessed ? 10000 : 0);
3241
3242 if (accessed)
3243 r->nr_accesses++;
3244 }
3245
3246 /**
3247 * damon_initialized() - Return if DAMON is ready to be used.
3248 *
3249 * Return: true if DAMON is ready to be used, false otherwise.
3250 */
damon_initialized(void)3251 bool damon_initialized(void)
3252 {
3253 return damon_region_cache != NULL;
3254 }
3255
damon_init(void)3256 static int __init damon_init(void)
3257 {
3258 damon_region_cache = KMEM_CACHE(damon_region, 0);
3259 if (unlikely(!damon_region_cache)) {
3260 pr_err("creating damon_region_cache fails\n");
3261 return -ENOMEM;
3262 }
3263
3264 return 0;
3265 }
3266
3267 subsys_initcall(damon_init);
3268
3269 #include "tests/core-kunit.h"
3270