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/paddr: support addr_unit for DAMOS_PAGEOUT

Add support of addr_unit for DAMOS_PAGEOUT action handling from the DAMOS
operation implementation for the physical address space.

Link: https://lkml.kernel.org/r/20250828171242.59810-4-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Signed-off-by: Quanmin Yan <yanquanmin1@huawei.com>
Reviewed-by: SeongJae Park <sj@kernel.org>
Cc: David Hildenbrand <david@redhat.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: ze zuo <zuoze1@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

SeongJae Park and committed by
Andrew Morton
85246435 d8096848

+23 -7
+23 -7
mm/damon/paddr.c
··· 24 24 return (phys_addr_t)addr * addr_unit; 25 25 } 26 26 27 + static unsigned long damon_pa_core_addr( 28 + phys_addr_t pa, unsigned long addr_unit) 29 + { 30 + /* 31 + * Use div_u64() for avoiding linking errors related with __udivdi3, 32 + * __aeabi_uldivmod, or similar problems. This should also improve the 33 + * performance optimization (read div_u64() comment for the detail). 34 + */ 35 + if (sizeof(pa) == 8 && sizeof(addr_unit) == 4) 36 + return div_u64(pa, addr_unit); 37 + return pa / addr_unit; 38 + } 39 + 27 40 static void damon_pa_mkold(phys_addr_t paddr) 28 41 { 29 42 struct folio *folio = damon_get_folio(PHYS_PFN(paddr)); ··· 148 135 return false; 149 136 } 150 137 151 - static unsigned long damon_pa_pageout(struct damon_region *r, struct damos *s, 138 + static unsigned long damon_pa_pageout(struct damon_region *r, 139 + unsigned long addr_unit, struct damos *s, 152 140 unsigned long *sz_filter_passed) 153 141 { 154 - unsigned long addr, applied; 142 + phys_addr_t addr, applied; 155 143 LIST_HEAD(folio_list); 156 144 bool install_young_filter = true; 157 145 struct damos_filter *filter; ··· 173 159 damos_add_filter(s, filter); 174 160 } 175 161 176 - addr = r->ar.start; 177 - while (addr < r->ar.end) { 162 + addr = damon_pa_phys_addr(r->ar.start, addr_unit); 163 + while (addr < damon_pa_phys_addr(r->ar.end, addr_unit)) { 178 164 folio = damon_get_folio(PHYS_PFN(addr)); 179 165 if (damon_pa_invalid_damos_folio(folio, s)) { 180 166 addr += PAGE_SIZE; ··· 184 170 if (damos_pa_filter_out(s, folio)) 185 171 goto put_folio; 186 172 else 187 - *sz_filter_passed += folio_size(folio); 173 + *sz_filter_passed += folio_size(folio) / addr_unit; 188 174 189 175 folio_clear_referenced(folio); 190 176 folio_test_clear_young(folio); ··· 203 189 applied = reclaim_pages(&folio_list); 204 190 cond_resched(); 205 191 s->last_applied = folio; 206 - return applied * PAGE_SIZE; 192 + return damon_pa_core_addr(applied * PAGE_SIZE, addr_unit); 207 193 } 208 194 209 195 static inline unsigned long damon_pa_mark_accessed_or_deactivate( ··· 316 302 struct damon_target *t, struct damon_region *r, 317 303 struct damos *scheme, unsigned long *sz_filter_passed) 318 304 { 305 + unsigned long aunit = ctx->addr_unit; 306 + 319 307 switch (scheme->action) { 320 308 case DAMOS_PAGEOUT: 321 - return damon_pa_pageout(r, scheme, sz_filter_passed); 309 + return damon_pa_pageout(r, aunit, scheme, sz_filter_passed); 322 310 case DAMOS_LRU_PRIO: 323 311 return damon_pa_mark_accessed(r, scheme, sz_filter_passed); 324 312 case DAMOS_LRU_DEPRIO: