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 = damon_get_monitor_folio(pte_pfn(entry)); 415 if (!folio) 416 goto out; 417 418 if (pte_young(entry) || !folio_test_idle(folio) || 419 mmu_notifier_test_young(walk->mm, addr)) 420 priv->young = true; 421 422 folio_put(folio); 423 424 out: 425 spin_unlock(ptl); 426 return 0; 427 } 428 #else 429 #define damon_young_hugetlb_entry NULL 430 #endif /* CONFIG_HUGETLB_PAGE */ 431 432 static bool damon_va_young(struct mm_struct *mm, unsigned long addr) 433 { 434 struct damon_young_walk_private arg = { 435 .young = false, 436 }; 437 438 struct mm_walk_ops damon_young_ops = { 439 .pmd_entry = damon_young_pmd_entry, 440 .hugetlb_entry = damon_young_hugetlb_entry, 441 }; 442 443 damon_va_walk_page_range(mm, addr, addr + 1, &damon_young_ops, &arg); 444 return arg.young; 445 } 446 447 /* 448 * Check whether the region was accessed after the last preparation 449 * 450 * mm 'mm_struct' for the given virtual address space 451 * r the region to be checked 452 */ 453 static void __damon_va_check_access(struct mm_struct *mm, 454 struct damon_region *r) 455 { 456 bool accessed; 457 458 if (!mm) { 459 damon_update_region_access_rate(r, false); 460 return; 461 } 462 463 accessed = damon_va_young(mm, r->sampling_addr); 464 damon_update_region_access_rate(r, accessed); 465 } 466 467 static unsigned int damon_va_check_accesses(struct damon_ctx *ctx) 468 { 469 struct damon_target *t; 470 struct mm_struct *mm; 471 struct damon_region *r; 472 unsigned int max_nr_accesses = 0; 473 474 damon_for_each_target(t, ctx) { 475 mm = damon_get_mm(t); 476 damon_for_each_region(r, t) { 477 __damon_va_check_access(mm, r); 478 max_nr_accesses = max(r->nr_accesses, max_nr_accesses); 479 } 480 if (mm) 481 mmput(mm); 482 } 483 484 return max_nr_accesses; 485 } 486 487 static void damon_va_prep_probe_region(struct damon_ctx *ctx, 488 struct mm_struct *mm, struct damon_region *r, 489 struct damon_probe *probe) 490 { 491 struct damon_prep *p; 492 493 damon_for_each_prep(p, probe) { 494 switch (p->action) { 495 case DAMON_PREP_SET_PGIDLE: 496 damon_va_mkold(mm, r->sampling_addr); 497 break; 498 default: 499 break; 500 } 501 } 502 } 503 504 static void damon_va_prep_probes(struct damon_ctx *ctx, bool set_samples) 505 { 506 struct damon_target *t; 507 struct mm_struct *mm; 508 struct damon_region *r; 509 struct damon_probe *p; 510 511 damon_for_each_target(t, ctx) { 512 mm = damon_get_mm(t); 513 if (!mm) 514 continue; 515 damon_for_each_region(r, t) { 516 if (set_samples) 517 r->sampling_addr = damon_rand(ctx, r->ar.start, 518 r->ar.end); 519 damon_for_each_probe(p, ctx) 520 damon_va_prep_probe_region(ctx, mm, r, p); 521 } 522 mmput(mm); 523 } 524 } 525 526 static bool damon_va_young_addr(struct folio *folio, pte_t *pte, pmd_t *pmd, 527 struct mm_struct *mm, unsigned long addr) 528 { 529 bool young = false; 530 531 if (pte) 532 young = pte_young(*pte); 533 else if (pmd) 534 young = pmd_young(*pmd); 535 young = young || !folio_test_idle(folio) || 536 mmu_notifier_test_young(mm, addr); 537 return young; 538 } 539 540 static bool damon_va_filter_match(struct damon_filter *filter, 541 struct folio *folio, pte_t *pte, pmd_t *pmd, 542 struct mm_struct *mm, unsigned long addr) 543 { 544 bool matched = false; 545 546 switch (filter->type) { 547 case DAMON_FILTER_TYPE_PGIDLE_UNSET: 548 if (!folio) 549 matched = false; 550 else 551 matched = damon_va_young_addr(folio, pte, pmd, mm, 552 addr); 553 break; 554 case DAMON_FILTER_TYPE_PGIDLE_SET: 555 if (!folio) 556 matched = false; 557 else 558 matched = !damon_va_young_addr(folio, pte, pmd, mm, 559 addr); 560 break; 561 default: 562 return damon_ops_filter_match(filter, folio); 563 } 564 return matched == filter->matching; 565 } 566 567 static bool damon_va_filter_pass(struct folio *folio, struct damon_probe *p, 568 pte_t *pte, pmd_t *pmd, struct mm_struct *mm, 569 unsigned long addr) 570 { 571 struct damon_filter *f; 572 bool pass = true; 573 574 damon_for_each_filter(f, p) { 575 if (damon_va_filter_match(f, folio, pte, pmd, mm, addr)) { 576 pass = f->allow; 577 break; 578 } 579 pass = !f->allow; 580 } 581 return pass; 582 } 583 584 struct damon_va_probe_walk_private { 585 struct damon_ctx *ctx; 586 struct damon_region *r; 587 }; 588 589 static void damon_va_probe_folio(struct damon_ctx *ctx, 590 struct damon_region *r, struct folio *folio, 591 pte_t *pte, pmd_t *pmd, struct mm_struct *mm) 592 { 593 struct damon_probe *probe; 594 int i = 0; 595 596 damon_for_each_probe(probe, ctx) { 597 if (damon_va_filter_pass(folio, probe, pte, pmd, mm, 598 r->sampling_addr)) 599 r->probe_hits[i]++; 600 i++; 601 } 602 } 603 604 static int damon_va_probe_pmd_entry(pmd_t *pmd, unsigned long addr, 605 unsigned long next, struct mm_walk *walk) 606 { 607 pte_t *pte; 608 pte_t ptent; 609 spinlock_t *ptl; 610 struct folio *folio; 611 struct damon_va_probe_walk_private *priv = walk->private; 612 613 #ifdef CONFIG_TRANSPARENT_HUGEPAGE 614 ptl = pmd_trans_huge_lock(pmd, walk->vma); 615 if (ptl) { 616 pmd_t pmde = pmdp_get(pmd); 617 618 if (!pmd_present(pmde)) 619 goto huge_out; 620 folio = vm_normal_folio_pmd(walk->vma, addr, pmde); 621 if (!folio) 622 goto huge_out; 623 damon_va_probe_folio(priv->ctx, priv->r, folio, NULL, &pmde, 624 walk->vma->vm_mm); 625 626 huge_out: 627 spin_unlock(ptl); 628 return 0; 629 } 630 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ 631 632 pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl); 633 if (!pte) 634 return 0; 635 ptent = ptep_get(pte); 636 if (!pte_present(ptent)) 637 goto out; 638 folio = vm_normal_folio(walk->vma, addr, ptent); 639 if (!folio) 640 goto out; 641 damon_va_probe_folio(priv->ctx, priv->r, folio, &ptent, NULL, 642 walk->vma->vm_mm); 643 644 out: 645 pte_unmap_unlock(pte, ptl); 646 return 0; 647 } 648 649 #ifdef CONFIG_HUGETLB_PAGE 650 static int damon_va_probe_hugetlb_entry(pte_t *pte, unsigned long hmask, 651 unsigned long addr, unsigned long end, struct mm_walk *walk) 652 { 653 struct damon_va_probe_walk_private *priv = walk->private; 654 struct hstate *h = hstate_vma(walk->vma); 655 struct folio *folio; 656 spinlock_t *ptl; 657 pte_t entry; 658 659 ptl = huge_pte_lock(h, walk->mm, pte); 660 entry = huge_ptep_get(walk->mm, addr, pte); 661 if (!pte_present(entry)) 662 goto out; 663 664 folio = damon_get_monitor_folio(pte_pfn(entry)); 665 if (!folio) 666 goto out; 667 damon_va_probe_folio(priv->ctx, priv->r, folio, &entry, NULL, 668 walk->vma->vm_mm); 669 folio_put(folio); 670 671 out: 672 spin_unlock(ptl); 673 return 0; 674 } 675 #else 676 #define damon_va_probe_hugetlb_entry NULL 677 #endif /* CONFIG_HUGETLB_PAGE */ 678 679 static void __damon_va_apply_probes(struct damon_ctx *ctx, 680 struct mm_struct *mm, struct damon_region *r) 681 { 682 struct damon_va_probe_walk_private arg = { 683 .ctx = ctx, 684 .r = r, 685 }; 686 struct mm_walk_ops damon_probe_walk_ops = { 687 .pmd_entry = damon_va_probe_pmd_entry, 688 .hugetlb_entry = damon_va_probe_hugetlb_entry, 689 }; 690 unsigned long addr = r->sampling_addr; 691 692 if (!mm) 693 return; 694 695 damon_va_walk_page_range(mm, addr, addr + 1, &damon_probe_walk_ops, 696 &arg); 697 } 698 699 static unsigned int damon_va_apply_probes(struct damon_ctx *ctx, 700 bool set_samples, bool return_max_wsum) 701 { 702 struct damon_target *t; 703 struct mm_struct *mm; 704 struct damon_region *r; 705 unsigned int max_wsum = 0; 706 707 damon_for_each_target(t, ctx) { 708 mm = damon_get_mm(t); 709 damon_for_each_region(r, t) { 710 if (set_samples) 711 r->sampling_addr = damon_rand(ctx, r->ar.start, 712 r->ar.end); 713 __damon_va_apply_probes(ctx, mm, r); 714 if (return_max_wsum) 715 max_wsum = max(damon_probe_hits_wsum(r, false, 716 false, ctx), max_wsum); 717 } 718 if (mm) 719 mmput(mm); 720 } 721 722 return max_wsum; 723 } 724 725 static bool damos_va_filter_young_match(struct damos_filter *filter, 726 struct folio *folio, struct vm_area_struct *vma, 727 unsigned long addr, pte_t *ptep, pmd_t *pmdp) 728 { 729 bool young = false; 730 731 if (ptep) 732 young = pte_young(ptep_get(ptep)); 733 else if (pmdp) 734 young = pmd_young(pmdp_get(pmdp)); 735 736 young = young || !folio_test_idle(folio) || 737 mmu_notifier_test_young(vma->vm_mm, addr); 738 739 if (young && ptep) 740 damon_ptep_mkold(ptep, vma, addr); 741 else if (young && pmdp) 742 damon_pmdp_mkold(pmdp, vma, addr); 743 744 return young == filter->matching; 745 } 746 747 static bool damos_va_filter_out(struct damos *scheme, struct folio *folio, 748 struct vm_area_struct *vma, unsigned long addr, 749 pte_t *ptep, pmd_t *pmdp) 750 { 751 struct damos_filter *filter; 752 bool matched; 753 754 if (scheme->core_filters_allowed) 755 return false; 756 757 damos_for_each_ops_filter(filter, scheme) { 758 /* 759 * damos_folio_filter_match checks the young filter by doing an 760 * rmap on the folio to find its page table. However, being the 761 * vaddr scheme, we have direct access to the page tables, so 762 * use that instead. 763 */ 764 if (filter->type == DAMOS_FILTER_TYPE_YOUNG) 765 matched = damos_va_filter_young_match(filter, folio, 766 vma, addr, ptep, pmdp); 767 else 768 matched = damos_folio_filter_match(filter, folio); 769 770 if (matched) 771 return !filter->allow; 772 } 773 return scheme->ops_filters_default_reject; 774 } 775 776 struct damos_va_migrate_private { 777 struct list_head *migration_lists; 778 struct damos *scheme; 779 }; 780 781 /* 782 * Place the given folio in the migration_list corresponding to where the folio 783 * should be migrated. 784 * 785 * The algorithm used here is similar to weighted_interleave_nid() 786 */ 787 static void damos_va_migrate_dests_add(struct folio *folio, 788 struct vm_area_struct *vma, unsigned long addr, 789 struct damos_migrate_dests *dests, 790 struct list_head *migration_lists) 791 { 792 pgoff_t ilx; 793 int order; 794 unsigned int target; 795 unsigned int weight_total = 0; 796 int i; 797 798 /* 799 * If dests is empty, there is only one migration list corresponding 800 * to s->target_nid. 801 */ 802 if (!dests->nr_dests) { 803 i = 0; 804 goto isolate; 805 } 806 807 order = folio_order(folio); 808 ilx = vma_start_pgoff(vma) >> order; 809 ilx += linear_page_delta(vma, addr) >> order; 810 811 for (i = 0; i < dests->nr_dests; i++) 812 weight_total += dests->weight_arr[i]; 813 814 /* If the total weights are somehow 0, don't migrate at all */ 815 if (!weight_total) 816 return; 817 818 target = ilx % weight_total; 819 for (i = 0; i < dests->nr_dests; i++) { 820 if (target < dests->weight_arr[i]) 821 break; 822 target -= dests->weight_arr[i]; 823 } 824 825 /* If the folio is already in the right node, don't do anything */ 826 if (folio_nid(folio) == dests->node_id_arr[i]) 827 return; 828 829 isolate: 830 if (!folio_isolate_lru(folio)) 831 return; 832 node_stat_add_folio(folio, NR_ISOLATED_ANON + 833 folio_is_file_lru(folio)); 834 list_add(&folio->lru, &migration_lists[i]); 835 } 836 837 static int damos_va_migrate_pmd_entry(pmd_t *pmd, unsigned long addr, 838 unsigned long next, struct mm_walk *walk) 839 { 840 struct damos_va_migrate_private *priv = walk->private; 841 struct list_head *migration_lists = priv->migration_lists; 842 struct damos *s = priv->scheme; 843 struct damos_migrate_dests *dests = &s->migrate_dests; 844 struct folio *folio; 845 spinlock_t *ptl; 846 pte_t *start_pte, *pte, ptent; 847 int nr; 848 849 #ifdef CONFIG_TRANSPARENT_HUGEPAGE 850 ptl = pmd_trans_huge_lock(pmd, walk->vma); 851 if (ptl) { 852 pmd_t pmde = pmdp_get(pmd); 853 854 if (!pmd_present(pmde)) 855 goto huge_out; 856 folio = vm_normal_folio_pmd(walk->vma, addr, pmde); 857 if (!folio) 858 goto huge_out; 859 if (damos_va_filter_out(s, folio, walk->vma, addr, NULL, pmd)) 860 goto huge_out; 861 damos_va_migrate_dests_add(folio, walk->vma, addr, dests, 862 migration_lists); 863 huge_out: 864 spin_unlock(ptl); 865 return 0; 866 } 867 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ 868 869 start_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl); 870 if (!pte) 871 return 0; 872 873 for (; addr < next; pte += nr, addr += nr * PAGE_SIZE) { 874 unsigned long page_idx; 875 876 nr = 1; 877 ptent = ptep_get(pte); 878 879 if (pte_none(ptent) || !pte_present(ptent)) 880 continue; 881 folio = vm_normal_folio(walk->vma, addr, ptent); 882 if (!folio) 883 continue; 884 if (damos_va_filter_out(s, folio, walk->vma, addr, pte, NULL)) 885 continue; 886 damos_va_migrate_dests_add(folio, walk->vma, addr, dests, 887 migration_lists); 888 page_idx = folio_page_idx(folio, pte_page(ptent)); 889 nr = folio_nr_pages(folio) - page_idx; 890 } 891 pte_unmap_unlock(start_pte, ptl); 892 return 0; 893 } 894 895 /* 896 * Functions for the target validity check and cleanup 897 */ 898 899 static bool damon_va_target_valid(struct damon_target *t) 900 { 901 struct task_struct *task; 902 903 task = damon_get_task_struct(t); 904 if (task) { 905 put_task_struct(task); 906 return true; 907 } 908 909 return false; 910 } 911 912 static void damon_va_cleanup_target(struct damon_target *t) 913 { 914 put_pid(t->pid); 915 } 916 917 #ifndef CONFIG_ADVISE_SYSCALLS 918 static unsigned long damos_madvise(struct damon_target *target, 919 struct damon_region *r, int behavior) 920 { 921 return 0; 922 } 923 #else 924 static unsigned long damos_madvise(struct damon_target *target, 925 struct damon_region *r, int behavior) 926 { 927 struct mm_struct *mm; 928 unsigned long start = PAGE_ALIGN(r->ar.start); 929 unsigned long len = PAGE_ALIGN(damon_sz_region(r)); 930 unsigned long applied; 931 932 mm = damon_get_mm(target); 933 if (!mm) 934 return 0; 935 936 applied = do_madvise(mm, start, len, behavior) ? 0 : len; 937 mmput(mm); 938 939 return applied; 940 } 941 #endif /* CONFIG_ADVISE_SYSCALLS */ 942 943 static unsigned long damos_va_migrate(struct damon_target *target, 944 struct damon_region *r, struct damos *s, 945 unsigned long *sz_filter_passed) 946 { 947 LIST_HEAD(folio_list); 948 struct damos_va_migrate_private priv; 949 struct mm_struct *mm; 950 int nr_dests; 951 int nid; 952 bool use_target_nid; 953 unsigned long applied = 0; 954 struct damos_migrate_dests *dests = &s->migrate_dests; 955 struct mm_walk_ops walk_ops = { 956 .pmd_entry = damos_va_migrate_pmd_entry, 957 .pte_entry = NULL, 958 }; 959 960 use_target_nid = dests->nr_dests == 0; 961 nr_dests = use_target_nid ? 1 : dests->nr_dests; 962 priv.scheme = s; 963 priv.migration_lists = kmalloc_objs(*priv.migration_lists, nr_dests); 964 if (!priv.migration_lists) 965 return 0; 966 967 for (int i = 0; i < nr_dests; i++) 968 INIT_LIST_HEAD(&priv.migration_lists[i]); 969 970 971 mm = damon_get_mm(target); 972 if (!mm) 973 goto free_lists; 974 975 damon_va_walk_page_range(mm, r->ar.start, r->ar.end, &walk_ops, &priv); 976 mmput(mm); 977 978 for (int i = 0; i < nr_dests; i++) { 979 nid = use_target_nid ? s->target_nid : dests->node_id_arr[i]; 980 applied += damon_migrate_pages(&priv.migration_lists[i], nid); 981 cond_resched(); 982 } 983 984 free_lists: 985 kfree(priv.migration_lists); 986 return applied * PAGE_SIZE; 987 } 988 989 struct damos_va_stat_private { 990 struct damos *scheme; 991 unsigned long *sz_filter_passed; 992 }; 993 994 static inline bool damos_va_invalid_folio(struct folio *folio, 995 struct damos *s) 996 { 997 return !folio || folio == s->last_applied; 998 } 999 1000 static int damos_va_stat_pmd_entry(pmd_t *pmd, unsigned long addr, 1001 unsigned long next, struct mm_walk *walk) 1002 { 1003 struct damos_va_stat_private *priv = walk->private; 1004 struct damos *s = priv->scheme; 1005 unsigned long *sz_filter_passed = priv->sz_filter_passed; 1006 struct vm_area_struct *vma = walk->vma; 1007 struct folio *folio; 1008 spinlock_t *ptl; 1009 pte_t *start_pte, *pte, ptent; 1010 int nr; 1011 1012 #ifdef CONFIG_TRANSPARENT_HUGEPAGE 1013 ptl = pmd_trans_huge_lock(pmd, vma); 1014 if (ptl) { 1015 pmd_t pmde = pmdp_get(pmd); 1016 1017 if (!pmd_present(pmde)) 1018 goto huge_unlock; 1019 1020 folio = vm_normal_folio_pmd(vma, addr, pmde); 1021 1022 if (damos_va_invalid_folio(folio, s)) 1023 goto huge_unlock; 1024 1025 if (!damos_va_filter_out(s, folio, vma, addr, NULL, pmd)) 1026 *sz_filter_passed += folio_size(folio); 1027 s->last_applied = folio; 1028 1029 huge_unlock: 1030 spin_unlock(ptl); 1031 return 0; 1032 } 1033 #endif 1034 start_pte = pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); 1035 if (!start_pte) 1036 return 0; 1037 1038 for (; addr < next; pte += nr, addr += nr * PAGE_SIZE) { 1039 unsigned long page_idx; 1040 1041 nr = 1; 1042 ptent = ptep_get(pte); 1043 1044 if (pte_none(ptent) || !pte_present(ptent)) 1045 continue; 1046 1047 folio = vm_normal_folio(vma, addr, ptent); 1048 1049 if (damos_va_invalid_folio(folio, s)) 1050 continue; 1051 1052 if (!damos_va_filter_out(s, folio, vma, addr, pte, NULL)) 1053 *sz_filter_passed += folio_size(folio); 1054 page_idx = folio_page_idx(folio, pte_page(ptent)); 1055 nr = folio_nr_pages(folio) - page_idx; 1056 s->last_applied = folio; 1057 } 1058 pte_unmap_unlock(start_pte, ptl); 1059 return 0; 1060 } 1061 1062 static unsigned long damos_va_stat(struct damon_target *target, 1063 struct damon_region *r, struct damos *s, 1064 unsigned long *sz_filter_passed) 1065 { 1066 struct damos_va_stat_private priv; 1067 struct mm_struct *mm; 1068 struct mm_walk_ops walk_ops = { 1069 .pmd_entry = damos_va_stat_pmd_entry, 1070 }; 1071 1072 priv.scheme = s; 1073 priv.sz_filter_passed = sz_filter_passed; 1074 1075 if (!damos_ops_has_filter(s)) 1076 return 0; 1077 1078 mm = damon_get_mm(target); 1079 if (!mm) 1080 return 0; 1081 1082 damon_va_walk_page_range(mm, r->ar.start, r->ar.end, &walk_ops, &priv); 1083 mmput(mm); 1084 return 0; 1085 } 1086 1087 static unsigned long damon_va_apply_scheme(struct damon_ctx *ctx, 1088 struct damon_target *t, struct damon_region *r, 1089 struct damos *scheme, unsigned long *sz_filter_passed) 1090 { 1091 int madv_action; 1092 1093 switch (scheme->action) { 1094 case DAMOS_WILLNEED: 1095 madv_action = MADV_WILLNEED; 1096 break; 1097 case DAMOS_COLD: 1098 madv_action = MADV_COLD; 1099 break; 1100 case DAMOS_PAGEOUT: 1101 madv_action = MADV_PAGEOUT; 1102 break; 1103 case DAMOS_HUGEPAGE: 1104 madv_action = MADV_HUGEPAGE; 1105 break; 1106 case DAMOS_NOHUGEPAGE: 1107 madv_action = MADV_NOHUGEPAGE; 1108 break; 1109 case DAMOS_COLLAPSE: 1110 madv_action = MADV_COLLAPSE; 1111 break; 1112 case DAMOS_MIGRATE_HOT: 1113 case DAMOS_MIGRATE_COLD: 1114 return damos_va_migrate(t, r, scheme, sz_filter_passed); 1115 case DAMOS_STAT: 1116 return damos_va_stat(t, r, scheme, sz_filter_passed); 1117 default: 1118 /* 1119 * DAMOS actions that are not yet supported by 'vaddr'. 1120 */ 1121 return 0; 1122 } 1123 1124 return damos_madvise(t, r, madv_action); 1125 } 1126 1127 static int damon_va_scheme_score(struct damon_ctx *context, 1128 struct damon_region *r, struct damos *scheme) 1129 { 1130 1131 switch (scheme->action) { 1132 case DAMOS_PAGEOUT: 1133 return damon_cold_score(context, r, scheme); 1134 case DAMOS_MIGRATE_HOT: 1135 return damon_hot_score(context, r, scheme); 1136 case DAMOS_MIGRATE_COLD: 1137 return damon_cold_score(context, r, scheme); 1138 default: 1139 break; 1140 } 1141 1142 return DAMOS_MAX_SCORE; 1143 } 1144 1145 static int __init damon_va_initcall(void) 1146 { 1147 struct damon_operations ops = { 1148 .id = DAMON_OPS_VADDR, 1149 .init = damon_va_init, 1150 .update = damon_va_update, 1151 .prepare_access_checks = damon_va_prepare_access_checks, 1152 .check_accesses = damon_va_check_accesses, 1153 .prep_probes = damon_va_prep_probes, 1154 .apply_probes = damon_va_apply_probes, 1155 .target_valid = damon_va_target_valid, 1156 .cleanup_target = damon_va_cleanup_target, 1157 .apply_scheme = damon_va_apply_scheme, 1158 .get_scheme_score = damon_va_scheme_score, 1159 }; 1160 /* ops for fixed virtual address ranges */ 1161 struct damon_operations ops_fvaddr = ops; 1162 int err; 1163 1164 /* Don't set the monitoring target regions for the entire mapping */ 1165 ops_fvaddr.id = DAMON_OPS_FVADDR; 1166 ops_fvaddr.init = NULL; 1167 ops_fvaddr.update = NULL; 1168 1169 err = damon_register_ops(&ops); 1170 if (err) 1171 return err; 1172 return damon_register_ops(&ops_fvaddr); 1173 } 1174 1175 subsys_initcall(damon_va_initcall); 1176 1177 #include "tests/vaddr-kunit.h" 1178