xref: /linux/mm/damon/vaddr.c (revision 283b3d31ec7a62bf4517fc57d07d8faf2bdbc841)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * DAMON Code for Virtual Address Spaces
4  */
5 
6 #define pr_fmt(fmt) "damon-va: " fmt
7 
8 #include <linux/highmem.h>
9 #include <linux/hugetlb.h>
10 #include <linux/mman.h>
11 #include <linux/mmu_notifier.h>
12 #include <linux/page_idle.h>
13 #include <linux/pagemap.h>
14 #include <linux/pagewalk.h>
15 #include <linux/sched/mm.h>
16 
17 #include "../internal.h"
18 #include "ops-common.h"
19 
20 #ifdef CONFIG_DAMON_VADDR_KUNIT_TEST
21 #undef DAMON_MIN_REGION_SZ
22 #define DAMON_MIN_REGION_SZ 1
23 #endif
24 
25 /*
26  * 't->pid' should be the pointer to the relevant 'struct pid' having reference
27  * count.  Caller must put the returned task, unless it is NULL.
28  */
29 static inline struct task_struct *damon_get_task_struct(struct damon_target *t)
30 {
31 	return get_pid_task(t->pid, PIDTYPE_PID);
32 }
33 
34 /*
35  * Get the mm_struct of the given target
36  *
37  * Caller _must_ put the mm_struct after use, unless it is NULL.
38  *
39  * Returns the mm_struct of the target on success, NULL on failure
40  */
41 static struct mm_struct *damon_get_mm(struct damon_target *t)
42 {
43 	struct task_struct *task;
44 	struct mm_struct *mm;
45 
46 	task = damon_get_task_struct(t);
47 	if (!task)
48 		return NULL;
49 
50 	mm = get_task_mm(task);
51 	put_task_struct(task);
52 	return mm;
53 }
54 
55 static unsigned long sz_range(struct damon_addr_range *r)
56 {
57 	return r->end - r->start;
58 }
59 
60 /*
61  * Find three regions separated by two biggest unmapped regions
62  *
63  * vma		the head vma of the target address space
64  * regions	an array of three address ranges that results will be saved
65  *
66  * This function receives an address space and finds three regions in it which
67  * separated by the two biggest unmapped regions in the space.  Please refer to
68  * below comments of '__damon_va_init_regions()' function to know why this is
69  * necessary.
70  *
71  * Returns 0 if success, or negative error code otherwise.
72  */
73 static int __damon_va_three_regions(struct mm_struct *mm,
74 				       struct damon_addr_range regions[3])
75 {
76 	struct damon_addr_range first_gap = {0}, second_gap = {0};
77 	VMA_ITERATOR(vmi, mm, 0);
78 	struct vm_area_struct *vma, *prev = NULL;
79 	unsigned long start;
80 
81 	/*
82 	 * Find the two biggest gaps so that first_gap > second_gap > others.
83 	 * If this is too slow, it can be optimised to examine the maple
84 	 * tree gaps.
85 	 */
86 	rcu_read_lock();
87 	for_each_vma(vmi, vma) {
88 		unsigned long gap;
89 
90 		if (!prev) {
91 			start = vma->vm_start;
92 			goto next;
93 		}
94 		gap = vma->vm_start - prev->vm_end;
95 
96 		if (gap > sz_range(&first_gap)) {
97 			second_gap = first_gap;
98 			first_gap.start = prev->vm_end;
99 			first_gap.end = vma->vm_start;
100 		} else if (gap > sz_range(&second_gap)) {
101 			second_gap.start = prev->vm_end;
102 			second_gap.end = vma->vm_start;
103 		}
104 next:
105 		prev = vma;
106 	}
107 	rcu_read_unlock();
108 
109 	if (!sz_range(&second_gap) || !sz_range(&first_gap))
110 		return -EINVAL;
111 
112 	/* Sort the two biggest gaps by address */
113 	if (first_gap.start > second_gap.start)
114 		swap(first_gap, second_gap);
115 
116 	/* Store the result */
117 	regions[0].start = ALIGN(start, DAMON_MIN_REGION_SZ);
118 	regions[0].end = ALIGN(first_gap.start, DAMON_MIN_REGION_SZ);
119 	regions[1].start = ALIGN(first_gap.end, DAMON_MIN_REGION_SZ);
120 	regions[1].end = ALIGN(second_gap.start, DAMON_MIN_REGION_SZ);
121 	regions[2].start = ALIGN(second_gap.end, DAMON_MIN_REGION_SZ);
122 	regions[2].end = ALIGN(prev->vm_end, DAMON_MIN_REGION_SZ);
123 
124 	return 0;
125 }
126 
127 /*
128  * Get the three regions in the given target (task)
129  *
130  * Returns 0 on success, negative error code otherwise.
131  */
132 static int damon_va_three_regions(struct damon_target *t,
133 				struct damon_addr_range regions[3])
134 {
135 	struct mm_struct *mm;
136 	int rc;
137 
138 	mm = damon_get_mm(t);
139 	if (!mm)
140 		return -EINVAL;
141 
142 	mmap_read_lock(mm);
143 	rc = __damon_va_three_regions(mm, regions);
144 	mmap_read_unlock(mm);
145 
146 	mmput(mm);
147 	return rc;
148 }
149 
150 /*
151  * Initialize the monitoring target regions for the given target (task)
152  *
153  * t	the given target
154  *
155  * Because only a number of small portions of the entire address space
156  * is actually mapped to the memory and accessed, monitoring the unmapped
157  * regions is wasteful.  That said, because we can deal with small noises,
158  * tracking every mapping is not strictly required but could even incur a high
159  * overhead if the mapping frequently changes or the number of mappings is
160  * high.  The adaptive regions adjustment mechanism will further help to deal
161  * with the noise by simply identifying the unmapped areas as a region that
162  * has no access.  Moreover, applying the real mappings that would have many
163  * unmapped areas inside will make the adaptive mechanism quite complex.  That
164  * said, too huge unmapped areas inside the monitoring target should be removed
165  * to not take the time for the adaptive mechanism.
166  *
167  * For the reason, we convert the complex mappings to three distinct regions
168  * that cover every mapped area of the address space.  Also the two gaps
169  * between the three regions are the two biggest unmapped areas in the given
170  * address space.  In detail, this function first identifies the start and the
171  * end of the mappings and the two biggest unmapped areas of the address space.
172  * Then, it constructs the three regions as below:
173  *
174  *     [mappings[0]->start, big_two_unmapped_areas[0]->start)
175  *     [big_two_unmapped_areas[0]->end, big_two_unmapped_areas[1]->start)
176  *     [big_two_unmapped_areas[1]->end, mappings[nr_mappings - 1]->end)
177  *
178  * As usual memory map of processes is as below, the gap between the heap and
179  * the uppermost mmap()-ed region, and the gap between the lowermost mmap()-ed
180  * region and the stack will be two biggest unmapped regions.  Because these
181  * gaps are exceptionally huge areas in usual address space, excluding these
182  * two biggest unmapped regions will be sufficient to make a trade-off.
183  *
184  *   <heap>
185  *   <BIG UNMAPPED REGION 1>
186  *   <uppermost mmap()-ed region>
187  *   (other mmap()-ed regions and small unmapped regions)
188  *   <lowermost mmap()-ed region>
189  *   <BIG UNMAPPED REGION 2>
190  *   <stack>
191  */
192 static void __damon_va_init_regions(struct damon_target *t)
193 {
194 	struct damon_addr_range regions[3];
195 
196 	if (damon_va_three_regions(t, regions))
197 		return;
198 
199 	damon_set_regions(t, regions, 3, DAMON_MIN_REGION_SZ);
200 }
201 
202 /* Initialize '->regions_list' of every target (task) */
203 static void damon_va_init(struct damon_ctx *ctx)
204 {
205 	struct damon_target *t;
206 
207 	damon_for_each_target(t, ctx) {
208 		/* the user may set the target regions as they want */
209 		if (!damon_nr_regions(t))
210 			__damon_va_init_regions(t);
211 	}
212 }
213 
214 /*
215  * Update regions for current memory mappings
216  */
217 static void damon_va_update(struct damon_ctx *ctx)
218 {
219 	struct damon_addr_range three_regions[3];
220 	struct damon_target *t;
221 
222 	damon_for_each_target(t, ctx) {
223 		if (damon_va_three_regions(t, three_regions))
224 			continue;
225 		damon_set_regions(t, three_regions, 3, DAMON_MIN_REGION_SZ);
226 	}
227 }
228 
229 static void damon_va_walk_page_range(struct mm_struct *mm, unsigned long start,
230 		unsigned long end, struct mm_walk_ops *ops, void *private)
231 {
232 	struct vm_area_struct *vma;
233 
234 	vma = lock_vma_under_rcu(mm, start);
235 	if (!vma)
236 		goto lock_mmap;
237 
238 	if (end > vma->vm_end) {
239 		vma_end_read(vma);
240 		goto lock_mmap;
241 	}
242 
243 	if (!(vma->vm_flags & VM_PFNMAP)) {
244 		ops->walk_lock = PGWALK_VMA_RDLOCK_VERIFY;
245 		walk_page_range_vma(vma, start, end, ops, private);
246 	}
247 
248 	vma_end_read(vma);
249 	return;
250 
251 lock_mmap:
252 	mmap_read_lock(mm);
253 	ops->walk_lock = PGWALK_RDLOCK;
254 	walk_page_range(mm, start, end, ops, private);
255 	mmap_read_unlock(mm);
256 }
257 
258 static int damon_mkold_pmd_entry(pmd_t *pmd, unsigned long addr,
259 		unsigned long next, struct mm_walk *walk)
260 {
261 	pte_t *pte;
262 	spinlock_t *ptl;
263 
264 	ptl = pmd_trans_huge_lock(pmd, walk->vma);
265 	if (ptl) {
266 		pmd_t pmde = pmdp_get(pmd);
267 
268 		if (pmd_present(pmde))
269 			damon_pmdp_mkold(pmd, walk->vma, addr);
270 		spin_unlock(ptl);
271 		return 0;
272 	}
273 
274 	pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
275 	if (!pte)
276 		return 0;
277 	if (!pte_present(ptep_get(pte)))
278 		goto out;
279 	damon_ptep_mkold(pte, walk->vma, addr);
280 out:
281 	pte_unmap_unlock(pte, ptl);
282 	return 0;
283 }
284 
285 #ifdef CONFIG_HUGETLB_PAGE
286 static int damon_mkold_hugetlb_entry(pte_t *pte, unsigned long hmask,
287 				     unsigned long addr, unsigned long end,
288 				     struct mm_walk *walk)
289 {
290 	struct hstate *h = hstate_vma(walk->vma);
291 	spinlock_t *ptl;
292 	pte_t entry;
293 
294 	ptl = huge_pte_lock(h, walk->mm, pte);
295 	entry = huge_ptep_get(walk->mm, addr, pte);
296 	if (!pte_present(entry))
297 		goto out;
298 
299 	damon_hugetlb_mkold(pte, walk->mm, walk->vma, addr);
300 
301 out:
302 	spin_unlock(ptl);
303 	return 0;
304 }
305 #else
306 #define damon_mkold_hugetlb_entry NULL
307 #endif /* CONFIG_HUGETLB_PAGE */
308 
309 static void damon_va_mkold(struct mm_struct *mm, unsigned long addr)
310 {
311 	struct mm_walk_ops damon_mkold_ops = {
312 		.pmd_entry = damon_mkold_pmd_entry,
313 		.hugetlb_entry = damon_mkold_hugetlb_entry,
314 	};
315 
316 	damon_va_walk_page_range(mm, addr, addr + 1, &damon_mkold_ops, NULL);
317 }
318 
319 /*
320  * Functions for the access checking of the regions
321  */
322 
323 static void __damon_va_prepare_access_check(struct mm_struct *mm,
324 					struct damon_region *r,
325 					struct damon_ctx *ctx)
326 {
327 	r->sampling_addr = damon_rand(ctx, r->ar.start, r->ar.end);
328 
329 	damon_va_mkold(mm, r->sampling_addr);
330 }
331 
332 static void damon_va_prepare_access_checks(struct damon_ctx *ctx)
333 {
334 	struct damon_target *t;
335 	struct mm_struct *mm;
336 	struct damon_region *r;
337 
338 	damon_for_each_target(t, ctx) {
339 		mm = damon_get_mm(t);
340 		if (!mm)
341 			continue;
342 		damon_for_each_region(r, t)
343 			__damon_va_prepare_access_check(mm, r, ctx);
344 		mmput(mm);
345 	}
346 }
347 
348 struct damon_young_walk_private {
349 	bool young;
350 };
351 
352 static int damon_young_pmd_entry(pmd_t *pmd, unsigned long addr,
353 		unsigned long next, struct mm_walk *walk)
354 {
355 	pte_t *pte;
356 	pte_t ptent;
357 	spinlock_t *ptl;
358 	struct folio *folio;
359 	struct damon_young_walk_private *priv = walk->private;
360 
361 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
362 	ptl = pmd_trans_huge_lock(pmd, walk->vma);
363 	if (ptl) {
364 		pmd_t pmde = pmdp_get(pmd);
365 
366 		if (!pmd_present(pmde))
367 			goto huge_out;
368 		folio = vm_normal_folio_pmd(walk->vma, addr, pmde);
369 		if (!folio)
370 			goto huge_out;
371 		if (pmd_young(pmde) || !folio_test_idle(folio) ||
372 					mmu_notifier_test_young(walk->mm,
373 						addr))
374 			priv->young = true;
375 huge_out:
376 		spin_unlock(ptl);
377 		return 0;
378 	}
379 #endif	/* CONFIG_TRANSPARENT_HUGEPAGE */
380 
381 	pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
382 	if (!pte)
383 		return 0;
384 	ptent = ptep_get(pte);
385 	if (!pte_present(ptent))
386 		goto out;
387 	folio = vm_normal_folio(walk->vma, addr, ptent);
388 	if (!folio)
389 		goto out;
390 	if (pte_young(ptent) || !folio_test_idle(folio) ||
391 			mmu_notifier_test_young(walk->mm, addr))
392 		priv->young = true;
393 out:
394 	pte_unmap_unlock(pte, ptl);
395 	return 0;
396 }
397 
398 #ifdef CONFIG_HUGETLB_PAGE
399 static int damon_young_hugetlb_entry(pte_t *pte, unsigned long hmask,
400 				     unsigned long addr, unsigned long end,
401 				     struct mm_walk *walk)
402 {
403 	struct damon_young_walk_private *priv = walk->private;
404 	struct hstate *h = hstate_vma(walk->vma);
405 	struct folio *folio;
406 	spinlock_t *ptl;
407 	pte_t entry;
408 
409 	ptl = huge_pte_lock(h, walk->mm, pte);
410 	entry = huge_ptep_get(walk->mm, addr, pte);
411 	if (!pte_present(entry))
412 		goto out;
413 
414 	folio = pfn_folio(pte_pfn(entry));
415 	folio_get(folio);
416 
417 	if (pte_young(entry) || !folio_test_idle(folio) ||
418 	    mmu_notifier_test_young(walk->mm, addr))
419 		priv->young = true;
420 
421 	folio_put(folio);
422 
423 out:
424 	spin_unlock(ptl);
425 	return 0;
426 }
427 #else
428 #define damon_young_hugetlb_entry NULL
429 #endif /* CONFIG_HUGETLB_PAGE */
430 
431 static bool damon_va_young(struct mm_struct *mm, unsigned long addr)
432 {
433 	struct damon_young_walk_private arg = {
434 		.young = false,
435 	};
436 
437 	struct mm_walk_ops damon_young_ops = {
438 		.pmd_entry = damon_young_pmd_entry,
439 		.hugetlb_entry = damon_young_hugetlb_entry,
440 	};
441 
442 	damon_va_walk_page_range(mm, addr, addr + 1, &damon_young_ops, &arg);
443 	return arg.young;
444 }
445 
446 /*
447  * Check whether the region was accessed after the last preparation
448  *
449  * mm	'mm_struct' for the given virtual address space
450  * r	the region to be checked
451  */
452 static void __damon_va_check_access(struct mm_struct *mm,
453 				struct damon_region *r)
454 {
455 	bool accessed;
456 
457 	if (!mm) {
458 		damon_update_region_access_rate(r, false);
459 		return;
460 	}
461 
462 	accessed = damon_va_young(mm, r->sampling_addr);
463 	damon_update_region_access_rate(r, accessed);
464 }
465 
466 static unsigned int damon_va_check_accesses(struct damon_ctx *ctx)
467 {
468 	struct damon_target *t;
469 	struct mm_struct *mm;
470 	struct damon_region *r;
471 	unsigned int max_nr_accesses = 0;
472 
473 	damon_for_each_target(t, ctx) {
474 		mm = damon_get_mm(t);
475 		damon_for_each_region(r, t) {
476 			__damon_va_check_access(mm, r);
477 			max_nr_accesses = max(r->nr_accesses, max_nr_accesses);
478 		}
479 		if (mm)
480 			mmput(mm);
481 	}
482 
483 	return max_nr_accesses;
484 }
485 
486 static void damon_va_prep_probe_region(struct damon_ctx *ctx,
487 		struct mm_struct *mm, struct damon_region *r,
488 		struct damon_probe *probe)
489 {
490 	struct damon_prep *p;
491 
492 	damon_for_each_prep(p, probe) {
493 		switch (p->action) {
494 		case DAMON_PREP_SET_PGIDLE:
495 			damon_va_mkold(mm, r->sampling_addr);
496 			break;
497 		default:
498 			break;
499 		}
500 	}
501 }
502 
503 static void damon_va_prep_probes(struct damon_ctx *ctx, bool set_samples)
504 {
505 	struct damon_target *t;
506 	struct mm_struct *mm;
507 	struct damon_region *r;
508 	struct damon_probe *p;
509 
510 	damon_for_each_target(t, ctx) {
511 		mm = damon_get_mm(t);
512 		if (!mm)
513 			continue;
514 		damon_for_each_region(r, t) {
515 			if (set_samples)
516 				r->sampling_addr = damon_rand(ctx, r->ar.start,
517 						r->ar.end);
518 			damon_for_each_probe(p, ctx)
519 				damon_va_prep_probe_region(ctx, mm, r, p);
520 		}
521 		mmput(mm);
522 	}
523 }
524 
525 static bool damon_va_young_addr(struct folio *folio, pte_t *pte, pmd_t *pmd,
526 		struct mm_struct *mm, unsigned long addr)
527 {
528 	bool young = false;
529 
530 	if (pte)
531 		young = pte_young(*pte);
532 	else if (pmd)
533 		young = pmd_young(*pmd);
534 	young = young || !folio_test_idle(folio) ||
535 		mmu_notifier_test_young(mm, addr);
536 	return young;
537 }
538 
539 static bool damon_va_filter_match(struct damon_filter *filter,
540 		struct folio *folio, pte_t *pte, pmd_t *pmd,
541 		struct mm_struct *mm, unsigned long addr)
542 {
543 	bool matched = false;
544 
545 	switch (filter->type) {
546 	case DAMON_FILTER_TYPE_PGIDLE_UNSET:
547 		if (!folio)
548 			matched = false;
549 		else
550 			matched = damon_va_young_addr(folio, pte, pmd, mm,
551 					addr);
552 		break;
553 	case DAMON_FILTER_TYPE_PGIDLE_SET:
554 		if (!folio)
555 			matched = false;
556 		else
557 			matched = !damon_va_young_addr(folio, pte, pmd, mm,
558 					addr);
559 		break;
560 	default:
561 		return damon_ops_filter_match(filter, folio);
562 	}
563 	return matched == filter->matching;
564 }
565 
566 static bool damon_va_filter_pass(struct folio *folio, struct damon_probe *p,
567 		pte_t *pte, pmd_t *pmd, struct mm_struct *mm,
568 		unsigned long addr)
569 {
570 	struct damon_filter *f;
571 	bool pass = true;
572 
573 	damon_for_each_filter(f, p) {
574 		if (damon_va_filter_match(f, folio, pte, pmd, mm, addr)) {
575 			pass = f->allow;
576 			break;
577 		}
578 		pass = !f->allow;
579 	}
580 	return pass;
581 }
582 
583 struct damon_va_probe_walk_private {
584 	struct damon_ctx *ctx;
585 	struct damon_region *r;
586 };
587 
588 static void damon_va_probe_folio(struct damon_ctx *ctx,
589 		struct damon_region *r, struct folio *folio,
590 		pte_t *pte, pmd_t *pmd, struct mm_struct *mm)
591 {
592 	struct damon_probe *probe;
593 	int i = 0;
594 
595 	damon_for_each_probe(probe, ctx) {
596 		if (damon_va_filter_pass(folio, probe, pte, pmd, mm,
597 					r->sampling_addr))
598 			r->probe_hits[i]++;
599 		i++;
600 	}
601 }
602 
603 static int damon_va_probe_pmd_entry(pmd_t *pmd, unsigned long addr,
604 		unsigned long next, struct mm_walk *walk)
605 {
606 	pte_t *pte;
607 	pte_t ptent;
608 	spinlock_t *ptl;
609 	struct folio *folio;
610 	struct damon_va_probe_walk_private *priv = walk->private;
611 
612 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
613 	ptl = pmd_trans_huge_lock(pmd, walk->vma);
614 	if (ptl) {
615 		pmd_t pmde = pmdp_get(pmd);
616 
617 		if (!pmd_present(pmde))
618 			goto huge_out;
619 		folio = vm_normal_folio_pmd(walk->vma, addr, pmde);
620 		if (!folio)
621 			goto huge_out;
622 		damon_va_probe_folio(priv->ctx, priv->r, folio, NULL, &pmde,
623 				walk->vma->vm_mm);
624 
625 huge_out:
626 		spin_unlock(ptl);
627 		return 0;
628 	}
629 #endif	/* CONFIG_TRANSPARENT_HUGEPAGE */
630 
631 	pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
632 	if (!pte)
633 		return 0;
634 	ptent = ptep_get(pte);
635 	if (!pte_present(ptent))
636 		goto out;
637 	folio = vm_normal_folio(walk->vma, addr, ptent);
638 	if (!folio)
639 		goto out;
640 	damon_va_probe_folio(priv->ctx, priv->r, folio, &ptent, NULL,
641 			walk->vma->vm_mm);
642 
643 out:
644 	pte_unmap_unlock(pte, ptl);
645 	return 0;
646 }
647 
648 #ifdef CONFIG_HUGETLB_PAGE
649 static int damon_va_probe_hugetlb_entry(pte_t *pte, unsigned long hmask,
650 		unsigned long addr, unsigned long end, struct mm_walk *walk)
651 {
652 	struct damon_va_probe_walk_private *priv = walk->private;
653 	struct hstate *h = hstate_vma(walk->vma);
654 	struct folio *folio;
655 	spinlock_t *ptl;
656 	pte_t entry;
657 
658 	ptl = huge_pte_lock(h, walk->mm, pte);
659 	entry = huge_ptep_get(walk->mm, addr, pte);
660 	if (!pte_present(entry))
661 		goto out;
662 
663 	folio = pfn_folio(pte_pfn(entry));
664 	folio_get(folio);
665 	damon_va_probe_folio(priv->ctx, priv->r, folio, &entry, NULL,
666 			walk->vma->vm_mm);
667 	folio_put(folio);
668 
669 out:
670 	spin_unlock(ptl);
671 	return 0;
672 }
673 #else
674 #define damon_va_probe_hugetlb_entry NULL
675 #endif /* CONFIG_HUGETLB_PAGE */
676 
677 static void __damon_va_apply_probes(struct damon_ctx *ctx,
678 		struct mm_struct *mm,  struct damon_region *r)
679 {
680 	struct damon_va_probe_walk_private arg = {
681 		.ctx = ctx,
682 		.r = r,
683 	};
684 	struct mm_walk_ops damon_probe_walk_ops = {
685 		.pmd_entry = damon_va_probe_pmd_entry,
686 		.hugetlb_entry = damon_va_probe_hugetlb_entry,
687 	};
688 	unsigned long addr = r->sampling_addr;
689 
690 	if (!mm)
691 		return;
692 
693 	damon_va_walk_page_range(mm, addr, addr + 1, &damon_probe_walk_ops,
694 			&arg);
695 }
696 
697 static unsigned int damon_va_apply_probes(struct damon_ctx *ctx,
698 		bool set_samples, bool return_max_wsum)
699 {
700 	struct damon_target *t;
701 	struct mm_struct *mm;
702 	struct damon_region *r;
703 	unsigned int max_wsum = 0;
704 
705 	damon_for_each_target(t, ctx) {
706 		mm = damon_get_mm(t);
707 		damon_for_each_region(r, t) {
708 			if (set_samples)
709 				r->sampling_addr = damon_rand(ctx, r->ar.start,
710 						r->ar.end);
711 			__damon_va_apply_probes(ctx, mm, r);
712 			if (return_max_wsum)
713 				max_wsum = max(damon_probe_hits_wsum(r, false,
714 							false, ctx), max_wsum);
715 		}
716 		if (mm)
717 			mmput(mm);
718 	}
719 
720 	return max_wsum;
721 }
722 
723 static bool damos_va_filter_young_match(struct damos_filter *filter,
724 		struct folio *folio, struct vm_area_struct *vma,
725 		unsigned long addr, pte_t *ptep, pmd_t *pmdp)
726 {
727 	bool young = false;
728 
729 	if (ptep)
730 		young = pte_young(ptep_get(ptep));
731 	else if (pmdp)
732 		young = pmd_young(pmdp_get(pmdp));
733 
734 	young = young || !folio_test_idle(folio) ||
735 		mmu_notifier_test_young(vma->vm_mm, addr);
736 
737 	if (young && ptep)
738 		damon_ptep_mkold(ptep, vma, addr);
739 	else if (young && pmdp)
740 		damon_pmdp_mkold(pmdp, vma, addr);
741 
742 	return young == filter->matching;
743 }
744 
745 static bool damos_va_filter_out(struct damos *scheme, struct folio *folio,
746 		struct vm_area_struct *vma, unsigned long addr,
747 		pte_t *ptep, pmd_t *pmdp)
748 {
749 	struct damos_filter *filter;
750 	bool matched;
751 
752 	if (scheme->core_filters_allowed)
753 		return false;
754 
755 	damos_for_each_ops_filter(filter, scheme) {
756 		/*
757 		 * damos_folio_filter_match checks the young filter by doing an
758 		 * rmap on the folio to find its page table. However, being the
759 		 * vaddr scheme, we have direct access to the page tables, so
760 		 * use that instead.
761 		 */
762 		if (filter->type == DAMOS_FILTER_TYPE_YOUNG)
763 			matched = damos_va_filter_young_match(filter, folio,
764 				vma, addr, ptep, pmdp);
765 		else
766 			matched = damos_folio_filter_match(filter, folio);
767 
768 		if (matched)
769 			return !filter->allow;
770 	}
771 	return scheme->ops_filters_default_reject;
772 }
773 
774 struct damos_va_migrate_private {
775 	struct list_head *migration_lists;
776 	struct damos *scheme;
777 };
778 
779 /*
780  * Place the given folio in the migration_list corresponding to where the folio
781  * should be migrated.
782  *
783  * The algorithm used here is similar to weighted_interleave_nid()
784  */
785 static void damos_va_migrate_dests_add(struct folio *folio,
786 		struct vm_area_struct *vma, unsigned long addr,
787 		struct damos_migrate_dests *dests,
788 		struct list_head *migration_lists)
789 {
790 	pgoff_t ilx;
791 	int order;
792 	unsigned int target;
793 	unsigned int weight_total = 0;
794 	int i;
795 
796 	/*
797 	 * If dests is empty, there is only one migration list corresponding
798 	 * to s->target_nid.
799 	 */
800 	if (!dests->nr_dests) {
801 		i = 0;
802 		goto isolate;
803 	}
804 
805 	order = folio_order(folio);
806 	ilx = vma_start_pgoff(vma) >> order;
807 	ilx += linear_page_delta(vma, addr) >> order;
808 
809 	for (i = 0; i < dests->nr_dests; i++)
810 		weight_total += dests->weight_arr[i];
811 
812 	/* If the total weights are somehow 0, don't migrate at all */
813 	if (!weight_total)
814 		return;
815 
816 	target = ilx % weight_total;
817 	for (i = 0; i < dests->nr_dests; i++) {
818 		if (target < dests->weight_arr[i])
819 			break;
820 		target -= dests->weight_arr[i];
821 	}
822 
823 	/* If the folio is already in the right node, don't do anything */
824 	if (folio_nid(folio) == dests->node_id_arr[i])
825 		return;
826 
827 isolate:
828 	if (!folio_isolate_lru(folio))
829 		return;
830 	node_stat_add_folio(folio, NR_ISOLATED_ANON +
831 			folio_is_file_lru(folio));
832 	list_add(&folio->lru, &migration_lists[i]);
833 }
834 
835 static int damos_va_migrate_pmd_entry(pmd_t *pmd, unsigned long addr,
836 		unsigned long next, struct mm_walk *walk)
837 {
838 	struct damos_va_migrate_private *priv = walk->private;
839 	struct list_head *migration_lists = priv->migration_lists;
840 	struct damos *s = priv->scheme;
841 	struct damos_migrate_dests *dests = &s->migrate_dests;
842 	struct folio *folio;
843 	spinlock_t *ptl;
844 	pte_t *start_pte, *pte, ptent;
845 	int nr;
846 
847 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
848 	ptl = pmd_trans_huge_lock(pmd, walk->vma);
849 	if (ptl) {
850 		pmd_t pmde = pmdp_get(pmd);
851 
852 		if (!pmd_present(pmde))
853 			goto huge_out;
854 		folio = vm_normal_folio_pmd(walk->vma, addr, pmde);
855 		if (!folio)
856 			goto huge_out;
857 		if (damos_va_filter_out(s, folio, walk->vma, addr, NULL, pmd))
858 			goto huge_out;
859 		damos_va_migrate_dests_add(folio, walk->vma, addr, dests,
860 				migration_lists);
861 huge_out:
862 		spin_unlock(ptl);
863 		return 0;
864 	}
865 #endif	/* CONFIG_TRANSPARENT_HUGEPAGE */
866 
867 	start_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
868 	if (!pte)
869 		return 0;
870 
871 	for (; addr < next; pte += nr, addr += nr * PAGE_SIZE) {
872 		unsigned long page_idx;
873 
874 		nr = 1;
875 		ptent = ptep_get(pte);
876 
877 		if (pte_none(ptent) || !pte_present(ptent))
878 			continue;
879 		folio = vm_normal_folio(walk->vma, addr, ptent);
880 		if (!folio)
881 			continue;
882 		if (damos_va_filter_out(s, folio, walk->vma, addr, pte, NULL))
883 			continue;
884 		damos_va_migrate_dests_add(folio, walk->vma, addr, dests,
885 				migration_lists);
886 		page_idx = folio_page_idx(folio, pte_page(ptent));
887 		nr = folio_nr_pages(folio) - page_idx;
888 	}
889 	pte_unmap_unlock(start_pte, ptl);
890 	return 0;
891 }
892 
893 /*
894  * Functions for the target validity check and cleanup
895  */
896 
897 static bool damon_va_target_valid(struct damon_target *t)
898 {
899 	struct task_struct *task;
900 
901 	task = damon_get_task_struct(t);
902 	if (task) {
903 		put_task_struct(task);
904 		return true;
905 	}
906 
907 	return false;
908 }
909 
910 static void damon_va_cleanup_target(struct damon_target *t)
911 {
912 	put_pid(t->pid);
913 }
914 
915 #ifndef CONFIG_ADVISE_SYSCALLS
916 static unsigned long damos_madvise(struct damon_target *target,
917 		struct damon_region *r, int behavior)
918 {
919 	return 0;
920 }
921 #else
922 static unsigned long damos_madvise(struct damon_target *target,
923 		struct damon_region *r, int behavior)
924 {
925 	struct mm_struct *mm;
926 	unsigned long start = PAGE_ALIGN(r->ar.start);
927 	unsigned long len = PAGE_ALIGN(damon_sz_region(r));
928 	unsigned long applied;
929 
930 	mm = damon_get_mm(target);
931 	if (!mm)
932 		return 0;
933 
934 	applied = do_madvise(mm, start, len, behavior) ? 0 : len;
935 	mmput(mm);
936 
937 	return applied;
938 }
939 #endif	/* CONFIG_ADVISE_SYSCALLS */
940 
941 static unsigned long damos_va_migrate(struct damon_target *target,
942 		struct damon_region *r, struct damos *s,
943 		unsigned long *sz_filter_passed)
944 {
945 	LIST_HEAD(folio_list);
946 	struct damos_va_migrate_private priv;
947 	struct mm_struct *mm;
948 	int nr_dests;
949 	int nid;
950 	bool use_target_nid;
951 	unsigned long applied = 0;
952 	struct damos_migrate_dests *dests = &s->migrate_dests;
953 	struct mm_walk_ops walk_ops = {
954 		.pmd_entry = damos_va_migrate_pmd_entry,
955 		.pte_entry = NULL,
956 	};
957 
958 	use_target_nid = dests->nr_dests == 0;
959 	nr_dests = use_target_nid ? 1 : dests->nr_dests;
960 	priv.scheme = s;
961 	priv.migration_lists = kmalloc_objs(*priv.migration_lists, nr_dests);
962 	if (!priv.migration_lists)
963 		return 0;
964 
965 	for (int i = 0; i < nr_dests; i++)
966 		INIT_LIST_HEAD(&priv.migration_lists[i]);
967 
968 
969 	mm = damon_get_mm(target);
970 	if (!mm)
971 		goto free_lists;
972 
973 	damon_va_walk_page_range(mm, r->ar.start, r->ar.end, &walk_ops, &priv);
974 	mmput(mm);
975 
976 	for (int i = 0; i < nr_dests; i++) {
977 		nid = use_target_nid ? s->target_nid : dests->node_id_arr[i];
978 		applied += damon_migrate_pages(&priv.migration_lists[i], nid);
979 		cond_resched();
980 	}
981 
982 free_lists:
983 	kfree(priv.migration_lists);
984 	return applied * PAGE_SIZE;
985 }
986 
987 struct damos_va_stat_private {
988 	struct damos *scheme;
989 	unsigned long *sz_filter_passed;
990 };
991 
992 static inline bool damos_va_invalid_folio(struct folio *folio,
993 		struct damos *s)
994 {
995 	return !folio || folio == s->last_applied;
996 }
997 
998 static int damos_va_stat_pmd_entry(pmd_t *pmd, unsigned long addr,
999 		unsigned long next, struct mm_walk *walk)
1000 {
1001 	struct damos_va_stat_private *priv = walk->private;
1002 	struct damos *s = priv->scheme;
1003 	unsigned long *sz_filter_passed = priv->sz_filter_passed;
1004 	struct vm_area_struct *vma = walk->vma;
1005 	struct folio *folio;
1006 	spinlock_t *ptl;
1007 	pte_t *start_pte, *pte, ptent;
1008 	int nr;
1009 
1010 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
1011 	ptl = pmd_trans_huge_lock(pmd, vma);
1012 	if (ptl) {
1013 		pmd_t pmde = pmdp_get(pmd);
1014 
1015 		if (!pmd_present(pmde))
1016 			goto huge_unlock;
1017 
1018 		folio = vm_normal_folio_pmd(vma, addr, pmde);
1019 
1020 		if (damos_va_invalid_folio(folio, s))
1021 			goto huge_unlock;
1022 
1023 		if (!damos_va_filter_out(s, folio, vma, addr, NULL, pmd))
1024 			*sz_filter_passed += folio_size(folio);
1025 		s->last_applied = folio;
1026 
1027 huge_unlock:
1028 		spin_unlock(ptl);
1029 		return 0;
1030 	}
1031 #endif
1032 	start_pte = pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
1033 	if (!start_pte)
1034 		return 0;
1035 
1036 	for (; addr < next; pte += nr, addr += nr * PAGE_SIZE) {
1037 		unsigned long page_idx;
1038 
1039 		nr = 1;
1040 		ptent = ptep_get(pte);
1041 
1042 		if (pte_none(ptent) || !pte_present(ptent))
1043 			continue;
1044 
1045 		folio = vm_normal_folio(vma, addr, ptent);
1046 
1047 		if (damos_va_invalid_folio(folio, s))
1048 			continue;
1049 
1050 		if (!damos_va_filter_out(s, folio, vma, addr, pte, NULL))
1051 			*sz_filter_passed += folio_size(folio);
1052 		page_idx = folio_page_idx(folio, pte_page(ptent));
1053 		nr = folio_nr_pages(folio) - page_idx;
1054 		s->last_applied = folio;
1055 	}
1056 	pte_unmap_unlock(start_pte, ptl);
1057 	return 0;
1058 }
1059 
1060 static unsigned long damos_va_stat(struct damon_target *target,
1061 		struct damon_region *r, struct damos *s,
1062 		unsigned long *sz_filter_passed)
1063 {
1064 	struct damos_va_stat_private priv;
1065 	struct mm_struct *mm;
1066 	struct mm_walk_ops walk_ops = {
1067 		.pmd_entry = damos_va_stat_pmd_entry,
1068 	};
1069 
1070 	priv.scheme = s;
1071 	priv.sz_filter_passed = sz_filter_passed;
1072 
1073 	if (!damos_ops_has_filter(s))
1074 		return 0;
1075 
1076 	mm = damon_get_mm(target);
1077 	if (!mm)
1078 		return 0;
1079 
1080 	damon_va_walk_page_range(mm, r->ar.start, r->ar.end, &walk_ops, &priv);
1081 	mmput(mm);
1082 	return 0;
1083 }
1084 
1085 static unsigned long damon_va_apply_scheme(struct damon_ctx *ctx,
1086 		struct damon_target *t, struct damon_region *r,
1087 		struct damos *scheme, unsigned long *sz_filter_passed)
1088 {
1089 	int madv_action;
1090 
1091 	switch (scheme->action) {
1092 	case DAMOS_WILLNEED:
1093 		madv_action = MADV_WILLNEED;
1094 		break;
1095 	case DAMOS_COLD:
1096 		madv_action = MADV_COLD;
1097 		break;
1098 	case DAMOS_PAGEOUT:
1099 		madv_action = MADV_PAGEOUT;
1100 		break;
1101 	case DAMOS_HUGEPAGE:
1102 		madv_action = MADV_HUGEPAGE;
1103 		break;
1104 	case DAMOS_NOHUGEPAGE:
1105 		madv_action = MADV_NOHUGEPAGE;
1106 		break;
1107 	case DAMOS_COLLAPSE:
1108 		madv_action = MADV_COLLAPSE;
1109 		break;
1110 	case DAMOS_MIGRATE_HOT:
1111 	case DAMOS_MIGRATE_COLD:
1112 		return damos_va_migrate(t, r, scheme, sz_filter_passed);
1113 	case DAMOS_STAT:
1114 		return damos_va_stat(t, r, scheme, sz_filter_passed);
1115 	default:
1116 		/*
1117 		 * DAMOS actions that are not yet supported by 'vaddr'.
1118 		 */
1119 		return 0;
1120 	}
1121 
1122 	return damos_madvise(t, r, madv_action);
1123 }
1124 
1125 static int damon_va_scheme_score(struct damon_ctx *context,
1126 		struct damon_region *r, struct damos *scheme)
1127 {
1128 
1129 	switch (scheme->action) {
1130 	case DAMOS_PAGEOUT:
1131 		return damon_cold_score(context, r, scheme);
1132 	case DAMOS_MIGRATE_HOT:
1133 		return damon_hot_score(context, r, scheme);
1134 	case DAMOS_MIGRATE_COLD:
1135 		return damon_cold_score(context, r, scheme);
1136 	default:
1137 		break;
1138 	}
1139 
1140 	return DAMOS_MAX_SCORE;
1141 }
1142 
1143 static int __init damon_va_initcall(void)
1144 {
1145 	struct damon_operations ops = {
1146 		.id = DAMON_OPS_VADDR,
1147 		.init = damon_va_init,
1148 		.update = damon_va_update,
1149 		.prepare_access_checks = damon_va_prepare_access_checks,
1150 		.check_accesses = damon_va_check_accesses,
1151 		.prep_probes = damon_va_prep_probes,
1152 		.apply_probes = damon_va_apply_probes,
1153 		.target_valid = damon_va_target_valid,
1154 		.cleanup_target = damon_va_cleanup_target,
1155 		.apply_scheme = damon_va_apply_scheme,
1156 		.get_scheme_score = damon_va_scheme_score,
1157 	};
1158 	/* ops for fixed virtual address ranges */
1159 	struct damon_operations ops_fvaddr = ops;
1160 	int err;
1161 
1162 	/* Don't set the monitoring target regions for the entire mapping */
1163 	ops_fvaddr.id = DAMON_OPS_FVADDR;
1164 	ops_fvaddr.init = NULL;
1165 	ops_fvaddr.update = NULL;
1166 
1167 	err = damon_register_ops(&ops);
1168 	if (err)
1169 		return err;
1170 	return damon_register_ops(&ops_fvaddr);
1171 }
1172 
1173 subsys_initcall(damon_va_initcall);
1174 
1175 #include "tests/vaddr-kunit.h"
1176