xref: /linux/mm/damon/tests/core-kunit.h (revision 21ef2d065ad3f0cfbf2ae51260bf962a9fa2c643)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Data Access Monitor Unit Tests
4  */
5 
6 #ifdef CONFIG_DAMON_KUNIT_TEST
7 
8 #ifndef _DAMON_CORE_TEST_H
9 #define _DAMON_CORE_TEST_H
10 
11 #include <kunit/test.h>
12 
13 static void damon_test_regions(struct kunit *test)
14 {
15 	struct damon_region *r;
16 	struct damon_target *t;
17 
18 	r = damon_new_region(1, 2);
19 	if (!r)
20 		kunit_skip(test, "region alloc fail");
21 	KUNIT_EXPECT_EQ(test, 1ul, r->ar.start);
22 	KUNIT_EXPECT_EQ(test, 2ul, r->ar.end);
23 	KUNIT_EXPECT_EQ(test, 0u, r->nr_accesses);
24 
25 	t = damon_new_target();
26 	if (!t) {
27 		damon_free_region(r);
28 		kunit_skip(test, "target alloc fail");
29 	}
30 	KUNIT_EXPECT_EQ(test, 0u, damon_nr_regions(t));
31 
32 	damon_add_region(r, t);
33 	KUNIT_EXPECT_EQ(test, 1u, damon_nr_regions(t));
34 
35 	damon_destroy_region(r, t);
36 	KUNIT_EXPECT_EQ(test, 0u, damon_nr_regions(t));
37 
38 	damon_free_target(t);
39 }
40 
41 static unsigned int nr_damon_targets(struct damon_ctx *ctx)
42 {
43 	struct damon_target *t;
44 	unsigned int nr_targets = 0;
45 
46 	damon_for_each_target(t, ctx)
47 		nr_targets++;
48 
49 	return nr_targets;
50 }
51 
52 static void damon_test_target(struct kunit *test)
53 {
54 	struct damon_ctx *c = damon_new_ctx();
55 	struct damon_target *t;
56 
57 	if (!c)
58 		kunit_skip(test, "ctx alloc fail");
59 
60 	t = damon_new_target();
61 	if (!t) {
62 		damon_destroy_ctx(c);
63 		kunit_skip(test, "target alloc fail");
64 	}
65 	KUNIT_EXPECT_EQ(test, 0u, nr_damon_targets(c));
66 
67 	damon_add_target(c, t);
68 	KUNIT_EXPECT_EQ(test, 1u, nr_damon_targets(c));
69 
70 	damon_destroy_target(t, c);
71 	KUNIT_EXPECT_EQ(test, 0u, nr_damon_targets(c));
72 
73 	damon_destroy_ctx(c);
74 }
75 
76 /*
77  * Test kdamond_reset_aggregated()
78  *
79  * DAMON checks access to each region and aggregates this information as the
80  * access frequency of each region.  In detail, it increases '->nr_accesses' of
81  * regions that an access has confirmed.  'kdamond_reset_aggregated()' flushes
82  * the aggregated information ('->nr_accesses' of each regions) to the result
83  * buffer.  As a result of the flushing, the '->nr_accesses' of regions are
84  * initialized to zero.
85  */
86 static void damon_test_aggregate(struct kunit *test)
87 {
88 	struct damon_ctx *ctx = damon_new_ctx();
89 	unsigned long saddr[][3] = {{10, 20, 30}, {5, 42, 49}, {13, 33, 55} };
90 	unsigned long eaddr[][3] = {{15, 27, 40}, {31, 45, 55}, {23, 44, 66} };
91 	unsigned long accesses[][3] = {{42, 95, 84}, {10, 20, 30}, {0, 1, 2} };
92 	struct damon_target *t;
93 	struct damon_region *r;
94 	int it, ir;
95 
96 	if (!ctx)
97 		kunit_skip(test, "ctx alloc fail");
98 
99 	for (it = 0; it < 3; it++) {
100 		t = damon_new_target();
101 		if (!t) {
102 			damon_destroy_ctx(ctx);
103 			kunit_skip(test, "target alloc fail");
104 		}
105 		damon_add_target(ctx, t);
106 	}
107 
108 	it = 0;
109 	damon_for_each_target(t, ctx) {
110 		for (ir = 0; ir < 3; ir++) {
111 			r = damon_new_region(saddr[it][ir], eaddr[it][ir]);
112 			if (!r) {
113 				damon_destroy_ctx(ctx);
114 				kunit_skip(test, "region alloc fail");
115 			}
116 			r->nr_accesses = accesses[it][ir];
117 			r->nr_accesses_bp = accesses[it][ir] * 10000;
118 			damon_add_region(r, t);
119 		}
120 		it++;
121 	}
122 	kdamond_reset_aggregated(ctx);
123 	it = 0;
124 	damon_for_each_target(t, ctx) {
125 		ir = 0;
126 		/* '->nr_accesses' should be zeroed */
127 		damon_for_each_region(r, t) {
128 			KUNIT_EXPECT_EQ(test, 0u, r->nr_accesses);
129 			ir++;
130 		}
131 		/* regions should be preserved */
132 		KUNIT_EXPECT_EQ(test, 3, ir);
133 		it++;
134 	}
135 	/* targets also should be preserved */
136 	KUNIT_EXPECT_EQ(test, 3, it);
137 
138 	damon_destroy_ctx(ctx);
139 }
140 
141 static void damon_test_split_at(struct kunit *test)
142 {
143 	struct damon_target *t;
144 	struct damon_region *r, *r_new;
145 
146 	t = damon_new_target();
147 	if (!t)
148 		kunit_skip(test, "target alloc fail");
149 	r = damon_new_region(0, 100);
150 	if (!r) {
151 		damon_free_target(t);
152 		kunit_skip(test, "region alloc fail");
153 	}
154 	r->nr_accesses_bp = 420000;
155 	r->nr_accesses = 42;
156 	r->last_nr_accesses = 15;
157 	r->age = 10;
158 	damon_add_region(r, t);
159 	damon_split_region_at(t, r, 25);
160 	KUNIT_EXPECT_EQ(test, r->ar.start, 0ul);
161 	KUNIT_EXPECT_EQ(test, r->ar.end, 25ul);
162 
163 	r_new = damon_next_region(r);
164 	KUNIT_EXPECT_EQ(test, r_new->ar.start, 25ul);
165 	KUNIT_EXPECT_EQ(test, r_new->ar.end, 100ul);
166 
167 	KUNIT_EXPECT_EQ(test, r->nr_accesses_bp, r_new->nr_accesses_bp);
168 	KUNIT_EXPECT_EQ(test, r->nr_accesses, r_new->nr_accesses);
169 	KUNIT_EXPECT_EQ(test, r->last_nr_accesses, r_new->last_nr_accesses);
170 	KUNIT_EXPECT_EQ(test, r->age, r_new->age);
171 
172 	damon_free_target(t);
173 }
174 
175 static void damon_test_merge_two(struct kunit *test)
176 {
177 	struct damon_target *t;
178 	struct damon_region *r, *r2, *r3;
179 	int i;
180 
181 	t = damon_new_target();
182 	if (!t)
183 		kunit_skip(test, "target alloc fail");
184 	r = damon_new_region(0, 100);
185 	if (!r) {
186 		damon_free_target(t);
187 		kunit_skip(test, "region alloc fail");
188 	}
189 	r->nr_accesses = 10;
190 	r->nr_accesses_bp = 100000;
191 	r->age = 9;
192 	damon_add_region(r, t);
193 	r2 = damon_new_region(100, 300);
194 	if (!r2) {
195 		damon_free_target(t);
196 		kunit_skip(test, "second region alloc fail");
197 	}
198 	r2->nr_accesses = 20;
199 	r2->nr_accesses_bp = 200000;
200 	r2->age = 21;
201 	damon_add_region(r2, t);
202 
203 	damon_merge_two_regions(t, r, r2);
204 	KUNIT_EXPECT_EQ(test, r->ar.start, 0ul);
205 	KUNIT_EXPECT_EQ(test, r->ar.end, 300ul);
206 	KUNIT_EXPECT_EQ(test, r->nr_accesses, 16u);
207 	KUNIT_EXPECT_EQ(test, r->nr_accesses_bp, 160000u);
208 	KUNIT_EXPECT_EQ(test, r->age, 17u);
209 
210 	i = 0;
211 	damon_for_each_region(r3, t) {
212 		KUNIT_EXPECT_PTR_EQ(test, r, r3);
213 		i++;
214 	}
215 	KUNIT_EXPECT_EQ(test, i, 1);
216 
217 	damon_free_target(t);
218 }
219 
220 static struct damon_region *__nth_region_of(struct damon_target *t, int idx)
221 {
222 	struct damon_region *r;
223 	unsigned int i = 0;
224 
225 	damon_for_each_region(r, t) {
226 		if (i++ == idx)
227 			return r;
228 	}
229 
230 	return NULL;
231 }
232 
233 static void damon_test_merge_regions_of(struct kunit *test)
234 {
235 	struct damon_target *t;
236 	struct damon_region *r;
237 	unsigned long sa[] = {0, 100, 114, 122, 130, 156, 170, 184, 230};
238 	unsigned long ea[] = {100, 112, 122, 130, 156, 170, 184, 230, 10170};
239 	unsigned int nrs[] = {0, 0, 10, 10, 20, 30, 1, 2, 5};
240 
241 	unsigned long saddrs[] = {0, 114, 130, 156, 170, 230};
242 	unsigned long eaddrs[] = {112, 130, 156, 170, 230, 10170};
243 	int i;
244 
245 	t = damon_new_target();
246 	if (!t)
247 		kunit_skip(test, "target alloc fail");
248 	for (i = 0; i < ARRAY_SIZE(sa); i++) {
249 		r = damon_new_region(sa[i], ea[i]);
250 		if (!r) {
251 			damon_free_target(t);
252 			kunit_skip(test, "region alloc fail");
253 		}
254 		r->nr_accesses = nrs[i];
255 		r->nr_accesses_bp = nrs[i] * 10000;
256 		damon_add_region(r, t);
257 	}
258 
259 	damon_merge_regions_of(t, 9, 9999);
260 	/* 0-112, 114-130, 130-156, 156-170, 170-230, 230-10170 */
261 	KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 6u);
262 	for (i = 0; i < 6; i++) {
263 		r = __nth_region_of(t, i);
264 		KUNIT_EXPECT_EQ(test, r->ar.start, saddrs[i]);
265 		KUNIT_EXPECT_EQ(test, r->ar.end, eaddrs[i]);
266 	}
267 	damon_free_target(t);
268 }
269 
270 static void damon_test_split_regions_of(struct kunit *test)
271 {
272 	struct damon_ctx *c;
273 	struct damon_target *t;
274 	struct damon_region *r;
275 	unsigned long sa[] = {0, 300, 500};
276 	unsigned long ea[] = {220, 400, 700};
277 	int i;
278 
279 	c = damon_new_ctx();
280 	if (!c)
281 		kunit_skip(test, "ctx alloc fail");
282 
283 	t = damon_new_target();
284 	if (!t) {
285 		damon_destroy_ctx(c);
286 		kunit_skip(test, "target alloc fail");
287 	}
288 	r = damon_new_region(0, 22);
289 	if (!r) {
290 		damon_free_target(t);
291 		damon_destroy_ctx(c);
292 		kunit_skip(test, "region alloc fail");
293 	}
294 	damon_add_region(r, t);
295 	damon_split_regions_of(c, t, 2, 1);
296 	KUNIT_EXPECT_LE(test, damon_nr_regions(t), 2u);
297 	damon_free_target(t);
298 
299 	t = damon_new_target();
300 	if (!t) {
301 		damon_destroy_ctx(c);
302 		kunit_skip(test, "second target alloc fail");
303 	}
304 	r = damon_new_region(0, 220);
305 	if (!r) {
306 		damon_free_target(t);
307 		damon_destroy_ctx(c);
308 		kunit_skip(test, "second region alloc fail");
309 	}
310 	damon_add_region(r, t);
311 	damon_split_regions_of(c, t, 4, 1);
312 	KUNIT_EXPECT_LE(test, damon_nr_regions(t), 4u);
313 	damon_free_target(t);
314 
315 	t = damon_new_target();
316 	if (!t) {
317 		damon_destroy_ctx(c);
318 		kunit_skip(test, "third target alloc fail");
319 	}
320 	for (i = 0; i < ARRAY_SIZE(sa); i++) {
321 		r = damon_new_region(sa[i], ea[i]);
322 		if (!r) {
323 			damon_free_target(t);
324 			damon_destroy_ctx(c);
325 			kunit_skip(test, "region alloc fail");
326 		}
327 		damon_add_region(r, t);
328 	}
329 	damon_split_regions_of(c, t, 4, 5);
330 	KUNIT_EXPECT_LE(test, damon_nr_regions(t), 12u);
331 	damon_for_each_region(r, t)
332 		KUNIT_EXPECT_GE(test, damon_sz_region(r) % 5ul, 0ul);
333 	damon_free_target(t);
334 
335 	damon_destroy_ctx(c);
336 }
337 
338 static void damon_test_ops_registration(struct kunit *test)
339 {
340 	struct damon_ctx *c = damon_new_ctx();
341 	struct damon_operations ops = {.id = DAMON_OPS_VADDR}, bak;
342 	bool need_cleanup = false;
343 
344 	if (!c)
345 		kunit_skip(test, "ctx alloc fail");
346 
347 	/* DAMON_OPS_VADDR is registered only if CONFIG_DAMON_VADDR is set */
348 	if (!damon_is_registered_ops(DAMON_OPS_VADDR)) {
349 		bak.id = DAMON_OPS_VADDR;
350 		KUNIT_EXPECT_EQ(test, damon_register_ops(&bak), 0);
351 		need_cleanup = true;
352 	}
353 
354 	/* DAMON_OPS_VADDR is ensured to be registered */
355 	KUNIT_EXPECT_EQ(test, damon_select_ops(c, DAMON_OPS_VADDR), 0);
356 
357 	/* Double-registration is prohibited */
358 	KUNIT_EXPECT_EQ(test, damon_register_ops(&ops), -EINVAL);
359 
360 	/* Unknown ops id cannot be registered */
361 	KUNIT_EXPECT_EQ(test, damon_select_ops(c, NR_DAMON_OPS), -EINVAL);
362 
363 	/* Registration should success after unregistration */
364 	mutex_lock(&damon_ops_lock);
365 	bak = damon_registered_ops[DAMON_OPS_VADDR];
366 	damon_registered_ops[DAMON_OPS_VADDR] = (struct damon_operations){};
367 	mutex_unlock(&damon_ops_lock);
368 
369 	ops.id = DAMON_OPS_VADDR;
370 	KUNIT_EXPECT_EQ(test, damon_register_ops(&ops), 0);
371 
372 	mutex_lock(&damon_ops_lock);
373 	damon_registered_ops[DAMON_OPS_VADDR] = bak;
374 	mutex_unlock(&damon_ops_lock);
375 
376 	/* Check double-registration failure again */
377 	KUNIT_EXPECT_EQ(test, damon_register_ops(&ops), -EINVAL);
378 
379 	damon_destroy_ctx(c);
380 
381 	if (need_cleanup) {
382 		mutex_lock(&damon_ops_lock);
383 		damon_registered_ops[DAMON_OPS_VADDR] =
384 			(struct damon_operations){};
385 		mutex_unlock(&damon_ops_lock);
386 	}
387 }
388 
389 static void damon_test_set_regions_for(struct kunit *test,
390 		struct damon_addr_range *old_ranges, int sz_old_ranges,
391 		struct damon_addr_range *new_ranges, int sz_new_ranges,
392 		unsigned long min_region_sz,
393 		struct damon_addr_range *expect_ranges, int sz_expect_ranges)
394 {
395 	struct damon_target *t;
396 	struct damon_region *r;
397 	int i;
398 
399 	t = damon_new_target();
400 	if (!t)
401 		kunit_skip(test, "target alloc fail");
402 	for (i = 0; i < sz_old_ranges; i++) {
403 		r = damon_new_region(old_ranges[i].start, old_ranges[i].end);
404 		if (!r) {
405 			damon_destroy_target(t, NULL);
406 			kunit_skip(test, "%d-th r alloc fail\n", i);
407 		}
408 		damon_add_region(r, t);
409 	}
410 
411 	damon_set_regions(t, new_ranges, sz_new_ranges, min_region_sz);
412 
413 	KUNIT_EXPECT_EQ(test, damon_nr_regions(t), sz_expect_ranges);
414 	if (damon_nr_regions(t) != sz_expect_ranges) {
415 		damon_destroy_target(t, NULL);
416 		return;
417 	}
418 	i = 0;
419 	damon_for_each_region(r, t) {
420 		KUNIT_EXPECT_EQ(test, r->ar.start, expect_ranges[i].start);
421 		KUNIT_EXPECT_EQ(test, r->ar.end, expect_ranges[i++].end);
422 	}
423 
424 	damon_destroy_target(t, NULL);
425 }
426 
427 static void damon_test_set_regions(struct kunit *test)
428 {
429 	/* Initial build up on empty target. */
430 	damon_test_set_regions_for(test,
431 			(struct damon_addr_range[]){}, 0,
432 			(struct damon_addr_range[]){
433 			{.start = 5, .end = 15},
434 			{.start = 15, .end = 25},
435 			}, 2,
436 			1,
437 			(struct damon_addr_range[]){
438 			{.start = 5, .end = 15},
439 			{.start = 15, .end = 25},
440 			}, 2);
441 	/* Un-intersecting regions should be removed. */
442 	damon_test_set_regions_for(test,
443 			(struct damon_addr_range[]){
444 			{.start = 4, .end = 16},
445 			{.start = 24, .end = 32},
446 			}, 2,
447 			(struct damon_addr_range[]){
448 			{.start = 18, .end = 23},
449 			}, 1,
450 			1,
451 			(struct damon_addr_range[]){
452 			{.start = 18, .end = 23},
453 			}, 1);
454 	/*
455 	 * Holes should be filled up with new regions.
456 	 *
457 	 * old:       [4,   16)        [24,     32)
458 	 * new:         [8,                 28)
459 	 * expect:      [8, 16)[16,24),[24, 28)
460 	 */
461 	damon_test_set_regions_for(test,
462 			(struct damon_addr_range[]){
463 			{.start = 4, .end = 16},
464 			{.start = 24, .end = 32},
465 			}, 2,
466 			(struct damon_addr_range[]){
467 			{.start = 8, .end = 28},
468 			}, 1,
469 			1,
470 			(struct damon_addr_range[]){
471 			{.start = 8, .end = 16},
472 			{.start = 16, .end = 24},
473 			{.start = 24, .end = 28},
474 			}, 3);
475 	/*
476 	 * New regions should be able to be appended.
477 	 *
478 	 * old:       [0, 4)[4,    17)
479 	 * new:       [0,       15)     [25, 40)
480 	 * expect:    [0, 4)[4, 15)     [25, 40)
481 	 */
482 	damon_test_set_regions_for(test,
483 			(struct damon_addr_range[]){
484 			{.start = 0, .end = 4},
485 			{.start = 4, .end = 17},
486 			}, 2,
487 			(struct damon_addr_range[]){
488 			{.start = 0, .end = 15},
489 			{.start = 25, .end = 40},
490 			}, 2,
491 			1,
492 			(struct damon_addr_range[]){
493 			{.start = 0, .end = 4},
494 			{.start = 4, .end = 15},
495 			{.start = 25, .end = 40},
496 			}, 3);
497 	/*
498 	 * New regions should be able to be inserted.
499 	 *
500 	 * old:       [0, 4)                      [42,    52)
501 	 * new:       [0,       15)     [25, 40)    [44, 50)
502 	 * expect:    [0,       15)     [25, 40)    [44, 50)
503 	 */
504 	damon_test_set_regions_for(test,
505 			(struct damon_addr_range[]){
506 			{.start = 0, .end = 4},
507 			{.start = 42, .end = 52},
508 			}, 2,
509 			(struct damon_addr_range[]){
510 			{.start = 0, .end = 15},
511 			{.start = 25, .end = 40},
512 			{.start = 44, .end = 50},
513 			}, 3,
514 			1,
515 			(struct damon_addr_range[]){
516 			{.start = 0, .end = 15},
517 			{.start = 25, .end = 40},
518 			{.start = 44, .end = 50},
519 			}, 3);
520 }
521 
522 static void damon_test_nr_accesses_to_accesses_bp(struct kunit *test)
523 {
524 	struct damon_attrs attrs = {
525 		.sample_interval = 10,
526 		.aggr_interval = ((unsigned long)UINT_MAX + 1) * 10
527 	};
528 
529 	/*
530 	 * In some cases such as 32bit architectures where UINT_MAX is
531 	 * ULONG_MAX, attrs.aggr_interval becomes zero.  Calling
532 	 * damon_nr_accesses_to_accesses_bp() in the case will cause
533 	 * divide-by-zero.  Such case is prohibited in normal execution since
534 	 * the caution is documented on the comment for the function, and
535 	 * damon_update_monitoring_results() does the check.  Skip the test in
536 	 * the case.
537 	 */
538 	if (!attrs.aggr_interval)
539 		kunit_skip(test, "aggr_interval is zero.");
540 
541 	KUNIT_EXPECT_EQ(test, damon_nr_accesses_to_accesses_bp(123, &attrs), 0);
542 }
543 
544 static void damon_test_update_monitoring_result(struct kunit *test)
545 {
546 	struct damon_attrs old_attrs = {
547 		.sample_interval = 10, .aggr_interval = 1000,};
548 	struct damon_attrs new_attrs;
549 	struct damon_region *r = damon_new_region(3, 7);
550 
551 	if (!r)
552 		kunit_skip(test, "region alloc fail");
553 
554 	r->nr_accesses = 15;
555 	r->nr_accesses_bp = 150000;
556 	r->age = 20;
557 
558 	new_attrs = (struct damon_attrs){
559 		.sample_interval = 100, .aggr_interval = 10000,};
560 	damon_update_monitoring_result(r, &old_attrs, &new_attrs, false);
561 	KUNIT_EXPECT_EQ(test, r->nr_accesses, 15);
562 	KUNIT_EXPECT_EQ(test, r->age, 2);
563 
564 	new_attrs = (struct damon_attrs){
565 		.sample_interval = 1, .aggr_interval = 1000};
566 	damon_update_monitoring_result(r, &old_attrs, &new_attrs, false);
567 	KUNIT_EXPECT_EQ(test, r->nr_accesses, 150);
568 	KUNIT_EXPECT_EQ(test, r->age, 2);
569 
570 	new_attrs = (struct damon_attrs){
571 		.sample_interval = 1, .aggr_interval = 100};
572 	damon_update_monitoring_result(r, &old_attrs, &new_attrs, false);
573 	KUNIT_EXPECT_EQ(test, r->nr_accesses, 150);
574 	KUNIT_EXPECT_EQ(test, r->age, 20);
575 
576 	damon_free_region(r);
577 }
578 
579 static void damon_test_set_attrs(struct kunit *test)
580 {
581 	struct damon_ctx *c = damon_new_ctx();
582 	struct damon_attrs valid_attrs = {
583 		.min_nr_regions = 10, .max_nr_regions = 1000,
584 		.sample_interval = 5000, .aggr_interval = 100000,};
585 	struct damon_attrs invalid_attrs;
586 
587 	if (!c)
588 		kunit_skip(test, "ctx alloc fail");
589 
590 	KUNIT_EXPECT_EQ(test, damon_set_attrs(c, &valid_attrs), 0);
591 
592 	invalid_attrs = valid_attrs;
593 	invalid_attrs.min_nr_regions = 1;
594 	KUNIT_EXPECT_EQ(test, damon_set_attrs(c, &invalid_attrs), -EINVAL);
595 
596 	invalid_attrs = valid_attrs;
597 	invalid_attrs.max_nr_regions = 9;
598 	KUNIT_EXPECT_EQ(test, damon_set_attrs(c, &invalid_attrs), -EINVAL);
599 
600 	invalid_attrs = valid_attrs;
601 	invalid_attrs.aggr_interval = 4999;
602 	KUNIT_EXPECT_EQ(test, damon_set_attrs(c, &invalid_attrs), -EINVAL);
603 
604 	damon_destroy_ctx(c);
605 }
606 
607 static void damon_test_moving_sum(struct kunit *test)
608 {
609 	unsigned int mvsum = 50000, nomvsum = 50000, len_window = 10;
610 	unsigned int new_values[] = {10000, 0, 10000, 0, 0, 0, 10000, 0, 0, 0};
611 	unsigned int expects[] = {55000, 50000, 55000, 50000, 45000, 40000,
612 		45000, 40000, 35000, 30000};
613 	int i;
614 
615 	for (i = 0; i < ARRAY_SIZE(new_values); i++) {
616 		mvsum = damon_moving_sum(mvsum, nomvsum, len_window,
617 				new_values[i]);
618 		KUNIT_EXPECT_EQ(test, mvsum, expects[i]);
619 	}
620 }
621 
622 static void damos_test_new_filter(struct kunit *test)
623 {
624 	struct damos_filter *filter;
625 
626 	filter = damos_new_filter(DAMOS_FILTER_TYPE_ANON, true, false);
627 	if (!filter)
628 		kunit_skip(test, "filter alloc fail");
629 	KUNIT_EXPECT_EQ(test, filter->type, DAMOS_FILTER_TYPE_ANON);
630 	KUNIT_EXPECT_EQ(test, filter->matching, true);
631 	KUNIT_EXPECT_PTR_EQ(test, filter->list.prev, &filter->list);
632 	KUNIT_EXPECT_PTR_EQ(test, filter->list.next, &filter->list);
633 	damos_destroy_filter(filter);
634 }
635 
636 static void damos_test_commit_quota_goal_for(struct kunit *test,
637 		struct damos_quota_goal *dst,
638 		struct damos_quota_goal *src)
639 {
640 	u64 dst_last_psi_total = 0;
641 
642 	if (dst->metric == DAMOS_QUOTA_SOME_MEM_PSI_US)
643 		dst_last_psi_total = dst->last_psi_total;
644 	damos_commit_quota_goal(dst, src);
645 
646 	KUNIT_EXPECT_EQ(test, dst->metric, src->metric);
647 	KUNIT_EXPECT_EQ(test, dst->target_value, src->target_value);
648 	if (src->metric == DAMOS_QUOTA_USER_INPUT)
649 		KUNIT_EXPECT_EQ(test, dst->current_value, src->current_value);
650 	if (dst_last_psi_total && src->metric == DAMOS_QUOTA_SOME_MEM_PSI_US)
651 		KUNIT_EXPECT_EQ(test, dst->last_psi_total, dst_last_psi_total);
652 	switch (dst->metric) {
653 	case DAMOS_QUOTA_NODE_MEM_USED_BP:
654 	case DAMOS_QUOTA_NODE_MEM_FREE_BP:
655 		KUNIT_EXPECT_EQ(test, dst->nid, src->nid);
656 		break;
657 	case DAMOS_QUOTA_NODE_MEMCG_USED_BP:
658 	case DAMOS_QUOTA_NODE_MEMCG_FREE_BP:
659 		KUNIT_EXPECT_EQ(test, dst->nid, src->nid);
660 		KUNIT_EXPECT_EQ(test, dst->memcg_id, src->memcg_id);
661 		break;
662 	default:
663 		break;
664 	}
665 }
666 
667 static void damos_test_commit_quota_goal(struct kunit *test)
668 {
669 	struct damos_quota_goal dst = {
670 		.metric = DAMOS_QUOTA_SOME_MEM_PSI_US,
671 		.target_value = 1000,
672 		.current_value = 123,
673 		.last_psi_total = 456,
674 	};
675 
676 	damos_test_commit_quota_goal_for(test, &dst,
677 			&(struct damos_quota_goal){
678 			.metric = DAMOS_QUOTA_USER_INPUT,
679 			.target_value = 789,
680 			.current_value = 12});
681 	damos_test_commit_quota_goal_for(test, &dst,
682 			&(struct damos_quota_goal){
683 			.metric = DAMOS_QUOTA_NODE_MEM_FREE_BP,
684 			.target_value = 345,
685 			.current_value = 678,
686 			.nid = 9,
687 			});
688 	damos_test_commit_quota_goal_for(test, &dst,
689 			&(struct damos_quota_goal){
690 			.metric = DAMOS_QUOTA_NODE_MEM_USED_BP,
691 			.target_value = 12,
692 			.current_value = 345,
693 			.nid = 6,
694 			});
695 	damos_test_commit_quota_goal_for(test, &dst,
696 			&(struct damos_quota_goal){
697 			.metric = DAMOS_QUOTA_NODE_MEMCG_USED_BP,
698 			.target_value = 456,
699 			.current_value = 567,
700 			.nid = 6,
701 			.memcg_id = 7,
702 			});
703 	damos_test_commit_quota_goal_for(test, &dst,
704 			&(struct damos_quota_goal){
705 			.metric = DAMOS_QUOTA_NODE_MEMCG_FREE_BP,
706 			.target_value = 890,
707 			.current_value = 901,
708 			.nid = 10,
709 			.memcg_id = 1,
710 			});
711 	damos_test_commit_quota_goal_for(test, &dst,
712 			&(struct damos_quota_goal) {
713 			.metric = DAMOS_QUOTA_SOME_MEM_PSI_US,
714 			.target_value = 234,
715 			.current_value = 345,
716 			.last_psi_total = 567,
717 			});
718 }
719 
720 static void damos_test_commit_quota_goals_for(struct kunit *test,
721 		struct damos_quota_goal *dst_goals, int nr_dst_goals,
722 		struct damos_quota_goal *src_goals, int nr_src_goals)
723 {
724 	struct damos_quota dst, src;
725 	struct damos_quota_goal *goal, *next;
726 	bool skip = true;
727 	int i;
728 
729 	INIT_LIST_HEAD(&dst.goals);
730 	INIT_LIST_HEAD(&src.goals);
731 
732 	for (i = 0; i < nr_dst_goals; i++) {
733 		/*
734 		 * When nr_src_goals is smaller than dst_goals,
735 		 * damos_commit_quota_goals() will kfree() the dst goals.
736 		 * Make it kfree()-able.
737 		 */
738 		goal = damos_new_quota_goal(dst_goals[i].metric,
739 				dst_goals[i].target_value);
740 		if (!goal)
741 			goto out;
742 		damos_add_quota_goal(&dst, goal);
743 	}
744 	skip = false;
745 	for (i = 0; i < nr_src_goals; i++)
746 		damos_add_quota_goal(&src, &src_goals[i]);
747 
748 	damos_commit_quota_goals(&dst, &src);
749 
750 	i = 0;
751 	damos_for_each_quota_goal(goal, (&dst)) {
752 		KUNIT_EXPECT_EQ(test, goal->metric, src_goals[i].metric);
753 		KUNIT_EXPECT_EQ(test, goal->target_value,
754 				src_goals[i++].target_value);
755 	}
756 	KUNIT_EXPECT_EQ(test, i, nr_src_goals);
757 
758 out:
759 	damos_for_each_quota_goal_safe(goal, next, (&dst))
760 		damos_destroy_quota_goal(goal);
761 	if (skip)
762 		kunit_skip(test, "goal alloc fail");
763 }
764 
765 static void damos_test_commit_quota_goals(struct kunit *test)
766 {
767 	damos_test_commit_quota_goals_for(test,
768 			(struct damos_quota_goal[]){}, 0,
769 			(struct damos_quota_goal[]){
770 				{
771 				.metric = DAMOS_QUOTA_USER_INPUT,
772 				.target_value = 123,
773 				},
774 			}, 1);
775 	damos_test_commit_quota_goals_for(test,
776 			(struct damos_quota_goal[]){
777 				{
778 				.metric = DAMOS_QUOTA_USER_INPUT,
779 				.target_value = 234,
780 				},
781 
782 			}, 1,
783 			(struct damos_quota_goal[]){
784 				{
785 				.metric = DAMOS_QUOTA_USER_INPUT,
786 				.target_value = 345,
787 				},
788 			}, 1);
789 	damos_test_commit_quota_goals_for(test,
790 			(struct damos_quota_goal[]){
791 				{
792 				.metric = DAMOS_QUOTA_USER_INPUT,
793 				.target_value = 456,
794 				},
795 
796 			}, 1,
797 			(struct damos_quota_goal[]){}, 0);
798 }
799 
800 static void damos_test_commit_quota(struct kunit *test)
801 {
802 	struct damos_quota dst = {
803 		.reset_interval = 1,
804 		.ms = 2,
805 		.sz = 3,
806 		.goal_tuner = DAMOS_QUOTA_GOAL_TUNER_CONSIST,
807 		.fail_charge_num = 2,
808 		.fail_charge_denom = 3,
809 		.weight_sz = 4,
810 		.weight_nr_accesses = 5,
811 		.weight_age = 6,
812 	};
813 	struct damos_quota src = {
814 		.reset_interval = 7,
815 		.ms = 8,
816 		.sz = 9,
817 		.goal_tuner = DAMOS_QUOTA_GOAL_TUNER_TEMPORAL,
818 		.fail_charge_num = 1,
819 		.fail_charge_denom = 1024,
820 		.weight_sz = 10,
821 		.weight_nr_accesses = 11,
822 		.weight_age = 12,
823 	};
824 
825 	INIT_LIST_HEAD(&dst.goals);
826 	INIT_LIST_HEAD(&src.goals);
827 
828 	damos_commit_quota(&dst, &src);
829 
830 	KUNIT_EXPECT_EQ(test, dst.reset_interval, src.reset_interval);
831 	KUNIT_EXPECT_EQ(test, dst.ms, src.ms);
832 	KUNIT_EXPECT_EQ(test, dst.sz, src.sz);
833 	KUNIT_EXPECT_EQ(test, dst.goal_tuner, src.goal_tuner);
834 	KUNIT_EXPECT_EQ(test, dst.fail_charge_num, src.fail_charge_num);
835 	KUNIT_EXPECT_EQ(test, dst.fail_charge_denom, src.fail_charge_denom);
836 	KUNIT_EXPECT_EQ(test, dst.weight_sz, src.weight_sz);
837 	KUNIT_EXPECT_EQ(test, dst.weight_nr_accesses, src.weight_nr_accesses);
838 	KUNIT_EXPECT_EQ(test, dst.weight_age, src.weight_age);
839 }
840 
841 static int damos_test_help_dests_setup(struct damos_migrate_dests *dests,
842 		unsigned int *node_id_arr, unsigned int *weight_arr,
843 		size_t nr_dests)
844 {
845 	size_t i;
846 
847 	dests->node_id_arr = kmalloc_objs(*dests->node_id_arr, nr_dests);
848 	if (!dests->node_id_arr)
849 		return -ENOMEM;
850 	dests->weight_arr = kmalloc_objs(*dests->weight_arr, nr_dests);
851 	if (!dests->weight_arr) {
852 		kfree(dests->node_id_arr);
853 		dests->node_id_arr = NULL;
854 		return -ENOMEM;
855 	}
856 
857 	for (i = 0; i < nr_dests; i++) {
858 		dests->node_id_arr[i] = node_id_arr[i];
859 		dests->weight_arr[i] = weight_arr[i];
860 	}
861 	dests->nr_dests = nr_dests;
862 	return 0;
863 }
864 
865 static void damos_test_help_dests_free(struct damos_migrate_dests *dests)
866 {
867 	kfree(dests->node_id_arr);
868 	kfree(dests->weight_arr);
869 }
870 
871 static void damos_test_commit_dests_for(struct kunit *test,
872 		unsigned int *dst_node_id_arr, unsigned int *dst_weight_arr,
873 		size_t dst_nr_dests,
874 		unsigned int *src_node_id_arr, unsigned int *src_weight_arr,
875 		size_t src_nr_dests)
876 {
877 	struct damos_migrate_dests dst = {}, src = {};
878 	int i, err;
879 	bool skip = true;
880 
881 	err = damos_test_help_dests_setup(&dst, dst_node_id_arr,
882 			dst_weight_arr, dst_nr_dests);
883 	if (err)
884 		kunit_skip(test, "dests setup fail");
885 	err = damos_test_help_dests_setup(&src, src_node_id_arr,
886 			src_weight_arr, src_nr_dests);
887 	if (err) {
888 		damos_test_help_dests_free(&dst);
889 		kunit_skip(test, "src setup fail");
890 	}
891 	err = damos_commit_dests(&dst, &src);
892 	if (err)
893 		goto out;
894 	skip = false;
895 
896 	KUNIT_EXPECT_EQ(test, dst.nr_dests, src_nr_dests);
897 	for (i = 0; i < dst.nr_dests; i++) {
898 		KUNIT_EXPECT_EQ(test, dst.node_id_arr[i], src_node_id_arr[i]);
899 		KUNIT_EXPECT_EQ(test, dst.weight_arr[i], src_weight_arr[i]);
900 	}
901 
902 out:
903 	damos_test_help_dests_free(&dst);
904 	damos_test_help_dests_free(&src);
905 	if (skip)
906 		kunit_skip(test, "skip");
907 }
908 
909 static void damos_test_commit_dests(struct kunit *test)
910 {
911 	damos_test_commit_dests_for(test,
912 			(unsigned int[]){1, 2, 3}, (unsigned int[]){2, 3, 4},
913 			3,
914 			(unsigned int[]){4, 5, 6}, (unsigned int[]){5, 6, 7},
915 			3);
916 	damos_test_commit_dests_for(test,
917 			(unsigned int[]){1, 2}, (unsigned int[]){2, 3},
918 			2,
919 			(unsigned int[]){4, 5, 6}, (unsigned int[]){5, 6, 7},
920 			3);
921 	damos_test_commit_dests_for(test,
922 			NULL, NULL, 0,
923 			(unsigned int[]){4, 5, 6}, (unsigned int[]){5, 6, 7},
924 			3);
925 	damos_test_commit_dests_for(test,
926 			(unsigned int[]){1, 2, 3}, (unsigned int[]){2, 3, 4},
927 			3,
928 			(unsigned int[]){4, 5}, (unsigned int[]){5, 6}, 2);
929 	damos_test_commit_dests_for(test,
930 			(unsigned int[]){1, 2, 3}, (unsigned int[]){2, 3, 4},
931 			3,
932 			NULL, NULL, 0);
933 }
934 
935 static void damos_test_commit_filter_for(struct kunit *test,
936 		struct damos_filter *dst, struct damos_filter *src)
937 {
938 	damos_commit_filter(dst, src);
939 	KUNIT_EXPECT_EQ(test, dst->type, src->type);
940 	KUNIT_EXPECT_EQ(test, dst->matching, src->matching);
941 	KUNIT_EXPECT_EQ(test, dst->allow, src->allow);
942 	switch (src->type) {
943 	case DAMOS_FILTER_TYPE_MEMCG:
944 		KUNIT_EXPECT_EQ(test, dst->memcg_id, src->memcg_id);
945 		break;
946 	case DAMOS_FILTER_TYPE_ADDR:
947 		KUNIT_EXPECT_EQ(test, dst->addr_range.start,
948 				src->addr_range.start);
949 		KUNIT_EXPECT_EQ(test, dst->addr_range.end,
950 				src->addr_range.end);
951 		break;
952 	case DAMOS_FILTER_TYPE_TARGET:
953 		KUNIT_EXPECT_EQ(test, dst->target_idx, src->target_idx);
954 		break;
955 	case DAMOS_FILTER_TYPE_HUGEPAGE_SIZE:
956 		KUNIT_EXPECT_EQ(test, dst->sz_range.min, src->sz_range.min);
957 		KUNIT_EXPECT_EQ(test, dst->sz_range.max, src->sz_range.max);
958 		break;
959 	default:
960 		break;
961 	}
962 }
963 
964 static void damos_test_commit_filter(struct kunit *test)
965 {
966 	struct damos_filter dst = {
967 		.type = DAMOS_FILTER_TYPE_ACTIVE,
968 		.matching = false,
969 		.allow = false,
970 	};
971 
972 	damos_test_commit_filter_for(test, &dst,
973 			&(struct damos_filter){
974 			.type = DAMOS_FILTER_TYPE_ANON,
975 			.matching = true,
976 			.allow = true,
977 			});
978 	damos_test_commit_filter_for(test, &dst,
979 			&(struct damos_filter){
980 			.type = DAMOS_FILTER_TYPE_MEMCG,
981 			.matching = false,
982 			.allow = false,
983 			.memcg_id = 123,
984 			});
985 	damos_test_commit_filter_for(test, &dst,
986 			&(struct damos_filter){
987 			.type = DAMOS_FILTER_TYPE_YOUNG,
988 			.matching = true,
989 			.allow = true,
990 			});
991 	damos_test_commit_filter_for(test, &dst,
992 			&(struct damos_filter){
993 			.type = DAMOS_FILTER_TYPE_HUGEPAGE_SIZE,
994 			.matching = false,
995 			.allow = false,
996 			.sz_range = {.min = 234, .max = 345},
997 			});
998 	damos_test_commit_filter_for(test, &dst,
999 			&(struct damos_filter){
1000 			.type = DAMOS_FILTER_TYPE_UNMAPPED,
1001 			.matching = true,
1002 			.allow = true,
1003 			});
1004 	damos_test_commit_filter_for(test, &dst,
1005 			&(struct damos_filter){
1006 			.type = DAMOS_FILTER_TYPE_ADDR,
1007 			.matching = false,
1008 			.allow = false,
1009 			.addr_range = {.start = 456, .end = 567},
1010 			});
1011 	damos_test_commit_filter_for(test, &dst,
1012 			&(struct damos_filter){
1013 			.type = DAMOS_FILTER_TYPE_TARGET,
1014 			.matching = true,
1015 			.allow = true,
1016 			.target_idx = 6,
1017 			});
1018 }
1019 
1020 static void damos_test_help_initailize_scheme(struct damos *scheme)
1021 {
1022 	INIT_LIST_HEAD(&scheme->quota.goals);
1023 	INIT_LIST_HEAD(&scheme->core_filters);
1024 	INIT_LIST_HEAD(&scheme->ops_filters);
1025 }
1026 
1027 static void damos_test_commit_for(struct kunit *test, struct damos *dst,
1028 		struct damos *src)
1029 {
1030 	int err;
1031 
1032 	damos_test_help_initailize_scheme(dst);
1033 	damos_test_help_initailize_scheme(src);
1034 
1035 	err = damos_commit(dst, src);
1036 	if (err)
1037 		kunit_skip(test, "damos_commit fail");
1038 
1039 	KUNIT_EXPECT_EQ(test, dst->pattern.min_sz_region,
1040 			src->pattern.min_sz_region);
1041 	KUNIT_EXPECT_EQ(test, dst->pattern.max_sz_region,
1042 			src->pattern.max_sz_region);
1043 	KUNIT_EXPECT_EQ(test, dst->pattern.min_nr_accesses,
1044 			src->pattern.min_nr_accesses);
1045 	KUNIT_EXPECT_EQ(test, dst->pattern.max_nr_accesses,
1046 			src->pattern.max_nr_accesses);
1047 	KUNIT_EXPECT_EQ(test, dst->pattern.min_age_region,
1048 			src->pattern.min_age_region);
1049 	KUNIT_EXPECT_EQ(test, dst->pattern.max_age_region,
1050 			src->pattern.max_age_region);
1051 
1052 	KUNIT_EXPECT_EQ(test, dst->action, src->action);
1053 	KUNIT_EXPECT_EQ(test, dst->apply_interval_us, src->apply_interval_us);
1054 
1055 	KUNIT_EXPECT_EQ(test, dst->wmarks.metric, src->wmarks.metric);
1056 	KUNIT_EXPECT_EQ(test, dst->wmarks.interval, src->wmarks.interval);
1057 	KUNIT_EXPECT_EQ(test, dst->wmarks.high, src->wmarks.high);
1058 	KUNIT_EXPECT_EQ(test, dst->wmarks.mid, src->wmarks.mid);
1059 	KUNIT_EXPECT_EQ(test, dst->wmarks.low, src->wmarks.low);
1060 
1061 	switch (src->action) {
1062 	case DAMOS_MIGRATE_COLD:
1063 	case DAMOS_MIGRATE_HOT:
1064 		KUNIT_EXPECT_EQ(test, dst->target_nid, src->target_nid);
1065 		break;
1066 	default:
1067 		break;
1068 	}
1069 }
1070 
1071 static void damos_test_commit_pageout(struct kunit *test)
1072 {
1073 	damos_test_commit_for(test,
1074 			&(struct damos){
1075 				.pattern = (struct damos_access_pattern){
1076 					1, 2, 3, 4, 5, 6},
1077 				.action = DAMOS_PAGEOUT,
1078 				.apply_interval_us = 1000000,
1079 				.wmarks = (struct damos_watermarks){
1080 					DAMOS_WMARK_FREE_MEM_RATE,
1081 					900, 100, 50},
1082 			},
1083 			&(struct damos){
1084 				.pattern = (struct damos_access_pattern){
1085 					2, 3, 4, 5, 6, 7},
1086 				.action = DAMOS_PAGEOUT,
1087 				.apply_interval_us = 2000000,
1088 				.wmarks = (struct damos_watermarks){
1089 					DAMOS_WMARK_FREE_MEM_RATE,
1090 					800, 50, 30},
1091 			});
1092 }
1093 
1094 static void damos_test_commit_migrate_hot(struct kunit *test)
1095 {
1096 	damos_test_commit_for(test,
1097 			&(struct damos){
1098 				.pattern = (struct damos_access_pattern){
1099 					1, 2, 3, 4, 5, 6},
1100 				.action = DAMOS_PAGEOUT,
1101 				.apply_interval_us = 1000000,
1102 				.wmarks = (struct damos_watermarks){
1103 					DAMOS_WMARK_FREE_MEM_RATE,
1104 					900, 100, 50},
1105 			},
1106 			&(struct damos){
1107 				.pattern = (struct damos_access_pattern){
1108 					2, 3, 4, 5, 6, 7},
1109 				.action = DAMOS_MIGRATE_HOT,
1110 				.apply_interval_us = 2000000,
1111 				.target_nid = 5,
1112 			});
1113 }
1114 
1115 static struct damon_target *damon_test_help_setup_target(
1116 		unsigned long region_start_end[][2], int nr_regions)
1117 {
1118 	struct damon_target *t;
1119 	struct damon_region *r;
1120 	int i;
1121 
1122 	t = damon_new_target();
1123 	if (!t)
1124 		return NULL;
1125 	for (i = 0; i < nr_regions; i++) {
1126 		r = damon_new_region(region_start_end[i][0],
1127 				region_start_end[i][1]);
1128 		if (!r) {
1129 			damon_free_target(t);
1130 			return NULL;
1131 		}
1132 		damon_add_region(r, t);
1133 	}
1134 	return t;
1135 }
1136 
1137 static void damon_test_commit_target_regions_for(struct kunit *test,
1138 		unsigned long dst_start_end[][2], int nr_dst_regions,
1139 		unsigned long src_start_end[][2], int nr_src_regions,
1140 		unsigned long expect_start_end[][2], int nr_expect_regions)
1141 {
1142 	struct damon_target *dst_target, *src_target;
1143 	struct damon_region *r;
1144 	int i;
1145 
1146 	dst_target = damon_test_help_setup_target(dst_start_end, nr_dst_regions);
1147 	if (!dst_target)
1148 		kunit_skip(test, "dst target setup fail");
1149 	src_target = damon_test_help_setup_target(src_start_end, nr_src_regions);
1150 	if (!src_target) {
1151 		damon_free_target(dst_target);
1152 		kunit_skip(test, "src target setup fail");
1153 	}
1154 	damon_commit_target_regions(dst_target, src_target, 1);
1155 	i = 0;
1156 	damon_for_each_region(r, dst_target) {
1157 		KUNIT_EXPECT_EQ(test, r->ar.start, expect_start_end[i][0]);
1158 		KUNIT_EXPECT_EQ(test, r->ar.end, expect_start_end[i][1]);
1159 		i++;
1160 	}
1161 	KUNIT_EXPECT_EQ(test, damon_nr_regions(dst_target), nr_expect_regions);
1162 	KUNIT_EXPECT_EQ(test, i, nr_expect_regions);
1163 	damon_free_target(dst_target);
1164 	damon_free_target(src_target);
1165 }
1166 
1167 static void damon_test_commit_target_regions(struct kunit *test)
1168 {
1169 	damon_test_commit_target_regions_for(test,
1170 			(unsigned long[][2]) {{3, 8}, {8, 10}}, 2,
1171 			(unsigned long[][2]) {{4, 6}}, 1,
1172 			(unsigned long[][2]) {{4, 6}}, 1);
1173 	damon_test_commit_target_regions_for(test,
1174 			(unsigned long[][2]) {{3, 8}, {8, 10}}, 2,
1175 			(unsigned long[][2]) {}, 0,
1176 			(unsigned long[][2]) {{3, 8}, {8, 10}}, 2);
1177 }
1178 
1179 static void damon_test_commit_ctx(struct kunit *test)
1180 {
1181 	struct damon_ctx *src, *dst;
1182 
1183 	src = damon_new_ctx();
1184 	if (!src)
1185 		kunit_skip(test, "src alloc fail");
1186 	dst = damon_new_ctx();
1187 	if (!dst) {
1188 		damon_destroy_ctx(src);
1189 		kunit_skip(test, "dst alloc fail");
1190 	}
1191 	/* Only power of two min_region_sz is allowed. */
1192 	src->min_region_sz = 4096;
1193 	KUNIT_EXPECT_EQ(test, damon_commit_ctx(dst, src), 0);
1194 	src->min_region_sz = 4095;
1195 	KUNIT_EXPECT_EQ(test, damon_commit_ctx(dst, src), -EINVAL);
1196 	src->min_region_sz = 4096;
1197 	src->pause = true;
1198 	KUNIT_EXPECT_EQ(test, damon_commit_ctx(dst, src), 0);
1199 	KUNIT_EXPECT_TRUE(test, dst->pause);
1200 	damon_destroy_ctx(src);
1201 	damon_destroy_ctx(dst);
1202 }
1203 
1204 static void damos_test_filter_out(struct kunit *test)
1205 {
1206 	struct damon_target *t;
1207 	struct damon_region *r, *r2;
1208 	struct damos_filter *f;
1209 
1210 	f = damos_new_filter(DAMOS_FILTER_TYPE_ADDR, true, false);
1211 	if (!f)
1212 		kunit_skip(test, "filter alloc fail");
1213 	f->addr_range = (struct damon_addr_range){.start = 2, .end = 6};
1214 
1215 	t = damon_new_target();
1216 	if (!t) {
1217 		damos_destroy_filter(f);
1218 		kunit_skip(test, "target alloc fail");
1219 	}
1220 	r = damon_new_region(3, 5);
1221 	if (!r) {
1222 		damos_destroy_filter(f);
1223 		damon_free_target(t);
1224 		kunit_skip(test, "region alloc fail");
1225 	}
1226 	damon_add_region(r, t);
1227 
1228 	/* region in the range */
1229 	KUNIT_EXPECT_TRUE(test, damos_filter_match(NULL, t, r, f, 1));
1230 	KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 1);
1231 
1232 	/* region before the range */
1233 	r->ar.start = 1;
1234 	r->ar.end = 2;
1235 	KUNIT_EXPECT_FALSE(test,
1236 			damos_filter_match(NULL, t, r, f, 1));
1237 	KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 1);
1238 
1239 	/* region after the range */
1240 	r->ar.start = 6;
1241 	r->ar.end = 8;
1242 	KUNIT_EXPECT_FALSE(test,
1243 			damos_filter_match(NULL, t, r, f, 1));
1244 	KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 1);
1245 
1246 	/* region started before the range */
1247 	r->ar.start = 1;
1248 	r->ar.end = 4;
1249 	KUNIT_EXPECT_FALSE(test, damos_filter_match(NULL, t, r, f, 1));
1250 	/* filter should have split the region */
1251 	KUNIT_EXPECT_EQ(test, r->ar.start, 1);
1252 	KUNIT_EXPECT_EQ(test, r->ar.end, 2);
1253 	KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 2);
1254 	r2 = damon_next_region(r);
1255 	KUNIT_EXPECT_EQ(test, r2->ar.start, 2);
1256 	KUNIT_EXPECT_EQ(test, r2->ar.end, 4);
1257 	damon_destroy_region(r2, t);
1258 
1259 	/* region started in the range */
1260 	r->ar.start = 2;
1261 	r->ar.end = 8;
1262 	KUNIT_EXPECT_TRUE(test,
1263 			damos_filter_match(NULL, t, r, f, 1));
1264 	/* filter should have split the region */
1265 	KUNIT_EXPECT_EQ(test, r->ar.start, 2);
1266 	KUNIT_EXPECT_EQ(test, r->ar.end, 6);
1267 	KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 2);
1268 	r2 = damon_next_region(r);
1269 	KUNIT_EXPECT_EQ(test, r2->ar.start, 6);
1270 	KUNIT_EXPECT_EQ(test, r2->ar.end, 8);
1271 	damon_destroy_region(r2, t);
1272 
1273 	damon_free_target(t);
1274 	damos_free_filter(f);
1275 }
1276 
1277 static void damon_test_feed_loop_next_input(struct kunit *test)
1278 {
1279 	unsigned long last_input = 900000, current_score = 200;
1280 
1281 	/*
1282 	 * If current score is lower than the goal, which is always 10,000
1283 	 * (read the comment on damon_feed_loop_next_input()'s comment), next
1284 	 * input should be higher than the last input.
1285 	 */
1286 	KUNIT_EXPECT_GT(test,
1287 			damon_feed_loop_next_input(last_input, current_score),
1288 			last_input);
1289 
1290 	/*
1291 	 * If current score is higher than the goal, next input should be lower
1292 	 * than the last input.
1293 	 */
1294 	current_score = 250000000;
1295 	KUNIT_EXPECT_LT(test,
1296 			damon_feed_loop_next_input(last_input, current_score),
1297 			last_input);
1298 
1299 	/*
1300 	 * The next input depends on the distance between the current score and
1301 	 * the goal
1302 	 */
1303 	KUNIT_EXPECT_GT(test,
1304 			damon_feed_loop_next_input(last_input, 200),
1305 			damon_feed_loop_next_input(last_input, 2000));
1306 }
1307 
1308 static void damon_test_set_filters_default_reject(struct kunit *test)
1309 {
1310 	struct damos scheme;
1311 	struct damos_filter *target_filter, *anon_filter;
1312 
1313 	INIT_LIST_HEAD(&scheme.core_filters);
1314 	INIT_LIST_HEAD(&scheme.ops_filters);
1315 
1316 	damos_set_filters_default_reject(&scheme);
1317 	/*
1318 	 * No filter is installed.  Allow by default on both core and ops layer
1319 	 * filtering stages, since there are no filters at all.
1320 	 */
1321 	KUNIT_EXPECT_EQ(test, scheme.core_filters_default_reject, false);
1322 	KUNIT_EXPECT_EQ(test, scheme.ops_filters_default_reject, false);
1323 
1324 	target_filter = damos_new_filter(DAMOS_FILTER_TYPE_TARGET, true, true);
1325 	if (!target_filter)
1326 		kunit_skip(test, "filter alloc fail");
1327 	damos_add_filter(&scheme, target_filter);
1328 	damos_set_filters_default_reject(&scheme);
1329 	/*
1330 	 * A core-handled allow-filter is installed.
1331 	 * Reject by default on core layer filtering stage due to the last
1332 	 * core-layer-filter's behavior.
1333 	 * Allow by default on ops layer filtering stage due to the absence of
1334 	 * ops layer filters.
1335 	 */
1336 	KUNIT_EXPECT_EQ(test, scheme.core_filters_default_reject, true);
1337 	KUNIT_EXPECT_EQ(test, scheme.ops_filters_default_reject, false);
1338 
1339 	target_filter->allow = false;
1340 	damos_set_filters_default_reject(&scheme);
1341 	/*
1342 	 * A core-handled reject-filter is installed.
1343 	 * Allow by default on core layer filtering stage due to the last
1344 	 * core-layer-filter's behavior.
1345 	 * Allow by default on ops layer filtering stage due to the absence of
1346 	 * ops layer filters.
1347 	 */
1348 	KUNIT_EXPECT_EQ(test, scheme.core_filters_default_reject, false);
1349 	KUNIT_EXPECT_EQ(test, scheme.ops_filters_default_reject, false);
1350 
1351 	anon_filter = damos_new_filter(DAMOS_FILTER_TYPE_ANON, true, true);
1352 	if (!anon_filter) {
1353 		damos_free_filter(target_filter);
1354 		kunit_skip(test, "anon_filter alloc fail");
1355 	}
1356 	damos_add_filter(&scheme, anon_filter);
1357 
1358 	damos_set_filters_default_reject(&scheme);
1359 	/*
1360 	 * A core-handled reject-filter and ops-handled allow-filter are installed.
1361 	 * Allow by default on core layer filtering stage due to the existence
1362 	 * of the ops-handled filter.
1363 	 * Reject by default on ops layer filtering stage due to the last
1364 	 * ops-layer-filter's behavior.
1365 	 */
1366 	KUNIT_EXPECT_EQ(test, scheme.core_filters_default_reject, false);
1367 	KUNIT_EXPECT_EQ(test, scheme.ops_filters_default_reject, true);
1368 
1369 	target_filter->allow = true;
1370 	damos_set_filters_default_reject(&scheme);
1371 	/*
1372 	 * A core-handled allow-filter and ops-handled allow-filter are
1373 	 * installed.
1374 	 * Allow by default on core layer filtering stage due to the existence
1375 	 * of the ops-handled filter.
1376 	 * Reject by default on ops layer filtering stage due to the last
1377 	 * ops-layer-filter's behavior.
1378 	 */
1379 	KUNIT_EXPECT_EQ(test, scheme.core_filters_default_reject, false);
1380 	KUNIT_EXPECT_EQ(test, scheme.ops_filters_default_reject, true);
1381 
1382 	damos_free_filter(anon_filter);
1383 	damos_free_filter(target_filter);
1384 }
1385 
1386 static void damon_test_apply_min_nr_regions_for(struct kunit *test,
1387 		unsigned long sz_regions, unsigned long min_region_sz,
1388 		unsigned long min_nr_regions,
1389 		unsigned long max_region_sz_expect,
1390 		unsigned long nr_regions_expect)
1391 {
1392 	struct damon_ctx *ctx;
1393 	struct damon_target *t;
1394 	struct damon_region *r;
1395 	unsigned long max_region_size;
1396 
1397 	ctx = damon_new_ctx();
1398 	if (!ctx)
1399 		kunit_skip(test, "ctx alloc fail\n");
1400 	t = damon_new_target();
1401 	if (!t) {
1402 		damon_destroy_ctx(ctx);
1403 		kunit_skip(test, "target alloc fail\n");
1404 	}
1405 	damon_add_target(ctx, t);
1406 	r = damon_new_region(0, sz_regions);
1407 	if (!r) {
1408 		damon_destroy_ctx(ctx);
1409 		kunit_skip(test, "region alloc fail\n");
1410 	}
1411 	damon_add_region(r, t);
1412 
1413 	ctx->min_region_sz = min_region_sz;
1414 	ctx->attrs.min_nr_regions = min_nr_regions;
1415 	max_region_size = damon_apply_min_nr_regions(ctx);
1416 
1417 	KUNIT_EXPECT_EQ(test, max_region_size, max_region_sz_expect);
1418 	KUNIT_EXPECT_EQ(test, damon_nr_regions(t), nr_regions_expect);
1419 
1420 	damon_destroy_ctx(ctx);
1421 }
1422 
1423 static void damon_test_apply_min_nr_regions(struct kunit *test)
1424 {
1425 	/* common, expected setup */
1426 	damon_test_apply_min_nr_regions_for(test, 10, 1, 10, 1, 10);
1427 	/* no zero size limit */
1428 	damon_test_apply_min_nr_regions_for(test, 10, 1, 15, 1, 10);
1429 	/* max size should be aligned by min_region_sz */
1430 	damon_test_apply_min_nr_regions_for(test, 10, 2, 2, 6, 2);
1431 	/*
1432 	 * when min_nr_regions and min_region_sz conflicts, min_region_sz wins.
1433 	 */
1434 	damon_test_apply_min_nr_regions_for(test, 10, 2, 10, 2, 5);
1435 }
1436 
1437 static void damon_test_is_last_region(struct kunit *test)
1438 {
1439 	struct damon_region *r;
1440 	struct damon_target *t;
1441 	int i;
1442 
1443 	t = damon_new_target();
1444 	if (!t)
1445 		kunit_skip(test, "target alloc fail\n");
1446 
1447 	for (i = 0; i < 4; i++) {
1448 		r = damon_new_region(i * 2, (i + 1) * 2);
1449 		if (!r) {
1450 			damon_free_target(t);
1451 			kunit_skip(test, "region alloc %d fail\n", i);
1452 		}
1453 		damon_add_region(r, t);
1454 		KUNIT_EXPECT_TRUE(test, damon_is_last_region(r, t));
1455 	}
1456 	damon_free_target(t);
1457 }
1458 
1459 static struct kunit_case damon_test_cases[] = {
1460 	KUNIT_CASE(damon_test_target),
1461 	KUNIT_CASE(damon_test_regions),
1462 	KUNIT_CASE(damon_test_aggregate),
1463 	KUNIT_CASE(damon_test_split_at),
1464 	KUNIT_CASE(damon_test_merge_two),
1465 	KUNIT_CASE(damon_test_merge_regions_of),
1466 	KUNIT_CASE(damon_test_split_regions_of),
1467 	KUNIT_CASE(damon_test_ops_registration),
1468 	KUNIT_CASE(damon_test_set_regions),
1469 	KUNIT_CASE(damon_test_nr_accesses_to_accesses_bp),
1470 	KUNIT_CASE(damon_test_update_monitoring_result),
1471 	KUNIT_CASE(damon_test_set_attrs),
1472 	KUNIT_CASE(damon_test_moving_sum),
1473 	KUNIT_CASE(damos_test_new_filter),
1474 	KUNIT_CASE(damos_test_commit_quota_goal),
1475 	KUNIT_CASE(damos_test_commit_quota_goals),
1476 	KUNIT_CASE(damos_test_commit_quota),
1477 	KUNIT_CASE(damos_test_commit_dests),
1478 	KUNIT_CASE(damos_test_commit_filter),
1479 	KUNIT_CASE(damos_test_commit_pageout),
1480 	KUNIT_CASE(damos_test_commit_migrate_hot),
1481 	KUNIT_CASE(damon_test_commit_target_regions),
1482 	KUNIT_CASE(damon_test_commit_ctx),
1483 	KUNIT_CASE(damos_test_filter_out),
1484 	KUNIT_CASE(damon_test_feed_loop_next_input),
1485 	KUNIT_CASE(damon_test_set_filters_default_reject),
1486 	KUNIT_CASE(damon_test_apply_min_nr_regions),
1487 	KUNIT_CASE(damon_test_is_last_region),
1488 	{},
1489 };
1490 
1491 static struct kunit_suite damon_test_suite = {
1492 	.name = "damon",
1493 	.test_cases = damon_test_cases,
1494 };
1495 kunit_test_suite(damon_test_suite);
1496 
1497 #endif /* _DAMON_CORE_TEST_H */
1498 
1499 #endif	/* CONFIG_DAMON_KUNIT_TEST */
1500