mm/damon/paddr: support addr_unit for access monitoring

Add support of addr_unit paramer for access monitoing operations of paddr.

Link: https://lkml.kernel.org/r/20250828171242.59810-3-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>
This commit is contained in:
SeongJae Park 2025-08-28 10:12:33 -07:00 committed by Andrew Morton
parent 09a616cbb3
commit d8096848e7

View File

@ -18,7 +18,13 @@
#include "../internal.h"
#include "ops-common.h"
static void damon_pa_mkold(unsigned long paddr)
static phys_addr_t damon_pa_phys_addr(
unsigned long addr, unsigned long addr_unit)
{
return (phys_addr_t)addr * addr_unit;
}
static void damon_pa_mkold(phys_addr_t paddr)
{
struct folio *folio = damon_get_folio(PHYS_PFN(paddr));
@ -29,11 +35,12 @@ static void damon_pa_mkold(unsigned long paddr)
folio_put(folio);
}
static void __damon_pa_prepare_access_check(struct damon_region *r)
static void __damon_pa_prepare_access_check(struct damon_region *r,
unsigned long addr_unit)
{
r->sampling_addr = damon_rand(r->ar.start, r->ar.end);
damon_pa_mkold(r->sampling_addr);
damon_pa_mkold(damon_pa_phys_addr(r->sampling_addr, addr_unit));
}
static void damon_pa_prepare_access_checks(struct damon_ctx *ctx)
@ -43,11 +50,11 @@ static void damon_pa_prepare_access_checks(struct damon_ctx *ctx)
damon_for_each_target(t, ctx) {
damon_for_each_region(r, t)
__damon_pa_prepare_access_check(r);
__damon_pa_prepare_access_check(r, ctx->addr_unit);
}
}
static bool damon_pa_young(unsigned long paddr, unsigned long *folio_sz)
static bool damon_pa_young(phys_addr_t paddr, unsigned long *folio_sz)
{
struct folio *folio = damon_get_folio(PHYS_PFN(paddr));
bool accessed;
@ -62,23 +69,25 @@ static bool damon_pa_young(unsigned long paddr, unsigned long *folio_sz)
}
static void __damon_pa_check_access(struct damon_region *r,
struct damon_attrs *attrs)
struct damon_attrs *attrs, unsigned long addr_unit)
{
static unsigned long last_addr;
static phys_addr_t last_addr;
static unsigned long last_folio_sz = PAGE_SIZE;
static bool last_accessed;
phys_addr_t sampling_addr = damon_pa_phys_addr(
r->sampling_addr, addr_unit);
/* If the region is in the last checked page, reuse the result */
if (ALIGN_DOWN(last_addr, last_folio_sz) ==
ALIGN_DOWN(r->sampling_addr, last_folio_sz)) {
ALIGN_DOWN(sampling_addr, last_folio_sz)) {
damon_update_region_access_rate(r, last_accessed, attrs);
return;
}
last_accessed = damon_pa_young(r->sampling_addr, &last_folio_sz);
last_accessed = damon_pa_young(sampling_addr, &last_folio_sz);
damon_update_region_access_rate(r, last_accessed, attrs);
last_addr = r->sampling_addr;
last_addr = sampling_addr;
}
static unsigned int damon_pa_check_accesses(struct damon_ctx *ctx)
@ -89,7 +98,8 @@ static unsigned int damon_pa_check_accesses(struct damon_ctx *ctx)
damon_for_each_target(t, ctx) {
damon_for_each_region(r, t) {
__damon_pa_check_access(r, &ctx->attrs);
__damon_pa_check_access(
r, &ctx->attrs, ctx->addr_unit);
max_nr_accesses = max(r->nr_accesses, max_nr_accesses);
}
}