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