Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm/damon/vaddr: support stat-purpose DAMOS filters

This patch extends DAMOS_STAT handling of the DAMON operations sets for
virtual address spaces for ops-level DAMOS filters. It leverages the
walk_page_range to walk the page table and gets the folio from page table.
The last folio scanned is stored in damos->last_applied to prevent double
counting.

Link: https://lkml.kernel.org/r/264a4b5ea202fd73c01b349c9694d8bf9978c441.1754135312.git.pyyjason@gmail.com
Signed-off-by: Yueyang Pan <pyyjason@gmail.com>
Reviewed-by: SeongJae Park <sj@kernel.org>
Cc: Usama Arif <usamaarif642@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Yueyang Pan and committed by
Andrew Morton
63f39737 408b299a

+102 -1
+102 -1
mm/damon/vaddr.c
··· 890 890 return applied * PAGE_SIZE; 891 891 } 892 892 893 + struct damos_va_stat_private { 894 + struct damos *scheme; 895 + unsigned long *sz_filter_passed; 896 + }; 897 + 898 + static inline bool damos_va_invalid_folio(struct folio *folio, 899 + struct damos *s) 900 + { 901 + return !folio || folio == s->last_applied; 902 + } 903 + 904 + static int damos_va_stat_pmd_entry(pmd_t *pmd, unsigned long addr, 905 + unsigned long next, struct mm_walk *walk) 906 + { 907 + struct damos_va_stat_private *priv = walk->private; 908 + struct damos *s = priv->scheme; 909 + unsigned long *sz_filter_passed = priv->sz_filter_passed; 910 + struct vm_area_struct *vma = walk->vma; 911 + struct folio *folio; 912 + spinlock_t *ptl; 913 + pte_t *start_pte, *pte, ptent; 914 + int nr; 915 + 916 + #ifdef CONFIG_TRANSPARENT_HUGEPAGE 917 + if (pmd_trans_huge(*pmd)) { 918 + pmd_t pmde; 919 + 920 + ptl = pmd_trans_huge_lock(pmd, vma); 921 + if (!ptl) 922 + return 0; 923 + pmde = pmdp_get(pmd); 924 + if (!pmd_present(pmde)) 925 + goto huge_unlock; 926 + 927 + folio = vm_normal_folio_pmd(vma, addr, pmde); 928 + 929 + if (damos_va_invalid_folio(folio, s)) 930 + goto huge_unlock; 931 + 932 + if (!damos_va_filter_out(s, folio, vma, addr, NULL, pmd)) 933 + *sz_filter_passed += folio_size(folio); 934 + s->last_applied = folio; 935 + 936 + huge_unlock: 937 + spin_unlock(ptl); 938 + return 0; 939 + } 940 + #endif 941 + start_pte = pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); 942 + if (!start_pte) 943 + return 0; 944 + 945 + for (; addr < next; pte += nr, addr += nr * PAGE_SIZE) { 946 + nr = 1; 947 + ptent = ptep_get(pte); 948 + 949 + if (pte_none(ptent) || !pte_present(ptent)) 950 + continue; 951 + 952 + folio = vm_normal_folio(vma, addr, ptent); 953 + 954 + if (damos_va_invalid_folio(folio, s)) 955 + continue; 956 + 957 + if (!damos_va_filter_out(s, folio, vma, addr, pte, NULL)) 958 + *sz_filter_passed += folio_size(folio); 959 + nr = folio_nr_pages(folio); 960 + s->last_applied = folio; 961 + } 962 + pte_unmap_unlock(start_pte, ptl); 963 + return 0; 964 + } 965 + 966 + static unsigned long damos_va_stat(struct damon_target *target, 967 + struct damon_region *r, struct damos *s, 968 + unsigned long *sz_filter_passed) 969 + { 970 + struct damos_va_stat_private priv; 971 + struct mm_struct *mm; 972 + struct mm_walk_ops walk_ops = { 973 + .pmd_entry = damos_va_stat_pmd_entry, 974 + .walk_lock = PGWALK_RDLOCK, 975 + }; 976 + 977 + priv.scheme = s; 978 + priv.sz_filter_passed = sz_filter_passed; 979 + 980 + if (!damos_ops_has_filter(s)) 981 + return 0; 982 + 983 + mm = damon_get_mm(target); 984 + if (!mm) 985 + return 0; 986 + 987 + mmap_read_lock(mm); 988 + walk_page_range(mm, r->ar.start, r->ar.end, &walk_ops, &priv); 989 + mmap_read_unlock(mm); 990 + mmput(mm); 991 + return 0; 992 + } 993 + 893 994 static unsigned long damon_va_apply_scheme(struct damon_ctx *ctx, 894 995 struct damon_target *t, struct damon_region *r, 895 996 struct damos *scheme, unsigned long *sz_filter_passed) ··· 1017 916 case DAMOS_MIGRATE_COLD: 1018 917 return damos_va_migrate(t, r, scheme, sz_filter_passed); 1019 918 case DAMOS_STAT: 1020 - return 0; 919 + return damos_va_stat(t, r, scheme, sz_filter_passed); 1021 920 default: 1022 921 /* 1023 922 * DAMOS actions that are not yet supported by 'vaddr'.