From: SeongJae Park <sjpark@xxxxxxxxx> This commit allows DAMON users to configure their own monitoring target regions initializer / updater. Using this, users can confine the monitoring address spaces as they want. For example, users can track only stack, heap, or shared memory area, as they want. Signed-off-by: SeongJae Park <sjpark@xxxxxxxxx> --- include/linux/damon.h | 2 ++ mm/damon.c | 20 +++++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/include/linux/damon.h b/include/linux/damon.h index d72dd524924f..a051b5d966ed 100644 --- a/include/linux/damon.h +++ b/include/linux/damon.h @@ -93,6 +93,8 @@ struct damon_ctx { struct list_head schemes_list; /* 'damos' objects */ /* callbacks */ + void (*init_target_regions)(struct damon_ctx *context); + void (*update_target_regions)(struct damon_ctx *context); void (*sample_cb)(struct damon_ctx *context); void (*aggregate_cb)(struct damon_ctx *context); }; diff --git a/mm/damon.c b/mm/damon.c index 80fa3cab7720..da0e7efdf1e1 100644 --- a/mm/damon.c +++ b/mm/damon.c @@ -57,6 +57,9 @@ /* Get a random number in [l, r) */ #define damon_rand(ctx, l, r) (l + prandom_u32_state(&ctx->rndseed) % (r - l)) +static void kdamond_init_vm_regions(struct damon_ctx *ctx); +static void kdamond_update_vm_regions(struct damon_ctx *ctx); + /* A monitoring context for debugfs interface users. */ static struct damon_ctx damon_user_ctx = { .sample_interval = 5 * 1000, @@ -64,6 +67,9 @@ static struct damon_ctx damon_user_ctx = { .regions_update_interval = 1000 * 1000, .min_nr_regions = 10, .max_nr_regions = 1000, + + .init_target_regions = kdamond_init_vm_regions, + .update_target_regions = kdamond_update_vm_regions, }; /* @@ -327,7 +333,7 @@ static void swap_ranges(struct damon_addr_range *r1, * * This function receives an address space and finds three regions in it which * separated by the two biggest unmapped regions in the space. Please refer to - * below comments of 'damon_init_regions_of()' function to know why this is + * below comments of 'damon_init_vm_regions_of()' function to know why this is * necessary. * * Returns 0 if success, or negative error code otherwise. @@ -439,7 +445,7 @@ static int damon_three_regions_of(struct damon_task *t, * <BIG UNMAPPED REGION 2> * <stack> */ -static void damon_init_regions_of(struct damon_ctx *c, struct damon_task *t) +static void damon_init_vm_regions_of(struct damon_ctx *c, struct damon_task *t) { struct damon_region *r; struct damon_addr_range regions[3]; @@ -463,12 +469,12 @@ static void damon_init_regions_of(struct damon_ctx *c, struct damon_task *t) } /* Initialize '->regions_list' of every task */ -static void kdamond_init_regions(struct damon_ctx *ctx) +static void kdamond_init_vm_regions(struct damon_ctx *ctx) { struct damon_task *t; damon_for_each_task(ctx, t) - damon_init_regions_of(ctx, t); + damon_init_vm_regions_of(ctx, t); } static void damon_mkold(struct mm_struct *mm, unsigned long addr) @@ -1074,7 +1080,7 @@ static void damon_apply_three_regions(struct damon_ctx *ctx, /* * Update regions for current memory mappings */ -static void kdamond_update_regions(struct damon_ctx *ctx) +static void kdamond_update_vm_regions(struct damon_ctx *ctx) { struct damon_addr_range three_regions[3]; struct damon_task *t; @@ -1126,7 +1132,7 @@ static int kdamond_fn(void *data) unsigned int max_nr_accesses = 0; pr_info("kdamond (%d) starts\n", ctx->kdamond->pid); - kdamond_init_regions(ctx); + ctx->init_target_regions(ctx); while (!kdamond_need_stop(ctx)) { kdamond_prepare_access_checks(ctx); if (ctx->sample_cb) @@ -1147,7 +1153,7 @@ static int kdamond_fn(void *data) } if (kdamond_need_update_regions(ctx)) - kdamond_update_regions(ctx); + ctx->update_target_regions(ctx); } damon_flush_rbuffer(ctx); damon_for_each_task(ctx, t) { -- 2.17.1