forked from mirrors/linux
		
	mm/damon/core: use a dedicated struct for monitoring attributes
DAMON monitoring attributes are directly defined as fields of 'struct damon_ctx'. This makes 'struct damon_ctx' a little long and complicated. This commit defines and uses a struct, 'struct damon_attrs', which is dedicated for only the monitoring attributes to make the purpose of the five values clearer and simplify 'struct damon_ctx'. Link: https://lkml.kernel.org/r/20220913174449.50645-6-sj@kernel.org Signed-off-by: SeongJae Park <sj@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									70e0c1d1bf
								
							
						
					
					
						commit
						cbeaa77b04
					
				
					 5 changed files with 44 additions and 34 deletions
				
			
		| 
						 | 
					@ -389,13 +389,15 @@ struct damon_callback {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * struct damon_ctx - Represents a context for each monitoring.  This is the
 | 
					 * struct damon_attrs - Monitoring attributes for accuracy/overhead control.
 | 
				
			||||||
 * main interface that allows users to set the attributes and get the results
 | 
					 | 
				
			||||||
 * of the monitoring.
 | 
					 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @sample_interval:		The time between access samplings.
 | 
					 * @sample_interval:		The time between access samplings.
 | 
				
			||||||
 * @aggr_interval:		The time between monitor results aggregations.
 | 
					 * @aggr_interval:		The time between monitor results aggregations.
 | 
				
			||||||
 * @ops_update_interval:	The time between monitoring operations updates.
 | 
					 * @ops_update_interval:	The time between monitoring operations updates.
 | 
				
			||||||
 | 
					 * @min_nr_regions:		The minimum number of adaptive monitoring
 | 
				
			||||||
 | 
					 *				regions.
 | 
				
			||||||
 | 
					 * @max_nr_regions:		The maximum number of adaptive monitoring
 | 
				
			||||||
 | 
					 *				regions.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * For each @sample_interval, DAMON checks whether each region is accessed or
 | 
					 * For each @sample_interval, DAMON checks whether each region is accessed or
 | 
				
			||||||
 * not.  It aggregates and keeps the access information (number of accesses to
 | 
					 * not.  It aggregates and keeps the access information (number of accesses to
 | 
				
			||||||
| 
						 | 
					@ -405,7 +407,21 @@ struct damon_callback {
 | 
				
			||||||
 * @ops_update_interval.  All time intervals are in micro-seconds.
 | 
					 * @ops_update_interval.  All time intervals are in micro-seconds.
 | 
				
			||||||
 * Please refer to &struct damon_operations and &struct damon_callback for more
 | 
					 * Please refer to &struct damon_operations and &struct damon_callback for more
 | 
				
			||||||
 * detail.
 | 
					 * detail.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct damon_attrs {
 | 
				
			||||||
 | 
						unsigned long sample_interval;
 | 
				
			||||||
 | 
						unsigned long aggr_interval;
 | 
				
			||||||
 | 
						unsigned long ops_update_interval;
 | 
				
			||||||
 | 
						unsigned long min_nr_regions;
 | 
				
			||||||
 | 
						unsigned long max_nr_regions;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * struct damon_ctx - Represents a context for each monitoring.  This is the
 | 
				
			||||||
 | 
					 * main interface that allows users to set the attributes and get the results
 | 
				
			||||||
 | 
					 * of the monitoring.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
					 * @attrs:		Monitoring attributes for accuracy/overhead control.
 | 
				
			||||||
 * @kdamond:		Kernel thread who does the monitoring.
 | 
					 * @kdamond:		Kernel thread who does the monitoring.
 | 
				
			||||||
 * @kdamond_lock:	Mutex for the synchronizations with @kdamond.
 | 
					 * @kdamond_lock:	Mutex for the synchronizations with @kdamond.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -427,15 +443,11 @@ struct damon_callback {
 | 
				
			||||||
 * @ops:	Set of monitoring operations for given use cases.
 | 
					 * @ops:	Set of monitoring operations for given use cases.
 | 
				
			||||||
 * @callback:	Set of callbacks for monitoring events notifications.
 | 
					 * @callback:	Set of callbacks for monitoring events notifications.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @min_nr_regions:	The minimum number of adaptive monitoring regions.
 | 
					 | 
				
			||||||
 * @max_nr_regions:	The maximum number of adaptive monitoring regions.
 | 
					 | 
				
			||||||
 * @adaptive_targets:	Head of monitoring targets (&damon_target) list.
 | 
					 * @adaptive_targets:	Head of monitoring targets (&damon_target) list.
 | 
				
			||||||
 * @schemes:		Head of schemes (&damos) list.
 | 
					 * @schemes:		Head of schemes (&damos) list.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct damon_ctx {
 | 
					struct damon_ctx {
 | 
				
			||||||
	unsigned long sample_interval;
 | 
						struct damon_attrs attrs;
 | 
				
			||||||
	unsigned long aggr_interval;
 | 
					 | 
				
			||||||
	unsigned long ops_update_interval;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* private: internal use only */
 | 
					/* private: internal use only */
 | 
				
			||||||
	struct timespec64 last_aggregation;
 | 
						struct timespec64 last_aggregation;
 | 
				
			||||||
| 
						 | 
					@ -448,8 +460,6 @@ struct damon_ctx {
 | 
				
			||||||
	struct damon_operations ops;
 | 
						struct damon_operations ops;
 | 
				
			||||||
	struct damon_callback callback;
 | 
						struct damon_callback callback;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	unsigned long min_nr_regions;
 | 
					 | 
				
			||||||
	unsigned long max_nr_regions;
 | 
					 | 
				
			||||||
	struct list_head adaptive_targets;
 | 
						struct list_head adaptive_targets;
 | 
				
			||||||
	struct list_head schemes;
 | 
						struct list_head schemes;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -382,17 +382,17 @@ struct damon_ctx *damon_new_ctx(void)
 | 
				
			||||||
	if (!ctx)
 | 
						if (!ctx)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx->sample_interval = 5 * 1000;
 | 
						ctx->attrs.sample_interval = 5 * 1000;
 | 
				
			||||||
	ctx->aggr_interval = 100 * 1000;
 | 
						ctx->attrs.aggr_interval = 100 * 1000;
 | 
				
			||||||
	ctx->ops_update_interval = 60 * 1000 * 1000;
 | 
						ctx->attrs.ops_update_interval = 60 * 1000 * 1000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ktime_get_coarse_ts64(&ctx->last_aggregation);
 | 
						ktime_get_coarse_ts64(&ctx->last_aggregation);
 | 
				
			||||||
	ctx->last_ops_update = ctx->last_aggregation;
 | 
						ctx->last_ops_update = ctx->last_aggregation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutex_init(&ctx->kdamond_lock);
 | 
						mutex_init(&ctx->kdamond_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx->min_nr_regions = 10;
 | 
						ctx->attrs.min_nr_regions = 10;
 | 
				
			||||||
	ctx->max_nr_regions = 1000;
 | 
						ctx->attrs.max_nr_regions = 1000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	INIT_LIST_HEAD(&ctx->adaptive_targets);
 | 
						INIT_LIST_HEAD(&ctx->adaptive_targets);
 | 
				
			||||||
	INIT_LIST_HEAD(&ctx->schemes);
 | 
						INIT_LIST_HEAD(&ctx->schemes);
 | 
				
			||||||
| 
						 | 
					@ -448,11 +448,11 @@ int damon_set_attrs(struct damon_ctx *ctx, unsigned long sample_int,
 | 
				
			||||||
	if (min_nr_reg > max_nr_reg)
 | 
						if (min_nr_reg > max_nr_reg)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx->sample_interval = sample_int;
 | 
						ctx->attrs.sample_interval = sample_int;
 | 
				
			||||||
	ctx->aggr_interval = aggr_int;
 | 
						ctx->attrs.aggr_interval = aggr_int;
 | 
				
			||||||
	ctx->ops_update_interval = ops_upd_int;
 | 
						ctx->attrs.ops_update_interval = ops_upd_int;
 | 
				
			||||||
	ctx->min_nr_regions = min_nr_reg;
 | 
						ctx->attrs.min_nr_regions = min_nr_reg;
 | 
				
			||||||
	ctx->max_nr_regions = max_nr_reg;
 | 
						ctx->attrs.max_nr_regions = max_nr_reg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -507,8 +507,8 @@ static unsigned long damon_region_sz_limit(struct damon_ctx *ctx)
 | 
				
			||||||
			sz += r->ar.end - r->ar.start;
 | 
								sz += r->ar.end - r->ar.start;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ctx->min_nr_regions)
 | 
						if (ctx->attrs.min_nr_regions)
 | 
				
			||||||
		sz /= ctx->min_nr_regions;
 | 
							sz /= ctx->attrs.min_nr_regions;
 | 
				
			||||||
	if (sz < DAMON_MIN_REGION)
 | 
						if (sz < DAMON_MIN_REGION)
 | 
				
			||||||
		sz = DAMON_MIN_REGION;
 | 
							sz = DAMON_MIN_REGION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -657,7 +657,7 @@ static bool damon_check_reset_time_interval(struct timespec64 *baseline,
 | 
				
			||||||
static bool kdamond_aggregate_interval_passed(struct damon_ctx *ctx)
 | 
					static bool kdamond_aggregate_interval_passed(struct damon_ctx *ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return damon_check_reset_time_interval(&ctx->last_aggregation,
 | 
						return damon_check_reset_time_interval(&ctx->last_aggregation,
 | 
				
			||||||
			ctx->aggr_interval);
 | 
								ctx->attrs.aggr_interval);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -1016,12 +1016,12 @@ static void kdamond_split_regions(struct damon_ctx *ctx)
 | 
				
			||||||
	damon_for_each_target(t, ctx)
 | 
						damon_for_each_target(t, ctx)
 | 
				
			||||||
		nr_regions += damon_nr_regions(t);
 | 
							nr_regions += damon_nr_regions(t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nr_regions > ctx->max_nr_regions / 2)
 | 
						if (nr_regions > ctx->attrs.max_nr_regions / 2)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Maybe the middle of the region has different access frequency */
 | 
						/* Maybe the middle of the region has different access frequency */
 | 
				
			||||||
	if (last_nr_regions == nr_regions &&
 | 
						if (last_nr_regions == nr_regions &&
 | 
				
			||||||
			nr_regions < ctx->max_nr_regions / 3)
 | 
								nr_regions < ctx->attrs.max_nr_regions / 3)
 | 
				
			||||||
		nr_subregions = 3;
 | 
							nr_subregions = 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	damon_for_each_target(t, ctx)
 | 
						damon_for_each_target(t, ctx)
 | 
				
			||||||
| 
						 | 
					@ -1039,7 +1039,7 @@ static void kdamond_split_regions(struct damon_ctx *ctx)
 | 
				
			||||||
static bool kdamond_need_update_operations(struct damon_ctx *ctx)
 | 
					static bool kdamond_need_update_operations(struct damon_ctx *ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return damon_check_reset_time_interval(&ctx->last_ops_update,
 | 
						return damon_check_reset_time_interval(&ctx->last_ops_update,
 | 
				
			||||||
			ctx->ops_update_interval);
 | 
								ctx->attrs.ops_update_interval);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -1188,7 +1188,7 @@ static int kdamond_fn(void *data)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		kdamond_usleep(ctx->sample_interval);
 | 
							kdamond_usleep(ctx->attrs.sample_interval);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (ctx->ops.check_accesses)
 | 
							if (ctx->ops.check_accesses)
 | 
				
			||||||
			max_nr_accesses = ctx->ops.check_accesses(ctx);
 | 
								max_nr_accesses = ctx->ops.check_accesses(ctx);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,9 +55,9 @@ static ssize_t dbgfs_attrs_read(struct file *file,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutex_lock(&ctx->kdamond_lock);
 | 
						mutex_lock(&ctx->kdamond_lock);
 | 
				
			||||||
	ret = scnprintf(kbuf, ARRAY_SIZE(kbuf), "%lu %lu %lu %lu %lu\n",
 | 
						ret = scnprintf(kbuf, ARRAY_SIZE(kbuf), "%lu %lu %lu %lu %lu\n",
 | 
				
			||||||
			ctx->sample_interval, ctx->aggr_interval,
 | 
								ctx->attrs.sample_interval, ctx->attrs.aggr_interval,
 | 
				
			||||||
			ctx->ops_update_interval, ctx->min_nr_regions,
 | 
								ctx->attrs.ops_update_interval,
 | 
				
			||||||
			ctx->max_nr_regions);
 | 
								ctx->attrs.min_nr_regions, ctx->attrs.max_nr_regions);
 | 
				
			||||||
	mutex_unlock(&ctx->kdamond_lock);
 | 
						mutex_unlock(&ctx->kdamond_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return simple_read_from_buffer(buf, count, ppos, kbuf, ret);
 | 
						return simple_read_from_buffer(buf, count, ppos, kbuf, ret);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,10 +99,10 @@ int damon_hot_score(struct damon_ctx *c, struct damon_region *r,
 | 
				
			||||||
	unsigned int age_weight = s->quota.weight_age;
 | 
						unsigned int age_weight = s->quota.weight_age;
 | 
				
			||||||
	int hotness;
 | 
						int hotness;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	max_nr_accesses = c->aggr_interval / c->sample_interval;
 | 
						max_nr_accesses = c->attrs.aggr_interval / c->attrs.sample_interval;
 | 
				
			||||||
	freq_subscore = r->nr_accesses * DAMON_MAX_SUBSCORE / max_nr_accesses;
 | 
						freq_subscore = r->nr_accesses * DAMON_MAX_SUBSCORE / max_nr_accesses;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	age_in_sec = (unsigned long)r->age * c->aggr_interval / 1000000;
 | 
						age_in_sec = (unsigned long)r->age * c->attrs.aggr_interval / 1000000;
 | 
				
			||||||
	for (age_in_log = 0; age_in_log < DAMON_MAX_AGE_IN_LOG && age_in_sec;
 | 
						for (age_in_log = 0; age_in_log < DAMON_MAX_AGE_IN_LOG && age_in_sec;
 | 
				
			||||||
			age_in_log++, age_in_sec >>= 1)
 | 
								age_in_log++, age_in_sec >>= 1)
 | 
				
			||||||
		;
 | 
							;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -251,8 +251,8 @@ static void __damon_va_init_regions(struct damon_ctx *ctx,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < 3; i++)
 | 
						for (i = 0; i < 3; i++)
 | 
				
			||||||
		sz += regions[i].end - regions[i].start;
 | 
							sz += regions[i].end - regions[i].start;
 | 
				
			||||||
	if (ctx->min_nr_regions)
 | 
						if (ctx->attrs.min_nr_regions)
 | 
				
			||||||
		sz /= ctx->min_nr_regions;
 | 
							sz /= ctx->attrs.min_nr_regions;
 | 
				
			||||||
	if (sz < DAMON_MIN_REGION)
 | 
						if (sz < DAMON_MIN_REGION)
 | 
				
			||||||
		sz = DAMON_MIN_REGION;
 | 
							sz = DAMON_MIN_REGION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue