* [PATCH 01/22] mm/damon/paddr: make supported DAMOS actions of paddr clear
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 02/22] mm/damon/paddr: deduplicate damon_pa_{mark_accessed,deactivate_pages}() SeongJae Park
` (20 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: Andrew Morton; +Cc: SeongJae Park, damon, linux-mm, linux-kernel
The 'swtich-case' statement in 'damon_va_apply_scheme()' function
provides a 'case' for every supported DAMOS action while all
not-yet-supported DAMOS actions fall through the 'default' case, and
comment it so that people can easily know which actions are supported.
Its counterpart in 'paddr', 'damon_pa_apply_scheme()', however, doesn't.
This commit makes the 'paddr' side function follows the pattern of
'vaddr' for better readability and consistency.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/paddr.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/mm/damon/paddr.c b/mm/damon/paddr.c
index f00cbe74a00e..5eba09d50855 100644
--- a/mm/damon/paddr.c
+++ b/mm/damon/paddr.c
@@ -274,7 +274,10 @@ static unsigned long damon_pa_apply_scheme(struct damon_ctx *ctx,
return damon_pa_mark_accessed(r);
case DAMOS_LRU_DEPRIO:
return damon_pa_deactivate_pages(r);
+ case DAMOS_STAT:
+ break;
default:
+ /* DAMOS actions that not yet supported by 'paddr'. */
break;
}
return 0;
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 02/22] mm/damon/paddr: deduplicate damon_pa_{mark_accessed,deactivate_pages}()
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
2022-09-13 17:44 ` [PATCH 01/22] mm/damon/paddr: make supported DAMOS actions of paddr clear SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 03/22] mm/damon/core: copy struct-to-struct instead of field-to-field in damon_new_scheme() SeongJae Park
` (19 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
The bodies of damon_pa_{mark_accessed,deactivate_pages}() contains
duplicates. This commit factors out the common part to a separate
function and removes the duplicates.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/paddr.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/mm/damon/paddr.c b/mm/damon/paddr.c
index 5eba09d50855..dfeebffe82f4 100644
--- a/mm/damon/paddr.c
+++ b/mm/damon/paddr.c
@@ -231,7 +231,8 @@ static unsigned long damon_pa_pageout(struct damon_region *r)
return applied * PAGE_SIZE;
}
-static unsigned long damon_pa_mark_accessed(struct damon_region *r)
+static inline unsigned long damon_pa_mark_accessed_or_deactivate(
+ struct damon_region *r, bool mark_accessed)
{
unsigned long addr, applied = 0;
@@ -240,27 +241,24 @@ static unsigned long damon_pa_mark_accessed(struct damon_region *r)
if (!page)
continue;
- mark_page_accessed(page);
+ if (mark_accessed)
+ mark_page_accessed(page);
+ else
+ deactivate_page(page);
put_page(page);
applied++;
}
return applied * PAGE_SIZE;
}
-static unsigned long damon_pa_deactivate_pages(struct damon_region *r)
+static unsigned long damon_pa_mark_accessed(struct damon_region *r)
{
- unsigned long addr, applied = 0;
-
- for (addr = r->ar.start; addr < r->ar.end; addr += PAGE_SIZE) {
- struct page *page = damon_get_page(PHYS_PFN(addr));
+ return damon_pa_mark_accessed_or_deactivate(r, true);
+}
- if (!page)
- continue;
- deactivate_page(page);
- put_page(page);
- applied++;
- }
- return applied * PAGE_SIZE;
+static unsigned long damon_pa_deactivate_pages(struct damon_region *r)
+{
+ return damon_pa_mark_accessed_or_deactivate(r, false);
}
static unsigned long damon_pa_apply_scheme(struct damon_ctx *ctx,
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 03/22] mm/damon/core: copy struct-to-struct instead of field-to-field in damon_new_scheme()
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
2022-09-13 17:44 ` [PATCH 01/22] mm/damon/paddr: make supported DAMOS actions of paddr clear SeongJae Park
2022-09-13 17:44 ` [PATCH 02/22] mm/damon/paddr: deduplicate damon_pa_{mark_accessed,deactivate_pages}() SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 04/22] mm/damon/core: factor out 'damos_quota' private fileds initialization SeongJae Park
` (18 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: Andrew Morton; +Cc: SeongJae Park, damon, linux-mm, linux-kernel
The function for new 'struct damos' creation, 'damon_new_scheme()',
copies each field of the struct one by one, though it could simply
copied via struct to struct. This commit replaces the unnecessarily
verbose field-to-field copies with struct-to-struct copies to make code
simple and short.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/core.c | 21 ++++-----------------
1 file changed, 4 insertions(+), 17 deletions(-)
diff --git a/mm/damon/core.c b/mm/damon/core.c
index c21f5fe5928a..27e0c312f7a5 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -276,22 +276,13 @@ struct damos *damon_new_scheme(struct damos_access_pattern *pattern,
scheme = kmalloc(sizeof(*scheme), GFP_KERNEL);
if (!scheme)
return NULL;
- scheme->pattern.min_sz_region = pattern->min_sz_region;
- scheme->pattern.max_sz_region = pattern->max_sz_region;
- scheme->pattern.min_nr_accesses = pattern->min_nr_accesses;
- scheme->pattern.max_nr_accesses = pattern->max_nr_accesses;
- scheme->pattern.min_age_region = pattern->min_age_region;
- scheme->pattern.max_age_region = pattern->max_age_region;
+ scheme->pattern = *pattern;
scheme->action = action;
scheme->stat = (struct damos_stat){};
INIT_LIST_HEAD(&scheme->list);
- scheme->quota.ms = quota->ms;
- scheme->quota.sz = quota->sz;
- scheme->quota.reset_interval = quota->reset_interval;
- scheme->quota.weight_sz = quota->weight_sz;
- scheme->quota.weight_nr_accesses = quota->weight_nr_accesses;
- scheme->quota.weight_age = quota->weight_age;
+ scheme->quota = *quota;
+ /* caller might not zero-initialized the private fileds */
scheme->quota.total_charged_sz = 0;
scheme->quota.total_charged_ns = 0;
scheme->quota.esz = 0;
@@ -300,11 +291,7 @@ struct damos *damon_new_scheme(struct damos_access_pattern *pattern,
scheme->quota.charge_target_from = NULL;
scheme->quota.charge_addr_from = 0;
- scheme->wmarks.metric = wmarks->metric;
- scheme->wmarks.interval = wmarks->interval;
- scheme->wmarks.high = wmarks->high;
- scheme->wmarks.mid = wmarks->mid;
- scheme->wmarks.low = wmarks->low;
+ scheme->wmarks = *wmarks;
scheme->wmarks.activated = true;
return scheme;
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 04/22] mm/damon/core: factor out 'damos_quota' private fileds initialization
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (2 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 03/22] mm/damon/core: copy struct-to-struct instead of field-to-field in damon_new_scheme() SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 05/22] mm/damon/core: use a dedicated struct for monitoring attributes SeongJae Park
` (17 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: Andrew Morton; +Cc: SeongJae Park, damon, linux-mm, linux-kernel
The 'struct damos' creation function, 'damon_new_scheme()', does
initialization of private fileds of 'struct damos_quota' in it. As its
verbose and makes the function unnecessarily long, this commit factors
it out to separate function.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/core.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 27e0c312f7a5..6767580c0a27 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -267,6 +267,19 @@ int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges,
return 0;
}
+/* initialize private fields of damos_quota and return the pointer */
+static struct damos_quota *damos_quota_init_priv(struct damos_quota *quota)
+{
+ quota->total_charged_sz = 0;
+ quota->total_charged_ns = 0;
+ quota->esz = 0;
+ quota->charged_sz = 0;
+ quota->charged_from = 0;
+ quota->charge_target_from = NULL;
+ quota->charge_addr_from = 0;
+ return quota;
+}
+
struct damos *damon_new_scheme(struct damos_access_pattern *pattern,
enum damos_action action, struct damos_quota *quota,
struct damos_watermarks *wmarks)
@@ -281,15 +294,7 @@ struct damos *damon_new_scheme(struct damos_access_pattern *pattern,
scheme->stat = (struct damos_stat){};
INIT_LIST_HEAD(&scheme->list);
- scheme->quota = *quota;
- /* caller might not zero-initialized the private fileds */
- scheme->quota.total_charged_sz = 0;
- scheme->quota.total_charged_ns = 0;
- scheme->quota.esz = 0;
- scheme->quota.charged_sz = 0;
- scheme->quota.charged_from = 0;
- scheme->quota.charge_target_from = NULL;
- scheme->quota.charge_addr_from = 0;
+ scheme->quota = *(damos_quota_init_priv(quota));
scheme->wmarks = *wmarks;
scheme->wmarks.activated = true;
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 05/22] mm/damon/core: use a dedicated struct for monitoring attributes
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (3 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 04/22] mm/damon/core: factor out 'damos_quota' private fileds initialization SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 06/22] mm/damon/core: reduce parameters for damon_set_attrs() SeongJae Park
` (16 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
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'.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
include/linux/damon.h | 30 ++++++++++++++++++++----------
mm/damon/core.c | 34 +++++++++++++++++-----------------
mm/damon/dbgfs.c | 6 +++---
mm/damon/ops-common.c | 4 ++--
mm/damon/vaddr.c | 4 ++--
5 files changed, 44 insertions(+), 34 deletions(-)
diff --git a/include/linux/damon.h b/include/linux/damon.h
index 016b6c9c03d6..2ceee8b07726 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -389,13 +389,15 @@ struct damon_callback {
};
/**
- * 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.
+ * struct damon_attrs - Monitoring attributes for accuracy/overhead control.
*
* @sample_interval: The time between access samplings.
* @aggr_interval: The time between monitor results aggregations.
* @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
* 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.
* Please refer to &struct damon_operations and &struct damon_callback for more
* 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_lock: Mutex for the synchronizations with @kdamond.
*
@@ -427,15 +443,11 @@ struct damon_callback {
* @ops: Set of monitoring operations for given use cases.
* @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.
* @schemes: Head of schemes (&damos) list.
*/
struct damon_ctx {
- unsigned long sample_interval;
- unsigned long aggr_interval;
- unsigned long ops_update_interval;
+ struct damon_attrs attrs;
/* private: internal use only */
struct timespec64 last_aggregation;
@@ -448,8 +460,6 @@ struct damon_ctx {
struct damon_operations ops;
struct damon_callback callback;
- unsigned long min_nr_regions;
- unsigned long max_nr_regions;
struct list_head adaptive_targets;
struct list_head schemes;
};
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 6767580c0a27..1f43ea9d956c 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -405,17 +405,17 @@ struct damon_ctx *damon_new_ctx(void)
if (!ctx)
return NULL;
- ctx->sample_interval = 5 * 1000;
- ctx->aggr_interval = 100 * 1000;
- ctx->ops_update_interval = 60 * 1000 * 1000;
+ ctx->attrs.sample_interval = 5 * 1000;
+ ctx->attrs.aggr_interval = 100 * 1000;
+ ctx->attrs.ops_update_interval = 60 * 1000 * 1000;
ktime_get_coarse_ts64(&ctx->last_aggregation);
ctx->last_ops_update = ctx->last_aggregation;
mutex_init(&ctx->kdamond_lock);
- ctx->min_nr_regions = 10;
- ctx->max_nr_regions = 1000;
+ ctx->attrs.min_nr_regions = 10;
+ ctx->attrs.max_nr_regions = 1000;
INIT_LIST_HEAD(&ctx->adaptive_targets);
INIT_LIST_HEAD(&ctx->schemes);
@@ -471,11 +471,11 @@ int damon_set_attrs(struct damon_ctx *ctx, unsigned long sample_int,
if (min_nr_reg > max_nr_reg)
return -EINVAL;
- ctx->sample_interval = sample_int;
- ctx->aggr_interval = aggr_int;
- ctx->ops_update_interval = ops_upd_int;
- ctx->min_nr_regions = min_nr_reg;
- ctx->max_nr_regions = max_nr_reg;
+ ctx->attrs.sample_interval = sample_int;
+ ctx->attrs.aggr_interval = aggr_int;
+ ctx->attrs.ops_update_interval = ops_upd_int;
+ ctx->attrs.min_nr_regions = min_nr_reg;
+ ctx->attrs.max_nr_regions = max_nr_reg;
return 0;
}
@@ -530,8 +530,8 @@ static unsigned long damon_region_sz_limit(struct damon_ctx *ctx)
sz += r->ar.end - r->ar.start;
}
- if (ctx->min_nr_regions)
- sz /= ctx->min_nr_regions;
+ if (ctx->attrs.min_nr_regions)
+ sz /= ctx->attrs.min_nr_regions;
if (sz < DAMON_MIN_REGION)
sz = DAMON_MIN_REGION;
@@ -680,7 +680,7 @@ static bool damon_check_reset_time_interval(struct timespec64 *baseline,
static bool kdamond_aggregate_interval_passed(struct damon_ctx *ctx)
{
return damon_check_reset_time_interval(&ctx->last_aggregation,
- ctx->aggr_interval);
+ ctx->attrs.aggr_interval);
}
/*
@@ -1062,12 +1062,12 @@ static void kdamond_split_regions(struct damon_ctx *ctx)
damon_for_each_target(t, ctx)
nr_regions += damon_nr_regions(t);
- if (nr_regions > ctx->max_nr_regions / 2)
+ if (nr_regions > ctx->attrs.max_nr_regions / 2)
return;
/* Maybe the middle of the region has different access frequency */
if (last_nr_regions == nr_regions &&
- nr_regions < ctx->max_nr_regions / 3)
+ nr_regions < ctx->attrs.max_nr_regions / 3)
nr_subregions = 3;
damon_for_each_target(t, ctx)
@@ -1085,7 +1085,7 @@ static void kdamond_split_regions(struct damon_ctx *ctx)
static bool kdamond_need_update_operations(struct damon_ctx *ctx)
{
return damon_check_reset_time_interval(&ctx->last_ops_update,
- ctx->ops_update_interval);
+ ctx->attrs.ops_update_interval);
}
/*
@@ -1229,7 +1229,7 @@ static int kdamond_fn(void *data)
ctx->callback.after_sampling(ctx))
break;
- kdamond_usleep(ctx->sample_interval);
+ kdamond_usleep(ctx->attrs.sample_interval);
if (ctx->ops.check_accesses)
max_nr_accesses = ctx->ops.check_accesses(ctx);
diff --git a/mm/damon/dbgfs.c b/mm/damon/dbgfs.c
index 1422037cedd2..74e7542af6d3 100644
--- a/mm/damon/dbgfs.c
+++ b/mm/damon/dbgfs.c
@@ -55,9 +55,9 @@ static ssize_t dbgfs_attrs_read(struct file *file,
mutex_lock(&ctx->kdamond_lock);
ret = scnprintf(kbuf, ARRAY_SIZE(kbuf), "%lu %lu %lu %lu %lu\n",
- ctx->sample_interval, ctx->aggr_interval,
- ctx->ops_update_interval, ctx->min_nr_regions,
- ctx->max_nr_regions);
+ ctx->attrs.sample_interval, ctx->attrs.aggr_interval,
+ ctx->attrs.ops_update_interval,
+ ctx->attrs.min_nr_regions, ctx->attrs.max_nr_regions);
mutex_unlock(&ctx->kdamond_lock);
return simple_read_from_buffer(buf, count, ppos, kbuf, ret);
diff --git a/mm/damon/ops-common.c b/mm/damon/ops-common.c
index f599838b5f64..9310df72e1c5 100644
--- a/mm/damon/ops-common.c
+++ b/mm/damon/ops-common.c
@@ -99,10 +99,10 @@ int damon_hot_score(struct damon_ctx *c, struct damon_region *r,
unsigned int age_weight = s->quota.weight_age;
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;
- 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;
age_in_log++, age_in_sec >>= 1)
;
diff --git a/mm/damon/vaddr.c b/mm/damon/vaddr.c
index 39ea48d9cc15..3f84584f9982 100644
--- a/mm/damon/vaddr.c
+++ b/mm/damon/vaddr.c
@@ -251,8 +251,8 @@ static void __damon_va_init_regions(struct damon_ctx *ctx,
for (i = 0; i < 3; i++)
sz += regions[i].end - regions[i].start;
- if (ctx->min_nr_regions)
- sz /= ctx->min_nr_regions;
+ if (ctx->attrs.min_nr_regions)
+ sz /= ctx->attrs.min_nr_regions;
if (sz < DAMON_MIN_REGION)
sz = DAMON_MIN_REGION;
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 06/22] mm/damon/core: reduce parameters for damon_set_attrs()
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (4 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 05/22] mm/damon/core: use a dedicated struct for monitoring attributes SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 07/22] mm/damon/reclaim: use 'struct damon_attrs' for storing parameters for it SeongJae Park
` (15 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
Number of parameters for 'damon_set_attrs()' is six. As it could be
confusing and verbose, this commit reduces the number by receiving
single pointer to a 'struct damon_attrs'.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
include/linux/damon.h | 4 +---
mm/damon/core.c | 21 +++++----------------
mm/damon/dbgfs.c | 9 ++++++---
mm/damon/lru_sort.c | 10 ++++++++--
mm/damon/reclaim.c | 10 ++++++++--
mm/damon/sysfs.c | 12 ++++++++----
6 files changed, 36 insertions(+), 30 deletions(-)
diff --git a/include/linux/damon.h b/include/linux/damon.h
index 2ceee8b07726..c5dc0c77c772 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -540,9 +540,7 @@ unsigned int damon_nr_regions(struct damon_target *t);
struct damon_ctx *damon_new_ctx(void);
void damon_destroy_ctx(struct damon_ctx *ctx);
-int damon_set_attrs(struct damon_ctx *ctx, unsigned long sample_int,
- unsigned long aggr_int, unsigned long ops_upd_int,
- unsigned long min_nr_reg, unsigned long max_nr_reg);
+int damon_set_attrs(struct damon_ctx *ctx, struct damon_attrs *attrs);
int damon_set_schemes(struct damon_ctx *ctx,
struct damos **schemes, ssize_t nr_schemes);
int damon_nr_running_ctxs(void);
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 1f43ea9d956c..d9d1bebc6a78 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -451,32 +451,21 @@ void damon_destroy_ctx(struct damon_ctx *ctx)
/**
* damon_set_attrs() - Set attributes for the monitoring.
* @ctx: monitoring context
- * @sample_int: time interval between samplings
- * @aggr_int: time interval between aggregations
- * @ops_upd_int: time interval between monitoring operations updates
- * @min_nr_reg: minimal number of regions
- * @max_nr_reg: maximum number of regions
+ * @attrs: monitoring attributes
*
* This function should not be called while the kdamond is running.
* Every time interval is in micro-seconds.
*
* Return: 0 on success, negative error code otherwise.
*/
-int damon_set_attrs(struct damon_ctx *ctx, unsigned long sample_int,
- unsigned long aggr_int, unsigned long ops_upd_int,
- unsigned long min_nr_reg, unsigned long max_nr_reg)
+int damon_set_attrs(struct damon_ctx *ctx, struct damon_attrs *attrs)
{
- if (min_nr_reg < 3)
+ if (attrs->min_nr_regions < 3)
return -EINVAL;
- if (min_nr_reg > max_nr_reg)
+ if (attrs->min_nr_regions > attrs->max_nr_regions)
return -EINVAL;
- ctx->attrs.sample_interval = sample_int;
- ctx->attrs.aggr_interval = aggr_int;
- ctx->attrs.ops_update_interval = ops_upd_int;
- ctx->attrs.min_nr_regions = min_nr_reg;
- ctx->attrs.max_nr_regions = max_nr_reg;
-
+ ctx->attrs = *attrs;
return 0;
}
diff --git a/mm/damon/dbgfs.c b/mm/damon/dbgfs.c
index 74e7542af6d3..c00eba4448d8 100644
--- a/mm/damon/dbgfs.c
+++ b/mm/damon/dbgfs.c
@@ -67,7 +67,7 @@ static ssize_t dbgfs_attrs_write(struct file *file,
const char __user *buf, size_t count, loff_t *ppos)
{
struct damon_ctx *ctx = file->private_data;
- unsigned long s, a, r, minr, maxr;
+ struct damon_attrs attrs;
char *kbuf;
ssize_t ret;
@@ -76,7 +76,10 @@ static ssize_t dbgfs_attrs_write(struct file *file,
return PTR_ERR(kbuf);
if (sscanf(kbuf, "%lu %lu %lu %lu %lu",
- &s, &a, &r, &minr, &maxr) != 5) {
+ &attrs.sample_interval, &attrs.aggr_interval,
+ &attrs.ops_update_interval,
+ &attrs.min_nr_regions,
+ &attrs.max_nr_regions) != 5) {
ret = -EINVAL;
goto out;
}
@@ -87,7 +90,7 @@ static ssize_t dbgfs_attrs_write(struct file *file,
goto unlock_out;
}
- ret = damon_set_attrs(ctx, s, a, r, minr, maxr);
+ ret = damon_set_attrs(ctx, &attrs);
if (!ret)
ret = count;
unlock_out:
diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c
index 307ba71adcfa..6d5f83965276 100644
--- a/mm/damon/lru_sort.c
+++ b/mm/damon/lru_sort.c
@@ -350,13 +350,19 @@ static struct damos *damon_lru_sort_new_cold_scheme(unsigned int cold_thres)
static int damon_lru_sort_apply_parameters(void)
{
+ struct damon_attrs attrs = {
+ .sample_interval = sample_interval,
+ .aggr_interval = aggr_interval,
+ .ops_update_interval = 0,
+ .min_nr_regions = min_nr_regions,
+ .max_nr_regions = max_nr_regions,
+ };
struct damos *scheme;
struct damon_addr_range addr_range;
unsigned int hot_thres, cold_thres;
int err = 0;
- err = damon_set_attrs(ctx, sample_interval, aggr_interval, 0,
- min_nr_regions, max_nr_regions);
+ err = damon_set_attrs(ctx, &attrs);
if (err)
return err;
diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c
index fe7bc0c55ecb..bc841efbab45 100644
--- a/mm/damon/reclaim.c
+++ b/mm/damon/reclaim.c
@@ -275,12 +275,18 @@ static struct damos *damon_reclaim_new_scheme(void)
static int damon_reclaim_apply_parameters(void)
{
+ struct damon_attrs attrs = {
+ .sample_interval = sample_interval,
+ .aggr_interval = aggr_interval,
+ .ops_update_interval = 0,
+ .min_nr_regions = min_nr_regions,
+ .max_nr_regions = max_nr_regions,
+ };
struct damos *scheme;
struct damon_addr_range addr_range;
int err = 0;
- err = damon_set_attrs(ctx, sample_interval, aggr_interval, 0,
- min_nr_regions, max_nr_regions);
+ err = damon_set_attrs(ctx, &attrs);
if (err)
return err;
diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
index 3606eec9b65d..1fa0023f136e 100644
--- a/mm/damon/sysfs.c
+++ b/mm/damon/sysfs.c
@@ -2130,10 +2130,14 @@ static int damon_sysfs_set_attrs(struct damon_ctx *ctx,
struct damon_sysfs_intervals *sys_intervals = sys_attrs->intervals;
struct damon_sysfs_ul_range *sys_nr_regions =
sys_attrs->nr_regions_range;
-
- return damon_set_attrs(ctx, sys_intervals->sample_us,
- sys_intervals->aggr_us, sys_intervals->update_us,
- sys_nr_regions->min, sys_nr_regions->max);
+ struct damon_attrs attrs = {
+ .sample_interval = sys_intervals->sample_us,
+ .aggr_interval = sys_intervals->aggr_us,
+ .ops_update_interval = sys_intervals->update_us,
+ .min_nr_regions = sys_nr_regions->min,
+ .max_nr_regions = sys_nr_regions->max,
+ };
+ return damon_set_attrs(ctx, &attrs);
}
static void damon_sysfs_destroy_targets(struct damon_ctx *ctx)
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 07/22] mm/damon/reclaim: use 'struct damon_attrs' for storing parameters for it
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (5 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 06/22] mm/damon/core: reduce parameters for damon_set_attrs() SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 08/22] mm/damon/lru_sort: " SeongJae Park
` (14 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
DAMON_RECLAIM receives monitoring attributes by parameters one by one to
separate variables, and then combine those into 'struct damon_attrs'.
This commit makes the module directly stores the parameter values to a
static 'struct damon_attrs' variable and use it to simplify the code.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/reclaim.c | 36 +++++++++++++++++++-----------------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c
index bc841efbab45..d35a00d8dde2 100644
--- a/mm/damon/reclaim.c
+++ b/mm/damon/reclaim.c
@@ -129,14 +129,22 @@ module_param(wmarks_mid, ulong, 0600);
static unsigned long wmarks_low __read_mostly = 200;
module_param(wmarks_low, ulong, 0600);
+static struct damon_attrs damon_reclaim_mon_attrs = {
+ .sample_interval = 5000,
+ .aggr_interval = 100000,
+ .ops_update_interval = 0,
+ .min_nr_regions = 10,
+ .max_nr_regions = 1000,
+};
+
/*
* Sampling interval for the monitoring in microseconds.
*
* The sampling interval of DAMON for the cold memory monitoring. Please refer
* to the DAMON documentation for more detail. 5 ms by default.
*/
-static unsigned long sample_interval __read_mostly = 5000;
-module_param(sample_interval, ulong, 0600);
+module_param_named(sample_interval, damon_reclaim_mon_attrs.sample_interval,
+ ulong, 0600);
/*
* Aggregation interval for the monitoring in microseconds.
@@ -144,8 +152,8 @@ module_param(sample_interval, ulong, 0600);
* The aggregation interval of DAMON for the cold memory monitoring. Please
* refer to the DAMON documentation for more detail. 100 ms by default.
*/
-static unsigned long aggr_interval __read_mostly = 100000;
-module_param(aggr_interval, ulong, 0600);
+module_param_named(aggr_interval, damon_reclaim_mon_attrs.aggr_interval, ulong,
+ 0600);
/*
* Minimum number of monitoring regions.
@@ -155,8 +163,8 @@ module_param(aggr_interval, ulong, 0600);
* But, setting this too high could result in increased monitoring overhead.
* Please refer to the DAMON documentation for more detail. 10 by default.
*/
-static unsigned long min_nr_regions __read_mostly = 10;
-module_param(min_nr_regions, ulong, 0600);
+module_param_named(min_nr_regions, damon_reclaim_mon_attrs.min_nr_regions,
+ ulong, 0600);
/*
* Maximum number of monitoring regions.
@@ -166,8 +174,8 @@ module_param(min_nr_regions, ulong, 0600);
* However, setting this too low could result in bad monitoring quality.
* Please refer to the DAMON documentation for more detail. 1000 by default.
*/
-static unsigned long max_nr_regions __read_mostly = 1000;
-module_param(max_nr_regions, ulong, 0600);
+module_param_named(max_nr_regions, damon_reclaim_mon_attrs.max_nr_regions,
+ ulong, 0600);
/*
* Start of the target memory region in physical address.
@@ -239,7 +247,8 @@ static struct damos *damon_reclaim_new_scheme(void)
.min_nr_accesses = 0,
.max_nr_accesses = 0,
/* for min_age or more micro-seconds */
- .min_age_region = min_age / aggr_interval,
+ .min_age_region = min_age /
+ damon_reclaim_mon_attrs.aggr_interval,
.max_age_region = UINT_MAX,
};
struct damos_watermarks wmarks = {
@@ -275,18 +284,11 @@ static struct damos *damon_reclaim_new_scheme(void)
static int damon_reclaim_apply_parameters(void)
{
- struct damon_attrs attrs = {
- .sample_interval = sample_interval,
- .aggr_interval = aggr_interval,
- .ops_update_interval = 0,
- .min_nr_regions = min_nr_regions,
- .max_nr_regions = max_nr_regions,
- };
struct damos *scheme;
struct damon_addr_range addr_range;
int err = 0;
- err = damon_set_attrs(ctx, &attrs);
+ err = damon_set_attrs(ctx, &damon_reclaim_mon_attrs);
if (err)
return err;
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 08/22] mm/damon/lru_sort: use 'struct damon_attrs' for storing parameters for it
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (6 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 07/22] mm/damon/reclaim: use 'struct damon_attrs' for storing parameters for it SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 09/22] mm/damon: implement a monitoring attributes module parameters generator macro SeongJae Park
` (13 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
DAMON_LRU_SORT receives monitoring attributes by parameters one by one
to separate variables, and then combines those into 'struct
damon_attrs'. This commit makes the module directly stores the
parameter values to a static 'struct damon_attrs' variable and use it to
simplify the code.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/lru_sort.c | 40 +++++++++++++++++++++-------------------
1 file changed, 21 insertions(+), 19 deletions(-)
diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c
index 6d5f83965276..ade985b83652 100644
--- a/mm/damon/lru_sort.c
+++ b/mm/damon/lru_sort.c
@@ -127,14 +127,22 @@ module_param(wmarks_mid, ulong, 0600);
static unsigned long wmarks_low __read_mostly = 50;
module_param(wmarks_low, ulong, 0600);
+static struct damon_attrs damon_lru_sort_mon_attrs = {
+ .sample_interval = 5000,
+ .aggr_interval = 100000,
+ .ops_update_interval = 0,
+ .min_nr_regions = 10,
+ .max_nr_regions = 1000,
+};
+
/*
* Sampling interval for the monitoring in microseconds.
*
* The sampling interval of DAMON for the hot/cold memory monitoring. Please
* refer to the DAMON documentation for more detail. 5 ms by default.
*/
-static unsigned long sample_interval __read_mostly = 5000;
-module_param(sample_interval, ulong, 0600);
+module_param_named(sample_interval, damon_lru_sort_mon_attrs.sample_interval,
+ ulong, 0600);
/*
* Aggregation interval for the monitoring in microseconds.
@@ -142,8 +150,8 @@ module_param(sample_interval, ulong, 0600);
* The aggregation interval of DAMON for the hot/cold memory monitoring.
* Please refer to the DAMON documentation for more detail. 100 ms by default.
*/
-static unsigned long aggr_interval __read_mostly = 100000;
-module_param(aggr_interval, ulong, 0600);
+module_param_named(aggr_interval, damon_lru_sort_mon_attrs.aggr_interval, ulong,
+ 0600);
/*
* Minimum number of monitoring regions.
@@ -153,8 +161,8 @@ module_param(aggr_interval, ulong, 0600);
* But, setting this too high could result in increased monitoring overhead.
* Please refer to the DAMON documentation for more detail. 10 by default.
*/
-static unsigned long min_nr_regions __read_mostly = 10;
-module_param(min_nr_regions, ulong, 0600);
+module_param_named(min_nr_regions, damon_lru_sort_mon_attrs.min_nr_regions,
+ ulong, 0600);
/*
* Maximum number of monitoring regions.
@@ -164,8 +172,8 @@ module_param(min_nr_regions, ulong, 0600);
* However, setting this too low could result in bad monitoring quality.
* Please refer to the DAMON documentation for more detail. 1000 by default.
*/
-static unsigned long max_nr_regions __read_mostly = 1000;
-module_param(max_nr_regions, ulong, 0600);
+module_param_named(max_nr_regions, damon_lru_sort_mon_attrs.max_nr_regions,
+ ulong, 0600);
/*
* Start of the target memory region in physical address.
@@ -350,25 +358,19 @@ static struct damos *damon_lru_sort_new_cold_scheme(unsigned int cold_thres)
static int damon_lru_sort_apply_parameters(void)
{
- struct damon_attrs attrs = {
- .sample_interval = sample_interval,
- .aggr_interval = aggr_interval,
- .ops_update_interval = 0,
- .min_nr_regions = min_nr_regions,
- .max_nr_regions = max_nr_regions,
- };
struct damos *scheme;
struct damon_addr_range addr_range;
unsigned int hot_thres, cold_thres;
int err = 0;
- err = damon_set_attrs(ctx, &attrs);
+ err = damon_set_attrs(ctx, &damon_lru_sort_mon_attrs);
if (err)
return err;
/* aggr_interval / sample_interval is the maximum nr_accesses */
- hot_thres = aggr_interval / sample_interval * hot_thres_access_freq /
- 1000;
+ hot_thres = damon_lru_sort_mon_attrs.aggr_interval /
+ damon_lru_sort_mon_attrs.sample_interval *
+ hot_thres_access_freq / 1000;
scheme = damon_lru_sort_new_hot_scheme(hot_thres);
if (!scheme)
return -ENOMEM;
@@ -376,7 +378,7 @@ static int damon_lru_sort_apply_parameters(void)
if (err)
return err;
- cold_thres = cold_min_age / aggr_interval;
+ cold_thres = cold_min_age / damon_lru_sort_mon_attrs.aggr_interval;
scheme = damon_lru_sort_new_cold_scheme(cold_thres);
if (!scheme)
return -ENOMEM;
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 09/22] mm/damon: implement a monitoring attributes module parameters generator macro
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (7 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 08/22] mm/damon/lru_sort: " SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 10/22] mm/damon/lru_sort: use monitoring attributes parameters generaotr macro SeongJae Park
` (12 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: linux-kernel, damon, linux-mm
DAMON_RECLAIM and DAMON_LRU_SORT have module parameters for monitoring
attributes that having same names. This commot implements a macro for
generating such module parameters so that we can reuse later.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/modules-common.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
create mode 100644 mm/damon/modules-common.h
diff --git a/mm/damon/modules-common.h b/mm/damon/modules-common.h
new file mode 100644
index 000000000000..0abd0636bc64
--- /dev/null
+++ b/mm/damon/modules-common.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Common Primitives for DAMON Modules
+ *
+ * Author: SeongJae Park <sj@kernel.org>
+ */
+
+#include <linux/moduleparam.h>
+
+#define DEFINE_DAMON_MODULES_MON_ATTRS_PARAMS(attrs) \
+ module_param_named(sample_interval, attrs.sample_interval, \
+ ulong, 0600); \
+ module_param_named(aggr_interval, attrs.aggr_interval, ulong, \
+ 0600); \
+ module_param_named(min_nr_regions, attrs.min_nr_regions, ulong, \
+ 0600); \
+ module_param_named(max_nr_regions, attrs.max_nr_regions, ulong, \
+ 0600);
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 10/22] mm/damon/lru_sort: use monitoring attributes parameters generaotr macro
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (8 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 09/22] mm/damon: implement a monitoring attributes module parameters generator macro SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 11/22] mm/damon/reclaim: use monitoring attributes parameters generator macro SeongJae Park
` (11 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
This commit makes DAMON_LRU_SORT to generate the module parameters for
DAMON monitoring attributes using the generator macro to simplify the
code and reduce duplicates.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/lru_sort.c | 47 +++++----------------------------------------
1 file changed, 5 insertions(+), 42 deletions(-)
diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c
index ade985b83652..e95626acee6f 100644
--- a/mm/damon/lru_sort.c
+++ b/mm/damon/lru_sort.c
@@ -13,6 +13,8 @@
#include <linux/sched.h>
#include <linux/workqueue.h>
+#include "modules-common.h"
+
#ifdef MODULE_PARAM_PREFIX
#undef MODULE_PARAM_PREFIX
#endif
@@ -128,52 +130,13 @@ static unsigned long wmarks_low __read_mostly = 50;
module_param(wmarks_low, ulong, 0600);
static struct damon_attrs damon_lru_sort_mon_attrs = {
- .sample_interval = 5000,
- .aggr_interval = 100000,
+ .sample_interval = 5000, /* 5 ms */
+ .aggr_interval = 100000, /* 100 ms */
.ops_update_interval = 0,
.min_nr_regions = 10,
.max_nr_regions = 1000,
};
-
-/*
- * Sampling interval for the monitoring in microseconds.
- *
- * The sampling interval of DAMON for the hot/cold memory monitoring. Please
- * refer to the DAMON documentation for more detail. 5 ms by default.
- */
-module_param_named(sample_interval, damon_lru_sort_mon_attrs.sample_interval,
- ulong, 0600);
-
-/*
- * Aggregation interval for the monitoring in microseconds.
- *
- * The aggregation interval of DAMON for the hot/cold memory monitoring.
- * Please refer to the DAMON documentation for more detail. 100 ms by default.
- */
-module_param_named(aggr_interval, damon_lru_sort_mon_attrs.aggr_interval, ulong,
- 0600);
-
-/*
- * Minimum number of monitoring regions.
- *
- * The minimal number of monitoring regions of DAMON for the hot/cold memory
- * monitoring. This can be used to set lower-bound of the monitoring quality.
- * But, setting this too high could result in increased monitoring overhead.
- * Please refer to the DAMON documentation for more detail. 10 by default.
- */
-module_param_named(min_nr_regions, damon_lru_sort_mon_attrs.min_nr_regions,
- ulong, 0600);
-
-/*
- * Maximum number of monitoring regions.
- *
- * The maximum number of monitoring regions of DAMON for the hot/cold memory
- * monitoring. This can be used to set upper-bound of the monitoring overhead.
- * However, setting this too low could result in bad monitoring quality.
- * Please refer to the DAMON documentation for more detail. 1000 by default.
- */
-module_param_named(max_nr_regions, damon_lru_sort_mon_attrs.max_nr_regions,
- ulong, 0600);
+DEFINE_DAMON_MODULES_MON_ATTRS_PARAMS(damon_lru_sort_mon_attrs);
/*
* Start of the target memory region in physical address.
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 11/22] mm/damon/reclaim: use monitoring attributes parameters generator macro
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (9 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 10/22] mm/damon/lru_sort: use monitoring attributes parameters generaotr macro SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 12/22] mm/damon/modules-common: implement a watermarks module " SeongJae Park
` (10 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
This commit makes DAMON_RECLAIM to generate the module parameters for
DAMON monitoring attributes using the generator macro to simplify the
code and reduce duplicates.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/reclaim.c | 47 +++++-----------------------------------------
1 file changed, 5 insertions(+), 42 deletions(-)
diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c
index d35a00d8dde2..48326bef20f5 100644
--- a/mm/damon/reclaim.c
+++ b/mm/damon/reclaim.c
@@ -13,6 +13,8 @@
#include <linux/sched.h>
#include <linux/workqueue.h>
+#include "modules-common.h"
+
#ifdef MODULE_PARAM_PREFIX
#undef MODULE_PARAM_PREFIX
#endif
@@ -130,52 +132,13 @@ static unsigned long wmarks_low __read_mostly = 200;
module_param(wmarks_low, ulong, 0600);
static struct damon_attrs damon_reclaim_mon_attrs = {
- .sample_interval = 5000,
- .aggr_interval = 100000,
+ .sample_interval = 5000, /* 5 ms */
+ .aggr_interval = 100000, /* 100 ms */
.ops_update_interval = 0,
.min_nr_regions = 10,
.max_nr_regions = 1000,
};
-
-/*
- * Sampling interval for the monitoring in microseconds.
- *
- * The sampling interval of DAMON for the cold memory monitoring. Please refer
- * to the DAMON documentation for more detail. 5 ms by default.
- */
-module_param_named(sample_interval, damon_reclaim_mon_attrs.sample_interval,
- ulong, 0600);
-
-/*
- * Aggregation interval for the monitoring in microseconds.
- *
- * The aggregation interval of DAMON for the cold memory monitoring. Please
- * refer to the DAMON documentation for more detail. 100 ms by default.
- */
-module_param_named(aggr_interval, damon_reclaim_mon_attrs.aggr_interval, ulong,
- 0600);
-
-/*
- * Minimum number of monitoring regions.
- *
- * The minimal number of monitoring regions of DAMON for the cold memory
- * monitoring. This can be used to set lower-bound of the monitoring quality.
- * But, setting this too high could result in increased monitoring overhead.
- * Please refer to the DAMON documentation for more detail. 10 by default.
- */
-module_param_named(min_nr_regions, damon_reclaim_mon_attrs.min_nr_regions,
- ulong, 0600);
-
-/*
- * Maximum number of monitoring regions.
- *
- * The maximum number of monitoring regions of DAMON for the cold memory
- * monitoring. This can be used to set upper-bound of the monitoring overhead.
- * However, setting this too low could result in bad monitoring quality.
- * Please refer to the DAMON documentation for more detail. 1000 by default.
- */
-module_param_named(max_nr_regions, damon_reclaim_mon_attrs.max_nr_regions,
- ulong, 0600);
+DEFINE_DAMON_MODULES_MON_ATTRS_PARAMS(damon_reclaim_mon_attrs);
/*
* Start of the target memory region in physical address.
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 12/22] mm/damon/modules-common: implement a watermarks module parameters generator macro
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (10 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 11/22] mm/damon/reclaim: use monitoring attributes parameters generator macro SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 13/22] mm/damon/lru_sort: use watermarks " SeongJae Park
` (9 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
DAMON_RECLAIM and DAMON_LRU_SORT have module parameters for watermarks
that having same names. This commit implements a macro for generating
such module parameters so that we can reuse later.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/modules-common.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/mm/damon/modules-common.h b/mm/damon/modules-common.h
index 0abd0636bc64..1370590a37d1 100644
--- a/mm/damon/modules-common.h
+++ b/mm/damon/modules-common.h
@@ -16,3 +16,10 @@
0600); \
module_param_named(max_nr_regions, attrs.max_nr_regions, ulong, \
0600);
+
+#define DEFINE_DAMON_MODULES_WMARKS_PARAMS(wmarks) \
+ module_param_named(wmarks_interval, wmarks->interval, ulong, \
+ 0600); \
+ module_param_named(wmarks_high, wmarks.high, ulong, 0600); \
+ module_param_named(wmarks_mid, wmarks.mid, ulong, 0600); \
+ module_param_named(wmarks_low, wmarks.lowulong, 0600);
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 13/22] mm/damon/lru_sort: use watermarks parameters generator macro
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (11 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 12/22] mm/damon/modules-common: implement a watermarks module " SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 14/22] mm/damon/reclaim: " SeongJae Park
` (8 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
This commit makes DAMON_LRU_SORT to generate the module parameters for
DAMOS watermarks using the generator macro to simplify the code and
reduce duplicates.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/lru_sort.c | 64 ++++++---------------------------------
mm/damon/modules-common.h | 4 +--
2 files changed, 12 insertions(+), 56 deletions(-)
diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c
index e95626acee6f..20760b39b50a 100644
--- a/mm/damon/lru_sort.c
+++ b/mm/damon/lru_sort.c
@@ -90,44 +90,14 @@ module_param(quota_ms, ulong, 0600);
static unsigned long quota_reset_interval_ms __read_mostly = 1000;
module_param(quota_reset_interval_ms, ulong, 0600);
-/*
- * The watermarks check time interval in microseconds.
- *
- * Minimal time to wait before checking the watermarks, when DAMON_LRU_SORT is
- * enabled but inactive due to its watermarks rule. 5 seconds by default.
- */
-static unsigned long wmarks_interval __read_mostly = 5000000;
-module_param(wmarks_interval, ulong, 0600);
-
-/*
- * Free memory rate (per thousand) for the high watermark.
- *
- * If free memory of the system in bytes per thousand bytes is higher than
- * this, DAMON_LRU_SORT becomes inactive, so it does nothing but periodically
- * checks the watermarks. 200 (20%) by default.
- */
-static unsigned long wmarks_high __read_mostly = 200;
-module_param(wmarks_high, ulong, 0600);
-
-/*
- * Free memory rate (per thousand) for the middle watermark.
- *
- * If free memory of the system in bytes per thousand bytes is between this and
- * the low watermark, DAMON_LRU_SORT becomes active, so starts the monitoring
- * and the LRU-lists sorting. 150 (15%) by default.
- */
-static unsigned long wmarks_mid __read_mostly = 150;
-module_param(wmarks_mid, ulong, 0600);
-
-/*
- * Free memory rate (per thousand) for the low watermark.
- *
- * If free memory of the system in bytes per thousand bytes is lower than this,
- * DAMON_LRU_SORT becomes inactive, so it does nothing but periodically checks
- * the watermarks. 50 (5%) by default.
- */
-static unsigned long wmarks_low __read_mostly = 50;
-module_param(wmarks_low, ulong, 0600);
+struct damos_watermarks damon_lru_sort_wmarks = {
+ .metric = DAMOS_WMARK_FREE_MEM_RATE,
+ .interval = 5000000, /* 5 seconds */
+ .high = 200, /* 20 percent */
+ .mid = 150, /* 15 percent */
+ .low = 50, /* 5 percent */
+};
+DEFINE_DAMON_MODULES_WMARKS_PARAMS(damon_lru_sort_wmarks);
static struct damon_attrs damon_lru_sort_mon_attrs = {
.sample_interval = 5000, /* 5 ms */
@@ -242,13 +212,6 @@ static struct damos *damon_lru_sort_new_hot_scheme(unsigned int hot_thres)
.min_age_region = 0,
.max_age_region = UINT_MAX,
};
- struct damos_watermarks wmarks = {
- .metric = DAMOS_WMARK_FREE_MEM_RATE,
- .interval = wmarks_interval,
- .high = wmarks_high,
- .mid = wmarks_mid,
- .low = wmarks_low,
- };
struct damos_quota quota = {
/*
* Do not try LRU-lists sorting of hot pages for more than half
@@ -270,7 +233,7 @@ static struct damos *damon_lru_sort_new_hot_scheme(unsigned int hot_thres)
/* under the quota. */
"a,
/* (De)activate this according to the watermarks. */
- &wmarks);
+ &damon_lru_sort_wmarks);
}
/* Create a DAMON-based operation scheme for cold memory regions */
@@ -287,13 +250,6 @@ static struct damos *damon_lru_sort_new_cold_scheme(unsigned int cold_thres)
.min_age_region = cold_thres,
.max_age_region = UINT_MAX,
};
- struct damos_watermarks wmarks = {
- .metric = DAMOS_WMARK_FREE_MEM_RATE,
- .interval = wmarks_interval,
- .high = wmarks_high,
- .mid = wmarks_mid,
- .low = wmarks_low,
- };
struct damos_quota quota = {
/*
* Do not try LRU-lists sorting of cold pages for more than
@@ -316,7 +272,7 @@ static struct damos *damon_lru_sort_new_cold_scheme(unsigned int cold_thres)
/* under the quota. */
"a,
/* (De)activate this according to the watermarks. */
- &wmarks);
+ &damon_lru_sort_wmarks);
}
static int damon_lru_sort_apply_parameters(void)
diff --git a/mm/damon/modules-common.h b/mm/damon/modules-common.h
index 1370590a37d1..4c2ce84869d5 100644
--- a/mm/damon/modules-common.h
+++ b/mm/damon/modules-common.h
@@ -18,8 +18,8 @@
0600);
#define DEFINE_DAMON_MODULES_WMARKS_PARAMS(wmarks) \
- module_param_named(wmarks_interval, wmarks->interval, ulong, \
+ module_param_named(wmarks_interval, wmarks.interval, ulong, \
0600); \
module_param_named(wmarks_high, wmarks.high, ulong, 0600); \
module_param_named(wmarks_mid, wmarks.mid, ulong, 0600); \
- module_param_named(wmarks_low, wmarks.lowulong, 0600);
+ module_param_named(wmarks_low, wmarks.low, ulong, 0600);
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 14/22] mm/damon/reclaim: use watermarks parameters generator macro
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (12 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 13/22] mm/damon/lru_sort: use watermarks " SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 15/22] mm/damon/modules-common: implement a stats " SeongJae Park
` (7 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
This commit makes DAMON_RECLAIM to generate the module parameters for
DAMOS watermarks using the generator macro to simplify the code and
reduce duplicates.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/reclaim.c | 56 ++++++++--------------------------------------
1 file changed, 9 insertions(+), 47 deletions(-)
diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c
index 48326bef20f5..7f845f617dc5 100644
--- a/mm/damon/reclaim.c
+++ b/mm/damon/reclaim.c
@@ -91,45 +91,14 @@ module_param(quota_sz, ulong, 0600);
static unsigned long quota_reset_interval_ms __read_mostly = 1000;
module_param(quota_reset_interval_ms, ulong, 0600);
-/*
- * The watermarks check time interval in microseconds.
- *
- * Minimal time to wait before checking the watermarks, when DAMON_RECLAIM is
- * enabled but inactive due to its watermarks rule. 5 seconds by default.
- */
-static unsigned long wmarks_interval __read_mostly = 5000000;
-module_param(wmarks_interval, ulong, 0600);
-
-/*
- * Free memory rate (per thousand) for the high watermark.
- *
- * If free memory of the system in bytes per thousand bytes is higher than
- * this, DAMON_RECLAIM becomes inactive, so it does nothing but periodically
- * checks the watermarks. 500 (50%) by default.
- */
-static unsigned long wmarks_high __read_mostly = 500;
-module_param(wmarks_high, ulong, 0600);
-
-/*
- * Free memory rate (per thousand) for the middle watermark.
- *
- * If free memory of the system in bytes per thousand bytes is between this and
- * the low watermark, DAMON_RECLAIM becomes active, so starts the monitoring
- * and the reclaiming. 400 (40%) by default.
- */
-static unsigned long wmarks_mid __read_mostly = 400;
-module_param(wmarks_mid, ulong, 0600);
-
-/*
- * Free memory rate (per thousand) for the low watermark.
- *
- * If free memory of the system in bytes per thousand bytes is lower than this,
- * DAMON_RECLAIM becomes inactive, so it does nothing but periodically checks
- * the watermarks. In the case, the system falls back to the LRU-based page
- * granularity reclamation logic. 200 (20%) by default.
- */
-static unsigned long wmarks_low __read_mostly = 200;
-module_param(wmarks_low, ulong, 0600);
+struct damos_watermarks damon_reclaim_wmarks = {
+ .metric = DAMOS_WMARK_FREE_MEM_RATE,
+ .interval = 5000000, /* 5 seconds */
+ .high = 500, /* 50 percent */
+ .mid = 400, /* 40 percent */
+ .low = 200, /* 20 percent */
+};
+DEFINE_DAMON_MODULES_WMARKS_PARAMS(damon_reclaim_wmarks);
static struct damon_attrs damon_reclaim_mon_attrs = {
.sample_interval = 5000, /* 5 ms */
@@ -214,13 +183,6 @@ static struct damos *damon_reclaim_new_scheme(void)
damon_reclaim_mon_attrs.aggr_interval,
.max_age_region = UINT_MAX,
};
- struct damos_watermarks wmarks = {
- .metric = DAMOS_WMARK_FREE_MEM_RATE,
- .interval = wmarks_interval,
- .high = wmarks_high,
- .mid = wmarks_mid,
- .low = wmarks_low,
- };
struct damos_quota quota = {
/*
* Do not try reclamation for more than quota_ms milliseconds
@@ -242,7 +204,7 @@ static struct damos *damon_reclaim_new_scheme(void)
/* under the quota. */
"a,
/* (De)activate this according to the watermarks. */
- &wmarks);
+ &damon_reclaim_wmarks);
}
static int damon_reclaim_apply_parameters(void)
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 15/22] mm/damon/modules-common: implement a stats parameters generator macro
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (13 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 14/22] mm/damon/reclaim: " SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 16/22] mm/damon/reclaim: use stat parameters generator SeongJae Park
` (6 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
DAMON_RECLAIM and DAMON_LRU_SORT have module parameters for DAMOS
statistics that having same names. This commit implements a macro for
generating such module parameters so that we can reuse later.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/modules-common.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/mm/damon/modules-common.h b/mm/damon/modules-common.h
index 4c2ce84869d5..ed973e0770ae 100644
--- a/mm/damon/modules-common.h
+++ b/mm/damon/modules-common.h
@@ -23,3 +23,15 @@
module_param_named(wmarks_high, wmarks.high, ulong, 0600); \
module_param_named(wmarks_mid, wmarks.mid, ulong, 0600); \
module_param_named(wmarks_low, wmarks.low, ulong, 0600);
+
+#define DEFINE_DAMON_MODULES_DAMOS_STATS_PARAMS(stat, try_name, \
+ succ_name, qt_exceed_name) \
+ module_param_named(nr_##try_name, stat.nr_tried, ulong, 0400); \
+ module_param_named(bytes_##try_name, stat.sz_tried, ulong, \
+ 0400); \
+ module_param_named(nr_##succ_name, stat.nr_applied, ulong, \
+ 0400); \
+ module_param_named(bytes_##succ_name, stat.sz_applied, ulong, \
+ 0400); \
+ module_param_named(qt_exceed_name, stat.qt_exceeds, ulong, \
+ 0400);
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 16/22] mm/damon/reclaim: use stat parameters generator
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (14 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 15/22] mm/damon/modules-common: implement a stats " SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 17/22] mm/damon/lru_sort: use stat generator SeongJae Park
` (5 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
This commit makes DAMON_RECLAIM to generate the module parameters for
DAMOS statistics using the generator macro to simplify the code and
reduce duplicates.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/reclaim.c | 41 +++++------------------------------------
1 file changed, 5 insertions(+), 36 deletions(-)
diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c
index 7f845f617dc5..1ef8353ac15a 100644
--- a/mm/damon/reclaim.c
+++ b/mm/damon/reclaim.c
@@ -136,35 +136,9 @@ module_param(monitor_region_end, ulong, 0600);
static int kdamond_pid __read_mostly = -1;
module_param(kdamond_pid, int, 0400);
-/*
- * Number of memory regions that tried to be reclaimed.
- */
-static unsigned long nr_reclaim_tried_regions __read_mostly;
-module_param(nr_reclaim_tried_regions, ulong, 0400);
-
-/*
- * Total bytes of memory regions that tried to be reclaimed.
- */
-static unsigned long bytes_reclaim_tried_regions __read_mostly;
-module_param(bytes_reclaim_tried_regions, ulong, 0400);
-
-/*
- * Number of memory regions that successfully be reclaimed.
- */
-static unsigned long nr_reclaimed_regions __read_mostly;
-module_param(nr_reclaimed_regions, ulong, 0400);
-
-/*
- * Total bytes of memory regions that successfully be reclaimed.
- */
-static unsigned long bytes_reclaimed_regions __read_mostly;
-module_param(bytes_reclaimed_regions, ulong, 0400);
-
-/*
- * Number of times that the time/space quota limits have exceeded
- */
-static unsigned long nr_quota_exceeds __read_mostly;
-module_param(nr_quota_exceeds, ulong, 0400);
+static struct damos_stat damon_reclaim_stat;
+DEFINE_DAMON_MODULES_DAMOS_STATS_PARAMS(damon_reclaim_stat,
+ reclaim_tried_regions, reclaimed_regions, quota_exceeds);
static struct damon_ctx *ctx;
static struct damon_target *target;
@@ -318,13 +292,8 @@ static int damon_reclaim_after_aggregation(struct damon_ctx *c)
struct damos *s;
/* update the stats parameter */
- damon_for_each_scheme(s, c) {
- nr_reclaim_tried_regions = s->stat.nr_tried;
- bytes_reclaim_tried_regions = s->stat.sz_tried;
- nr_reclaimed_regions = s->stat.nr_applied;
- bytes_reclaimed_regions = s->stat.sz_applied;
- nr_quota_exceeds = s->stat.qt_exceeds;
- }
+ damon_for_each_scheme(s, c)
+ damon_reclaim_stat = s->stat;
return damon_reclaim_handle_commit_inputs();
}
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 17/22] mm/damon/lru_sort: use stat generator
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (15 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 16/22] mm/damon/reclaim: use stat parameters generator SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 18/22] mm/damon/modules-common: implement a damos quota params generator SeongJae Park
` (4 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
This commit makes DAMON_LRU_SORT to generate the module parameters for
DAMOS statistics using the generator macro to simplify the code and
reduce duplicates.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/lru_sort.c | 83 +++++++--------------------------------------
1 file changed, 12 insertions(+), 71 deletions(-)
diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c
index 20760b39b50a..13a752aed272 100644
--- a/mm/damon/lru_sort.c
+++ b/mm/damon/lru_sort.c
@@ -135,65 +135,15 @@ module_param(monitor_region_end, ulong, 0600);
static int kdamond_pid __read_mostly = -1;
module_param(kdamond_pid, int, 0400);
-/*
- * Number of hot memory regions that tried to be LRU-sorted.
- */
-static unsigned long nr_lru_sort_tried_hot_regions __read_mostly;
-module_param(nr_lru_sort_tried_hot_regions, ulong, 0400);
-
-/*
- * Total bytes of hot memory regions that tried to be LRU-sorted.
- */
-static unsigned long bytes_lru_sort_tried_hot_regions __read_mostly;
-module_param(bytes_lru_sort_tried_hot_regions, ulong, 0400);
-
-/*
- * Number of hot memory regions that successfully be LRU-sorted.
- */
-static unsigned long nr_lru_sorted_hot_regions __read_mostly;
-module_param(nr_lru_sorted_hot_regions, ulong, 0400);
-
-/*
- * Total bytes of hot memory regions that successfully be LRU-sorted.
- */
-static unsigned long bytes_lru_sorted_hot_regions __read_mostly;
-module_param(bytes_lru_sorted_hot_regions, ulong, 0400);
-
-/*
- * Number of times that the time quota limit for hot regions have exceeded
- */
-static unsigned long nr_hot_quota_exceeds __read_mostly;
-module_param(nr_hot_quota_exceeds, ulong, 0400);
+static struct damos_stat damon_lru_sort_hot_stat;
+DEFINE_DAMON_MODULES_DAMOS_STATS_PARAMS(damon_lru_sort_hot_stat,
+ lru_sort_tried_hot_regions, lru_sorted_hot_regions,
+ hot_quota_exceeds);
-/*
- * Number of cold memory regions that tried to be LRU-sorted.
- */
-static unsigned long nr_lru_sort_tried_cold_regions __read_mostly;
-module_param(nr_lru_sort_tried_cold_regions, ulong, 0400);
-
-/*
- * Total bytes of cold memory regions that tried to be LRU-sorted.
- */
-static unsigned long bytes_lru_sort_tried_cold_regions __read_mostly;
-module_param(bytes_lru_sort_tried_cold_regions, ulong, 0400);
-
-/*
- * Number of cold memory regions that successfully be LRU-sorted.
- */
-static unsigned long nr_lru_sorted_cold_regions __read_mostly;
-module_param(nr_lru_sorted_cold_regions, ulong, 0400);
-
-/*
- * Total bytes of cold memory regions that successfully be LRU-sorted.
- */
-static unsigned long bytes_lru_sorted_cold_regions __read_mostly;
-module_param(bytes_lru_sorted_cold_regions, ulong, 0400);
-
-/*
- * Number of times that the time quota limit for cold regions have exceeded
- */
-static unsigned long nr_cold_quota_exceeds __read_mostly;
-module_param(nr_cold_quota_exceeds, ulong, 0400);
+static struct damos_stat damon_lru_sort_cold_stat;
+DEFINE_DAMON_MODULES_DAMOS_STATS_PARAMS(damon_lru_sort_cold_stat,
+ lru_sort_tried_cold_regions, lru_sorted_cold_regions,
+ cold_quota_exceeds);
static struct damon_ctx *ctx;
static struct damon_target *target;
@@ -397,19 +347,10 @@ static int damon_lru_sort_after_aggregation(struct damon_ctx *c)
/* update the stats parameter */
damon_for_each_scheme(s, c) {
- if (s->action == DAMOS_LRU_PRIO) {
- nr_lru_sort_tried_hot_regions = s->stat.nr_tried;
- bytes_lru_sort_tried_hot_regions = s->stat.sz_tried;
- nr_lru_sorted_hot_regions = s->stat.nr_applied;
- bytes_lru_sorted_hot_regions = s->stat.sz_applied;
- nr_hot_quota_exceeds = s->stat.qt_exceeds;
- } else if (s->action == DAMOS_LRU_DEPRIO) {
- nr_lru_sort_tried_cold_regions = s->stat.nr_tried;
- bytes_lru_sort_tried_cold_regions = s->stat.sz_tried;
- nr_lru_sorted_cold_regions = s->stat.nr_applied;
- bytes_lru_sorted_cold_regions = s->stat.sz_applied;
- nr_cold_quota_exceeds = s->stat.qt_exceeds;
- }
+ if (s->action == DAMOS_LRU_PRIO)
+ damon_lru_sort_hot_stat = s->stat;
+ else if (s->action == DAMOS_LRU_DEPRIO)
+ damon_lru_sort_cold_stat = s->stat;
}
return damon_lru_sort_handle_commit_inputs();
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 18/22] mm/damon/modules-common: implement a damos quota params generator
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (16 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 17/22] mm/damon/lru_sort: use stat generator SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 19/22] mm/damon/modules-common: implement damos time " SeongJae Park
` (3 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
DAMON_RECLAIM and DAMON_LRU_SORT have module parameters for DAMOS quotas
that having same names. This commit implements a macro for generating
such module parameters so that we can reuse later.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/modules-common.h | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/mm/damon/modules-common.h b/mm/damon/modules-common.h
index ed973e0770ae..3e99810b4689 100644
--- a/mm/damon/modules-common.h
+++ b/mm/damon/modules-common.h
@@ -17,6 +17,12 @@
module_param_named(max_nr_regions, attrs.max_nr_regions, ulong, \
0600);
+#define DEFINE_DAMON_MODULES_DAMOS_QUOTAS(quota) \
+ module_param_named(quota_ms, quota.ms, ulong, 0600); \
+ module_param_named(quota_sz, quota.sz, ulong, 0600); \
+ module_param_named(quota_reset_interval_ms, \
+ quota.reset_interval, ulong, 0600);
+
#define DEFINE_DAMON_MODULES_WMARKS_PARAMS(wmarks) \
module_param_named(wmarks_interval, wmarks.interval, ulong, \
0600); \
@@ -33,5 +39,5 @@
0400); \
module_param_named(bytes_##succ_name, stat.sz_applied, ulong, \
0400); \
- module_param_named(qt_exceed_name, stat.qt_exceeds, ulong, \
+ module_param_named(nr_##qt_exceed_name, stat.qt_exceeds, ulong, \
0400);
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 19/22] mm/damon/modules-common: implement damos time quota params generator
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (17 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 18/22] mm/damon/modules-common: implement a damos quota params generator SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 20/22] mm/damon/reclaim: use the quota params generator macro SeongJae Park
` (2 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
DAMON_LRU_SORT have module parameters for DAMOS time quota only but size
quota. This commit implements a macro for generating the module
parameters so that we can reuse later.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/modules-common.h | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/mm/damon/modules-common.h b/mm/damon/modules-common.h
index 3e99810b4689..5a4921851d32 100644
--- a/mm/damon/modules-common.h
+++ b/mm/damon/modules-common.h
@@ -17,12 +17,15 @@
module_param_named(max_nr_regions, attrs.max_nr_regions, ulong, \
0600);
-#define DEFINE_DAMON_MODULES_DAMOS_QUOTAS(quota) \
+#define DEFINE_DAMON_MODULES_DAMOS_TIME_QUOTA(quota) \
module_param_named(quota_ms, quota.ms, ulong, 0600); \
- module_param_named(quota_sz, quota.sz, ulong, 0600); \
module_param_named(quota_reset_interval_ms, \
quota.reset_interval, ulong, 0600);
+#define DEFINE_DAMON_MODULES_DAMOS_QUOTAS(quota) \
+ DEFINE_DAMON_MODULES_DAMOS_TIME_QUOTA(quota) \
+ module_param_named(quota_sz, quota.sz, ulong, 0600);
+
#define DEFINE_DAMON_MODULES_WMARKS_PARAMS(wmarks) \
module_param_named(wmarks_interval, wmarks.interval, ulong, \
0600); \
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 20/22] mm/damon/reclaim: use the quota params generator macro
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (18 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 19/22] mm/damon/modules-common: implement damos time " SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 21/22] mm/damon/lru_sort: use quotas param generator SeongJae Park
2022-09-13 17:44 ` [PATCH 22/22] mm/damon/lru_sort: deduplicate hot/cold schemes generators SeongJae Park
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
This commit makes DAMON_RECLAIM to generate the module parameters for
DAMOS quotas using the generator macro to simplify the code and reduce
duplicates.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/reclaim.c | 64 +++++++++-------------------------------------
1 file changed, 12 insertions(+), 52 deletions(-)
diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c
index 1ef8353ac15a..1acf808e1624 100644
--- a/mm/damon/reclaim.c
+++ b/mm/damon/reclaim.c
@@ -52,44 +52,17 @@ module_param(commit_inputs, bool, 0600);
static unsigned long min_age __read_mostly = 120000000;
module_param(min_age, ulong, 0600);
-/*
- * Limit of time for trying the reclamation in milliseconds.
- *
- * DAMON_RECLAIM tries to use only up to this time within a time window
- * (quota_reset_interval_ms) for trying reclamation of cold pages. This can be
- * used for limiting CPU consumption of DAMON_RECLAIM. If the value is zero,
- * the limit is disabled.
- *
- * 10 ms by default.
- */
-static unsigned long quota_ms __read_mostly = 10;
-module_param(quota_ms, ulong, 0600);
-
-/*
- * Limit of size of memory for the reclamation in bytes.
- *
- * DAMON_RECLAIM charges amount of memory which it tried to reclaim within a
- * time window (quota_reset_interval_ms) and makes no more than this limit is
- * tried. This can be used for limiting consumption of CPU and IO. If this
- * value is zero, the limit is disabled.
- *
- * 128 MiB by default.
- */
-static unsigned long quota_sz __read_mostly = 128 * 1024 * 1024;
-module_param(quota_sz, ulong, 0600);
-
-/*
- * The time/size quota charge reset interval in milliseconds.
- *
- * The charge reset interval for the quota of time (quota_ms) and size
- * (quota_sz). That is, DAMON_RECLAIM does not try reclamation for more than
- * quota_ms milliseconds or quota_sz bytes within quota_reset_interval_ms
- * milliseconds.
- *
- * 1 second by default.
- */
-static unsigned long quota_reset_interval_ms __read_mostly = 1000;
-module_param(quota_reset_interval_ms, ulong, 0600);
+static struct damos_quota damon_reclaim_quota = {
+ /* use up to 10 ms time, reclaim up to 128 MiB per 1 sec by default */
+ .ms = 10,
+ .sz = 128 * 1024 * 1024,
+ .reset_interval = 1000,
+ /* Within the quota, page out older regions first. */
+ .weight_sz = 0,
+ .weight_nr_accesses = 0,
+ .weight_age = 1
+};
+DEFINE_DAMON_MODULES_DAMOS_QUOTAS(damon_reclaim_quota);
struct damos_watermarks damon_reclaim_wmarks = {
.metric = DAMOS_WMARK_FREE_MEM_RATE,
@@ -157,26 +130,13 @@ static struct damos *damon_reclaim_new_scheme(void)
damon_reclaim_mon_attrs.aggr_interval,
.max_age_region = UINT_MAX,
};
- struct damos_quota quota = {
- /*
- * Do not try reclamation for more than quota_ms milliseconds
- * or quota_sz bytes within quota_reset_interval_ms.
- */
- .ms = quota_ms,
- .sz = quota_sz,
- .reset_interval = quota_reset_interval_ms,
- /* Within the quota, page out older regions first. */
- .weight_sz = 0,
- .weight_nr_accesses = 0,
- .weight_age = 1
- };
return damon_new_scheme(
&pattern,
/* page out those, as soon as found */
DAMOS_PAGEOUT,
/* under the quota. */
- "a,
+ &damon_reclaim_quota,
/* (De)activate this according to the watermarks. */
&damon_reclaim_wmarks);
}
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 21/22] mm/damon/lru_sort: use quotas param generator
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (19 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 20/22] mm/damon/reclaim: use the quota params generator macro SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
2022-09-13 17:44 ` [PATCH 22/22] mm/damon/lru_sort: deduplicate hot/cold schemes generators SeongJae Park
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
This commit makes DAMON_LRU_SORT to generate the module parameters for
DAMOS watermarks using the generator macro to simplify the code and
reduce duplicates.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/lru_sort.c | 70 ++++++++++++---------------------------------
1 file changed, 19 insertions(+), 51 deletions(-)
diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c
index 13a752aed272..8d9c3d1fd6be 100644
--- a/mm/damon/lru_sort.c
+++ b/mm/damon/lru_sort.c
@@ -65,30 +65,17 @@ module_param(hot_thres_access_freq, ulong, 0600);
static unsigned long cold_min_age __read_mostly = 120000000;
module_param(cold_min_age, ulong, 0600);
-/*
- * Limit of time for trying the LRU lists sorting in milliseconds.
- *
- * DAMON_LRU_SORT tries to use only up to this time within a time window
- * (quota_reset_interval_ms) for trying LRU lists sorting. This can be used
- * for limiting CPU consumption of DAMON_LRU_SORT. If the value is zero, the
- * limit is disabled.
- *
- * 10 ms by default.
- */
-static unsigned long quota_ms __read_mostly = 10;
-module_param(quota_ms, ulong, 0600);
-
-/*
- * The time quota charge reset interval in milliseconds.
- *
- * The charge reset interval for the quota of time (quota_ms). That is,
- * DAMON_LRU_SORT does not try LRU-lists sorting for more than quota_ms
- * milliseconds or quota_sz bytes within quota_reset_interval_ms milliseconds.
- *
- * 1 second by default.
- */
-static unsigned long quota_reset_interval_ms __read_mostly = 1000;
-module_param(quota_reset_interval_ms, ulong, 0600);
+static struct damos_quota damon_lru_sort_quota = {
+ /* Use up to 10 ms per 1 sec, by default */
+ .ms = 10,
+ .sz = 0,
+ .reset_interval = 1000,
+ /* Within the quota, mark hotter regions accessed first. */
+ .weight_sz = 0,
+ .weight_nr_accesses = 1,
+ .weight_age = 0,
+};
+DEFINE_DAMON_MODULES_DAMOS_TIME_QUOTA(damon_lru_sort_quota);
struct damos_watermarks damon_lru_sort_wmarks = {
.metric = DAMOS_WMARK_FREE_MEM_RATE,
@@ -162,19 +149,10 @@ static struct damos *damon_lru_sort_new_hot_scheme(unsigned int hot_thres)
.min_age_region = 0,
.max_age_region = UINT_MAX,
};
- struct damos_quota quota = {
- /*
- * Do not try LRU-lists sorting of hot pages for more than half
- * of quota_ms milliseconds within quota_reset_interval_ms.
- */
- .ms = quota_ms / 2,
- .sz = 0,
- .reset_interval = quota_reset_interval_ms,
- /* Within the quota, mark hotter regions accessed first. */
- .weight_sz = 0,
- .weight_nr_accesses = 1,
- .weight_age = 0,
- };
+ struct damos_quota quota = damon_lru_sort_quota;
+
+ /* Use half of total quota for hot pages sorting */
+ quota.ms = quota.ms / 2;
return damon_new_scheme(
&pattern,
@@ -200,20 +178,10 @@ static struct damos *damon_lru_sort_new_cold_scheme(unsigned int cold_thres)
.min_age_region = cold_thres,
.max_age_region = UINT_MAX,
};
- struct damos_quota quota = {
- /*
- * Do not try LRU-lists sorting of cold pages for more than
- * half of quota_ms milliseconds within
- * quota_reset_interval_ms.
- */
- .ms = quota_ms / 2,
- .sz = 0,
- .reset_interval = quota_reset_interval_ms,
- /* Within the quota, mark colder regions not accessed first. */
- .weight_sz = 0,
- .weight_nr_accesses = 0,
- .weight_age = 1,
- };
+ struct damos_quota quota = damon_lru_sort_quota;
+
+ /* Use half of total quota for cold pages sorting */
+ quota.ms = quota.ms / 2;
return damon_new_scheme(
&pattern,
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 22/22] mm/damon/lru_sort: deduplicate hot/cold schemes generators
2022-09-13 17:44 [PATCH 00/22] mm/damon: cleanup code SeongJae Park
` (20 preceding siblings ...)
2022-09-13 17:44 ` [PATCH 21/22] mm/damon/lru_sort: use quotas param generator SeongJae Park
@ 2022-09-13 17:44 ` SeongJae Park
21 siblings, 0 replies; 23+ messages in thread
From: SeongJae Park @ 2022-09-13 17:44 UTC (permalink / raw)
To: SeongJae Park, Andrew Morton; +Cc: damon, linux-mm, linux-kernel
damon_lru_sort_new_{hot,cold}_scheme() have quite a lot of duplicates.
This commit factors out the duplicate to a separate function and use it
for reducing the duplicate.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/lru_sort.c | 45 +++++++++++++++++++++------------------------
1 file changed, 21 insertions(+), 24 deletions(-)
diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c
index 8d9c3d1fd6be..07a0908963fd 100644
--- a/mm/damon/lru_sort.c
+++ b/mm/damon/lru_sort.c
@@ -135,6 +135,25 @@ DEFINE_DAMON_MODULES_DAMOS_STATS_PARAMS(damon_lru_sort_cold_stat,
static struct damon_ctx *ctx;
static struct damon_target *target;
+static struct damos *damon_lru_sort_new_scheme(
+ struct damos_access_pattern *pattern, enum damos_action action)
+{
+ struct damos_quota quota = damon_lru_sort_quota;
+
+ /* Use half of total quota for hot/cold pages sorting */
+ quota.ms = quota.ms / 2;
+
+ return damon_new_scheme(
+ /* find the pattern, and */
+ pattern,
+ /* (de)prioritize on LRU-lists */
+ action,
+ /* under the quota. */
+ "a,
+ /* (De)activate this according to the watermarks. */
+ &damon_lru_sort_wmarks);
+}
+
/* Create a DAMON-based operation scheme for hot memory regions */
static struct damos *damon_lru_sort_new_hot_scheme(unsigned int hot_thres)
{
@@ -149,19 +168,8 @@ static struct damos *damon_lru_sort_new_hot_scheme(unsigned int hot_thres)
.min_age_region = 0,
.max_age_region = UINT_MAX,
};
- struct damos_quota quota = damon_lru_sort_quota;
-
- /* Use half of total quota for hot pages sorting */
- quota.ms = quota.ms / 2;
- return damon_new_scheme(
- &pattern,
- /* prioritize those on LRU lists, as soon as found */
- DAMOS_LRU_PRIO,
- /* under the quota. */
- "a,
- /* (De)activate this according to the watermarks. */
- &damon_lru_sort_wmarks);
+ return damon_lru_sort_new_scheme(&pattern, DAMOS_LRU_PRIO);
}
/* Create a DAMON-based operation scheme for cold memory regions */
@@ -178,19 +186,8 @@ static struct damos *damon_lru_sort_new_cold_scheme(unsigned int cold_thres)
.min_age_region = cold_thres,
.max_age_region = UINT_MAX,
};
- struct damos_quota quota = damon_lru_sort_quota;
- /* Use half of total quota for cold pages sorting */
- quota.ms = quota.ms / 2;
-
- return damon_new_scheme(
- &pattern,
- /* mark those as not accessed, as soon as found */
- DAMOS_LRU_DEPRIO,
- /* under the quota. */
- "a,
- /* (De)activate this according to the watermarks. */
- &damon_lru_sort_wmarks);
+ return damon_lru_sort_new_scheme(&pattern, DAMOS_LRU_DEPRIO);
}
static int damon_lru_sort_apply_parameters(void)
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread