mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
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…
Add table
Add a link
Reference in a new issue