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