xref: /linux/mm/damon/vaddr.c (revision 1bd470f27f283cfcfd5c94705a2fabbe5f1e4e9f)
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 
653 	list_add(&folio->lru, &migration_lists[i]);
654 }
655 
656 static int damos_va_migrate_pmd_entry(pmd_t *pmd, unsigned long addr,
657 		unsigned long next, struct mm_walk *walk)
658 {
659 	struct damos_va_migrate_private *priv = walk->private;
660 	struct list_head *migration_lists = priv->migration_lists;
661 	struct damos *s = priv->scheme;
662 	struct damos_migrate_dests *dests = &s->migrate_dests;
663 	struct folio *folio;
664 	spinlock_t *ptl;
665 	pte_t *start_pte, *pte, ptent;
666 	int nr;
667 
668 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
669 	ptl = pmd_trans_huge_lock(pmd, walk->vma);
670 	if (ptl) {
671 		pmd_t pmde = pmdp_get(pmd);
672 
673 		if (!pmd_present(pmde))
674 			goto huge_out;
675 		folio = vm_normal_folio_pmd(walk->vma, addr, pmde);
676 		if (!folio)
677 			goto huge_out;
678 		if (damos_va_filter_out(s, folio, walk->vma, addr, NULL, pmd))
679 			goto huge_out;
680 		damos_va_migrate_dests_add(folio, walk->vma, addr, dests,
681 				migration_lists);
682 huge_out:
683 		spin_unlock(ptl);
684 		return 0;
685 	}
686 #endif	/* CONFIG_TRANSPARENT_HUGEPAGE */
687 
688 	start_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
689 	if (!pte)
690 		return 0;
691 
692 	for (; addr < next; pte += nr, addr += nr * PAGE_SIZE) {
693 		nr = 1;
694 		ptent = ptep_get(pte);
695 
696 		if (pte_none(ptent) || !pte_present(ptent))
697 			continue;
698 		folio = vm_normal_folio(walk->vma, addr, ptent);
699 		if (!folio)
700 			continue;
701 		if (damos_va_filter_out(s, folio, walk->vma, addr, pte, NULL))
702 			continue;
703 		damos_va_migrate_dests_add(folio, walk->vma, addr, dests,
704 				migration_lists);
705 		nr = folio_nr_pages(folio);
706 	}
707 	pte_unmap_unlock(start_pte, ptl);
708 	return 0;
709 }
710 
711 /*
712  * Functions for the target validity check and cleanup
713  */
714 
715 static bool damon_va_target_valid(struct damon_target *t)
716 {
717 	struct task_struct *task;
718 
719 	task = damon_get_task_struct(t);
720 	if (task) {
721 		put_task_struct(task);
722 		return true;
723 	}
724 
725 	return false;
726 }
727 
728 static void damon_va_cleanup_target(struct damon_target *t)
729 {
730 	put_pid(t->pid);
731 }
732 
733 #ifndef CONFIG_ADVISE_SYSCALLS
734 static unsigned long damos_madvise(struct damon_target *target,
735 		struct damon_region *r, int behavior)
736 {
737 	return 0;
738 }
739 #else
740 static unsigned long damos_madvise(struct damon_target *target,
741 		struct damon_region *r, int behavior)
742 {
743 	struct mm_struct *mm;
744 	unsigned long start = PAGE_ALIGN(r->ar.start);
745 	unsigned long len = PAGE_ALIGN(damon_sz_region(r));
746 	unsigned long applied;
747 
748 	mm = damon_get_mm(target);
749 	if (!mm)
750 		return 0;
751 
752 	applied = do_madvise(mm, start, len, behavior) ? 0 : len;
753 	mmput(mm);
754 
755 	return applied;
756 }
757 #endif	/* CONFIG_ADVISE_SYSCALLS */
758 
759 static unsigned long damos_va_migrate(struct damon_target *target,
760 		struct damon_region *r, struct damos *s,
761 		unsigned long *sz_filter_passed)
762 {
763 	LIST_HEAD(folio_list);
764 	struct damos_va_migrate_private priv;
765 	struct mm_struct *mm;
766 	int nr_dests;
767 	int nid;
768 	bool use_target_nid;
769 	unsigned long applied = 0;
770 	struct damos_migrate_dests *dests = &s->migrate_dests;
771 	struct mm_walk_ops walk_ops = {
772 		.pmd_entry = damos_va_migrate_pmd_entry,
773 		.pte_entry = NULL,
774 	};
775 
776 	use_target_nid = dests->nr_dests == 0;
777 	nr_dests = use_target_nid ? 1 : dests->nr_dests;
778 	priv.scheme = s;
779 	priv.migration_lists = kmalloc_objs(*priv.migration_lists, nr_dests);
780 	if (!priv.migration_lists)
781 		return 0;
782 
783 	for (int i = 0; i < nr_dests; i++)
784 		INIT_LIST_HEAD(&priv.migration_lists[i]);
785 
786 
787 	mm = damon_get_mm(target);
788 	if (!mm)
789 		goto free_lists;
790 
791 	damon_va_walk_page_range(mm, r->ar.start, r->ar.end, &walk_ops, &priv);
792 	mmput(mm);
793 
794 	for (int i = 0; i < nr_dests; i++) {
795 		nid = use_target_nid ? s->target_nid : dests->node_id_arr[i];
796 		applied += damon_migrate_pages(&priv.migration_lists[i], nid);
797 		cond_resched();
798 	}
799 
800 free_lists:
801 	kfree(priv.migration_lists);
802 	return applied * PAGE_SIZE;
803 }
804 
805 struct damos_va_stat_private {
806 	struct damos *scheme;
807 	unsigned long *sz_filter_passed;
808 };
809 
810 static inline bool damos_va_invalid_folio(struct folio *folio,
811 		struct damos *s)
812 {
813 	return !folio || folio == s->last_applied;
814 }
815 
816 static int damos_va_stat_pmd_entry(pmd_t *pmd, unsigned long addr,
817 		unsigned long next, struct mm_walk *walk)
818 {
819 	struct damos_va_stat_private *priv = walk->private;
820 	struct damos *s = priv->scheme;
821 	unsigned long *sz_filter_passed = priv->sz_filter_passed;
822 	struct vm_area_struct *vma = walk->vma;
823 	struct folio *folio;
824 	spinlock_t *ptl;
825 	pte_t *start_pte, *pte, ptent;
826 	int nr;
827 
828 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
829 	ptl = pmd_trans_huge_lock(pmd, vma);
830 	if (ptl) {
831 		pmd_t pmde = pmdp_get(pmd);
832 
833 		if (!pmd_present(pmde))
834 			goto huge_unlock;
835 
836 		folio = vm_normal_folio_pmd(vma, addr, pmde);
837 
838 		if (damos_va_invalid_folio(folio, s))
839 			goto huge_unlock;
840 
841 		if (!damos_va_filter_out(s, folio, vma, addr, NULL, pmd))
842 			*sz_filter_passed += folio_size(folio);
843 		s->last_applied = folio;
844 
845 huge_unlock:
846 		spin_unlock(ptl);
847 		return 0;
848 	}
849 #endif
850 	start_pte = pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
851 	if (!start_pte)
852 		return 0;
853 
854 	for (; addr < next; pte += nr, addr += nr * PAGE_SIZE) {
855 		nr = 1;
856 		ptent = ptep_get(pte);
857 
858 		if (pte_none(ptent) || !pte_present(ptent))
859 			continue;
860 
861 		folio = vm_normal_folio(vma, addr, ptent);
862 
863 		if (damos_va_invalid_folio(folio, s))
864 			continue;
865 
866 		if (!damos_va_filter_out(s, folio, vma, addr, pte, NULL))
867 			*sz_filter_passed += folio_size(folio);
868 		nr = folio_nr_pages(folio);
869 		s->last_applied = folio;
870 	}
871 	pte_unmap_unlock(start_pte, ptl);
872 	return 0;
873 }
874 
875 static unsigned long damos_va_stat(struct damon_target *target,
876 		struct damon_region *r, struct damos *s,
877 		unsigned long *sz_filter_passed)
878 {
879 	struct damos_va_stat_private priv;
880 	struct mm_struct *mm;
881 	struct mm_walk_ops walk_ops = {
882 		.pmd_entry = damos_va_stat_pmd_entry,
883 	};
884 
885 	priv.scheme = s;
886 	priv.sz_filter_passed = sz_filter_passed;
887 
888 	if (!damos_ops_has_filter(s))
889 		return 0;
890 
891 	mm = damon_get_mm(target);
892 	if (!mm)
893 		return 0;
894 
895 	damon_va_walk_page_range(mm, r->ar.start, r->ar.end, &walk_ops, &priv);
896 	mmput(mm);
897 	return 0;
898 }
899 
900 static unsigned long damon_va_apply_scheme(struct damon_ctx *ctx,
901 		struct damon_target *t, struct damon_region *r,
902 		struct damos *scheme, unsigned long *sz_filter_passed)
903 {
904 	int madv_action;
905 
906 	switch (scheme->action) {
907 	case DAMOS_WILLNEED:
908 		madv_action = MADV_WILLNEED;
909 		break;
910 	case DAMOS_COLD:
911 		madv_action = MADV_COLD;
912 		break;
913 	case DAMOS_PAGEOUT:
914 		madv_action = MADV_PAGEOUT;
915 		break;
916 	case DAMOS_HUGEPAGE:
917 		madv_action = MADV_HUGEPAGE;
918 		break;
919 	case DAMOS_NOHUGEPAGE:
920 		madv_action = MADV_NOHUGEPAGE;
921 		break;
922 	case DAMOS_COLLAPSE:
923 		madv_action = MADV_COLLAPSE;
924 		break;
925 	case DAMOS_MIGRATE_HOT:
926 	case DAMOS_MIGRATE_COLD:
927 		return damos_va_migrate(t, r, scheme, sz_filter_passed);
928 	case DAMOS_STAT:
929 		return damos_va_stat(t, r, scheme, sz_filter_passed);
930 	default:
931 		/*
932 		 * DAMOS actions that are not yet supported by 'vaddr'.
933 		 */
934 		return 0;
935 	}
936 
937 	return damos_madvise(t, r, madv_action);
938 }
939 
940 static int damon_va_scheme_score(struct damon_ctx *context,
941 		struct damon_region *r, struct damos *scheme)
942 {
943 
944 	switch (scheme->action) {
945 	case DAMOS_PAGEOUT:
946 		return damon_cold_score(context, r, scheme);
947 	case DAMOS_MIGRATE_HOT:
948 		return damon_hot_score(context, r, scheme);
949 	case DAMOS_MIGRATE_COLD:
950 		return damon_cold_score(context, r, scheme);
951 	default:
952 		break;
953 	}
954 
955 	return DAMOS_MAX_SCORE;
956 }
957 
958 static int __init damon_va_initcall(void)
959 {
960 	struct damon_operations ops = {
961 		.id = DAMON_OPS_VADDR,
962 		.init = damon_va_init,
963 		.update = damon_va_update,
964 		.prepare_access_checks = damon_va_prepare_access_checks,
965 		.check_accesses = damon_va_check_accesses,
966 		.target_valid = damon_va_target_valid,
967 		.cleanup_target = damon_va_cleanup_target,
968 		.apply_scheme = damon_va_apply_scheme,
969 		.get_scheme_score = damon_va_scheme_score,
970 	};
971 	/* ops for fixed virtual address ranges */
972 	struct damon_operations ops_fvaddr = ops;
973 	int err;
974 
975 	/* Don't set the monitoring target regions for the entire mapping */
976 	ops_fvaddr.id = DAMON_OPS_FVADDR;
977 	ops_fvaddr.init = NULL;
978 	ops_fvaddr.update = NULL;
979 
980 	err = damon_register_ops(&ops);
981 	if (err)
982 		return err;
983 	return damon_register_ops(&ops_fvaddr);
984 };
985 
986 subsys_initcall(damon_va_initcall);
987 
988 #include "tests/vaddr-kunit.h"
989