Skip to content

Commit f7d911c

Browse files
sjp38torvalds
authored andcommitted
mm/damon: rename damon_primitives to damon_operations
Patch series "Allow DAMON user code independent of monitoring primitives". In-kernel DAMON user code is required to configure the monitoring context (struct damon_ctx) with proper monitoring primitives (struct damon_primitive). This makes the user code dependent to all supporting monitoring primitives. For example, DAMON debugfs interface depends on both DAMON_VADDR and DAMON_PADDR, though some users have interest in only one use case. As more monitoring primitives are introduced, the problem will be bigger. To minimize such unnecessary dependency, this patchset makes monitoring primitives can be registered by the implemnting code and later dynamically searched and selected by the user code. In addition to that, this patchset renames monitoring primitives to monitoring operations, which is more easy to intuitively understand what it means and how it would be structed. This patch (of 8): DAMON has a set of callback functions called monitoring primitives and let it can be configured with various implementations for easy extension for different address spaces and usages. However, the word 'primitive' is not so explicit. Meanwhile, many other structs resembles similar purpose calls themselves 'operations'. To make the code easier to be understood, this commit renames 'damon_primitives' to 'damon_operations' before it is too late to rename. Link: https://lkml.kernel.org/r/20220215184603.1479-1-sj@kernel.org Link: https://lkml.kernel.org/r/20220215184603.1479-2-sj@kernel.org Signed-off-by: SeongJae Park <sj@kernel.org> Cc: Xin Hao <xhao@linux.alibaba.com> Cc: David Rientjes <rientjes@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 242e10a commit f7d911c

12 files changed

Lines changed: 96 additions & 95 deletions

File tree

include/linux/damon.h

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ struct damon_region {
6767
*
6868
* Each monitoring context could have multiple targets. For example, a context
6969
* for virtual memory address spaces could have multiple target processes. The
70-
* @pid should be set for appropriate address space monitoring primitives
71-
* including the virtual address spaces monitoring primitives.
70+
* @pid should be set for appropriate &struct damon_operations including the
71+
* virtual address spaces monitoring operations.
7272
*/
7373
struct damon_target {
7474
struct pid *pid;
@@ -120,9 +120,9 @@ enum damos_action {
120120
* uses smaller one as the effective quota.
121121
*
122122
* For selecting regions within the quota, DAMON prioritizes current scheme's
123-
* target memory regions using the &struct damon_primitive->get_scheme_score.
123+
* target memory regions using the &struct damon_operations->get_scheme_score.
124124
* You could customize the prioritization logic by setting &weight_sz,
125-
* &weight_nr_accesses, and &weight_age, because monitoring primitives are
125+
* &weight_nr_accesses, and &weight_age, because monitoring operations are
126126
* encouraged to respect those.
127127
*/
128128
struct damos_quota {
@@ -256,10 +256,10 @@ struct damos {
256256
struct damon_ctx;
257257

258258
/**
259-
* struct damon_primitive - Monitoring primitives for given use cases.
259+
* struct damon_operations - Monitoring operations for given use cases.
260260
*
261-
* @init: Initialize primitive-internal data structures.
262-
* @update: Update primitive-internal data structures.
261+
* @init: Initialize operations-related data structures.
262+
* @update: Update operations-related data structures.
263263
* @prepare_access_checks: Prepare next access check of target regions.
264264
* @check_accesses: Check the accesses to target regions.
265265
* @reset_aggregated: Reset aggregated accesses monitoring results.
@@ -269,18 +269,18 @@ struct damon_ctx;
269269
* @cleanup: Clean up the context.
270270
*
271271
* DAMON can be extended for various address spaces and usages. For this,
272-
* users should register the low level primitives for their target address
273-
* space and usecase via the &damon_ctx.primitive. Then, the monitoring thread
272+
* users should register the low level operations for their target address
273+
* space and usecase via the &damon_ctx.ops. Then, the monitoring thread
274274
* (&damon_ctx.kdamond) calls @init and @prepare_access_checks before starting
275-
* the monitoring, @update after each &damon_ctx.primitive_update_interval, and
275+
* the monitoring, @update after each &damon_ctx.ops_update_interval, and
276276
* @check_accesses, @target_valid and @prepare_access_checks after each
277277
* &damon_ctx.sample_interval. Finally, @reset_aggregated is called after each
278278
* &damon_ctx.aggr_interval.
279279
*
280-
* @init should initialize primitive-internal data structures. For example,
280+
* @init should initialize operations-related data structures. For example,
281281
* this could be used to construct proper monitoring target regions and link
282282
* those to @damon_ctx.adaptive_targets.
283-
* @update should update the primitive-internal data structures. For example,
283+
* @update should update the operations-related data structures. For example,
284284
* this could be used to update monitoring target regions for current status.
285285
* @prepare_access_checks should manipulate the monitoring regions to be
286286
* prepared for the next access check.
@@ -300,7 +300,7 @@ struct damon_ctx;
300300
* monitoring.
301301
* @cleanup is called from @kdamond just before its termination.
302302
*/
303-
struct damon_primitive {
303+
struct damon_operations {
304304
void (*init)(struct damon_ctx *context);
305305
void (*update)(struct damon_ctx *context);
306306
void (*prepare_access_checks)(struct damon_ctx *context);
@@ -354,15 +354,15 @@ struct damon_callback {
354354
*
355355
* @sample_interval: The time between access samplings.
356356
* @aggr_interval: The time between monitor results aggregations.
357-
* @primitive_update_interval: The time between monitoring primitive updates.
357+
* @ops_update_interval: The time between monitoring operations updates.
358358
*
359359
* For each @sample_interval, DAMON checks whether each region is accessed or
360360
* not. It aggregates and keeps the access information (number of accesses to
361361
* each region) for @aggr_interval time. DAMON also checks whether the target
362362
* memory regions need update (e.g., by ``mmap()`` calls from the application,
363363
* in case of virtual memory monitoring) and applies the changes for each
364-
* @primitive_update_interval. All time intervals are in micro-seconds.
365-
* Please refer to &struct damon_primitive and &struct damon_callback for more
364+
* @ops_update_interval. All time intervals are in micro-seconds.
365+
* Please refer to &struct damon_operations and &struct damon_callback for more
366366
* detail.
367367
*
368368
* @kdamond: Kernel thread who does the monitoring.
@@ -374,7 +374,7 @@ struct damon_callback {
374374
*
375375
* Once started, the monitoring thread runs until explicitly required to be
376376
* terminated or every monitoring target is invalid. The validity of the
377-
* targets is checked via the &damon_primitive.target_valid of @primitive. The
377+
* targets is checked via the &damon_operations.target_valid of @ops. The
378378
* termination can also be explicitly requested by writing non-zero to
379379
* @kdamond_stop. The thread sets @kdamond to NULL when it terminates.
380380
* Therefore, users can know whether the monitoring is ongoing or terminated by
@@ -384,7 +384,7 @@ struct damon_callback {
384384
* Note that the monitoring thread protects only @kdamond and @kdamond_stop via
385385
* @kdamond_lock. Accesses to other fields must be protected by themselves.
386386
*
387-
* @primitive: Set of monitoring primitives for given use cases.
387+
* @ops: Set of monitoring operations for given use cases.
388388
* @callback: Set of callbacks for monitoring events notifications.
389389
*
390390
* @min_nr_regions: The minimum number of adaptive monitoring regions.
@@ -395,17 +395,17 @@ struct damon_callback {
395395
struct damon_ctx {
396396
unsigned long sample_interval;
397397
unsigned long aggr_interval;
398-
unsigned long primitive_update_interval;
398+
unsigned long ops_update_interval;
399399

400400
/* private: internal use only */
401401
struct timespec64 last_aggregation;
402-
struct timespec64 last_primitive_update;
402+
struct timespec64 last_ops_update;
403403

404404
/* public: */
405405
struct task_struct *kdamond;
406406
struct mutex kdamond_lock;
407407

408-
struct damon_primitive primitive;
408+
struct damon_operations ops;
409409
struct damon_callback callback;
410410

411411
unsigned long min_nr_regions;
@@ -484,7 +484,7 @@ unsigned int damon_nr_regions(struct damon_target *t);
484484
struct damon_ctx *damon_new_ctx(void);
485485
void damon_destroy_ctx(struct damon_ctx *ctx);
486486
int damon_set_attrs(struct damon_ctx *ctx, unsigned long sample_int,
487-
unsigned long aggr_int, unsigned long primitive_upd_int,
487+
unsigned long aggr_int, unsigned long ops_upd_int,
488488
unsigned long min_nr_reg, unsigned long max_nr_reg);
489489
int damon_set_schemes(struct damon_ctx *ctx,
490490
struct damos **schemes, ssize_t nr_schemes);
@@ -497,12 +497,12 @@ int damon_stop(struct damon_ctx **ctxs, int nr_ctxs);
497497

498498
#ifdef CONFIG_DAMON_VADDR
499499
bool damon_va_target_valid(void *t);
500-
void damon_va_set_primitives(struct damon_ctx *ctx);
500+
void damon_va_set_operations(struct damon_ctx *ctx);
501501
#endif /* CONFIG_DAMON_VADDR */
502502

503503
#ifdef CONFIG_DAMON_PADDR
504504
bool damon_pa_target_valid(void *t);
505-
void damon_pa_set_primitives(struct damon_ctx *ctx);
505+
void damon_pa_set_operations(struct damon_ctx *ctx);
506506
#endif /* CONFIG_DAMON_PADDR */
507507

508508
#endif /* _DAMON_H */

mm/damon/Kconfig

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,27 @@ config DAMON_KUNIT_TEST
2525
If unsure, say N.
2626

2727
config DAMON_VADDR
28-
bool "Data access monitoring primitives for virtual address spaces"
28+
bool "Data access monitoring operations for virtual address spaces"
2929
depends on DAMON && MMU
3030
select PAGE_IDLE_FLAG
3131
help
32-
This builds the default data access monitoring primitives for DAMON
32+
This builds the default data access monitoring operations for DAMON
3333
that work for virtual address spaces.
3434

3535
config DAMON_PADDR
36-
bool "Data access monitoring primitives for the physical address space"
36+
bool "Data access monitoring operations for the physical address space"
3737
depends on DAMON && MMU
3838
select PAGE_IDLE_FLAG
3939
help
40-
This builds the default data access monitoring primitives for DAMON
40+
This builds the default data access monitoring operations for DAMON
4141
that works for the physical address space.
4242

4343
config DAMON_VADDR_KUNIT_TEST
44-
bool "Test for DAMON primitives" if !KUNIT_ALL_TESTS
44+
bool "Test for DAMON operations" if !KUNIT_ALL_TESTS
4545
depends on DAMON_VADDR && KUNIT=y
4646
default KUNIT_ALL_TESTS
4747
help
48-
This builds the DAMON virtual addresses primitives Kunit test suite.
48+
This builds the DAMON virtual addresses operations Kunit test suite.
4949

5050
For more information on KUnit and unit tests in general, please refer
5151
to the KUnit documentation.

mm/damon/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-License-Identifier: GPL-2.0
22

33
obj-$(CONFIG_DAMON) := core.o
4-
obj-$(CONFIG_DAMON_VADDR) += prmtv-common.o vaddr.o
5-
obj-$(CONFIG_DAMON_PADDR) += prmtv-common.o paddr.o
4+
obj-$(CONFIG_DAMON_VADDR) += ops-common.o vaddr.o
5+
obj-$(CONFIG_DAMON_PADDR) += ops-common.o paddr.o
66
obj-$(CONFIG_DAMON_DBGFS) += dbgfs.o
77
obj-$(CONFIG_DAMON_RECLAIM) += reclaim.o

mm/damon/core.c

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,10 @@ struct damon_ctx *damon_new_ctx(void)
204204

205205
ctx->sample_interval = 5 * 1000;
206206
ctx->aggr_interval = 100 * 1000;
207-
ctx->primitive_update_interval = 60 * 1000 * 1000;
207+
ctx->ops_update_interval = 60 * 1000 * 1000;
208208

209209
ktime_get_coarse_ts64(&ctx->last_aggregation);
210-
ctx->last_primitive_update = ctx->last_aggregation;
210+
ctx->last_ops_update = ctx->last_aggregation;
211211

212212
mutex_init(&ctx->kdamond_lock);
213213

@@ -224,8 +224,8 @@ static void damon_destroy_targets(struct damon_ctx *ctx)
224224
{
225225
struct damon_target *t, *next_t;
226226

227-
if (ctx->primitive.cleanup) {
228-
ctx->primitive.cleanup(ctx);
227+
if (ctx->ops.cleanup) {
228+
ctx->ops.cleanup(ctx);
229229
return;
230230
}
231231

@@ -250,7 +250,7 @@ void damon_destroy_ctx(struct damon_ctx *ctx)
250250
* @ctx: monitoring context
251251
* @sample_int: time interval between samplings
252252
* @aggr_int: time interval between aggregations
253-
* @primitive_upd_int: time interval between monitoring primitive updates
253+
* @ops_upd_int: time interval between monitoring operations updates
254254
* @min_nr_reg: minimal number of regions
255255
* @max_nr_reg: maximum number of regions
256256
*
@@ -260,7 +260,7 @@ void damon_destroy_ctx(struct damon_ctx *ctx)
260260
* Return: 0 on success, negative error code otherwise.
261261
*/
262262
int damon_set_attrs(struct damon_ctx *ctx, unsigned long sample_int,
263-
unsigned long aggr_int, unsigned long primitive_upd_int,
263+
unsigned long aggr_int, unsigned long ops_upd_int,
264264
unsigned long min_nr_reg, unsigned long max_nr_reg)
265265
{
266266
if (min_nr_reg < 3)
@@ -270,7 +270,7 @@ int damon_set_attrs(struct damon_ctx *ctx, unsigned long sample_int,
270270

271271
ctx->sample_interval = sample_int;
272272
ctx->aggr_interval = aggr_int;
273-
ctx->primitive_update_interval = primitive_upd_int;
273+
ctx->ops_update_interval = ops_upd_int;
274274
ctx->min_nr_regions = min_nr_reg;
275275
ctx->max_nr_regions = max_nr_reg;
276276

@@ -516,10 +516,10 @@ static bool damos_valid_target(struct damon_ctx *c, struct damon_target *t,
516516
{
517517
bool ret = __damos_valid_target(r, s);
518518

519-
if (!ret || !s->quota.esz || !c->primitive.get_scheme_score)
519+
if (!ret || !s->quota.esz || !c->ops.get_scheme_score)
520520
return ret;
521521

522-
return c->primitive.get_scheme_score(c, t, r, s) >= s->quota.min_score;
522+
return c->ops.get_scheme_score(c, t, r, s) >= s->quota.min_score;
523523
}
524524

525525
static void damon_do_apply_schemes(struct damon_ctx *c,
@@ -576,7 +576,7 @@ static void damon_do_apply_schemes(struct damon_ctx *c,
576576
continue;
577577

578578
/* Apply the scheme */
579-
if (c->primitive.apply_scheme) {
579+
if (c->ops.apply_scheme) {
580580
if (quota->esz &&
581581
quota->charged_sz + sz > quota->esz) {
582582
sz = ALIGN_DOWN(quota->esz - quota->charged_sz,
@@ -586,7 +586,7 @@ static void damon_do_apply_schemes(struct damon_ctx *c,
586586
damon_split_region_at(c, t, r, sz);
587587
}
588588
ktime_get_coarse_ts64(&begin);
589-
sz_applied = c->primitive.apply_scheme(c, t, r, s);
589+
sz_applied = c->ops.apply_scheme(c, t, r, s);
590590
ktime_get_coarse_ts64(&end);
591591
quota->total_charged_ns += timespec64_to_ns(&end) -
592592
timespec64_to_ns(&begin);
@@ -660,7 +660,7 @@ static void kdamond_apply_schemes(struct damon_ctx *c)
660660
damos_set_effective_quota(quota);
661661
}
662662

663-
if (!c->primitive.get_scheme_score)
663+
if (!c->ops.get_scheme_score)
664664
continue;
665665

666666
/* Fill up the score histogram */
@@ -669,7 +669,7 @@ static void kdamond_apply_schemes(struct damon_ctx *c)
669669
damon_for_each_region(r, t) {
670670
if (!__damos_valid_target(r, s))
671671
continue;
672-
score = c->primitive.get_scheme_score(
672+
score = c->ops.get_scheme_score(
673673
c, t, r, s);
674674
quota->histogram[score] +=
675675
r->ar.end - r->ar.start;
@@ -848,14 +848,15 @@ static void kdamond_split_regions(struct damon_ctx *ctx)
848848
}
849849

850850
/*
851-
* Check whether it is time to check and apply the target monitoring regions
851+
* Check whether it is time to check and apply the operations-related data
852+
* structures.
852853
*
853854
* Returns true if it is.
854855
*/
855-
static bool kdamond_need_update_primitive(struct damon_ctx *ctx)
856+
static bool kdamond_need_update_operations(struct damon_ctx *ctx)
856857
{
857-
return damon_check_reset_time_interval(&ctx->last_primitive_update,
858-
ctx->primitive_update_interval);
858+
return damon_check_reset_time_interval(&ctx->last_ops_update,
859+
ctx->ops_update_interval);
859860
}
860861

861862
/*
@@ -873,11 +874,11 @@ static bool kdamond_need_stop(struct damon_ctx *ctx)
873874
if (kthread_should_stop())
874875
return true;
875876

876-
if (!ctx->primitive.target_valid)
877+
if (!ctx->ops.target_valid)
877878
return false;
878879

879880
damon_for_each_target(t, ctx) {
880-
if (ctx->primitive.target_valid(t))
881+
if (ctx->ops.target_valid(t))
881882
return false;
882883
}
883884

@@ -976,8 +977,8 @@ static int kdamond_fn(void *data)
976977

977978
pr_debug("kdamond (%d) starts\n", current->pid);
978979

979-
if (ctx->primitive.init)
980-
ctx->primitive.init(ctx);
980+
if (ctx->ops.init)
981+
ctx->ops.init(ctx);
981982
if (ctx->callback.before_start && ctx->callback.before_start(ctx))
982983
done = true;
983984

@@ -987,16 +988,16 @@ static int kdamond_fn(void *data)
987988
if (kdamond_wait_activation(ctx))
988989
continue;
989990

990-
if (ctx->primitive.prepare_access_checks)
991-
ctx->primitive.prepare_access_checks(ctx);
991+
if (ctx->ops.prepare_access_checks)
992+
ctx->ops.prepare_access_checks(ctx);
992993
if (ctx->callback.after_sampling &&
993994
ctx->callback.after_sampling(ctx))
994995
done = true;
995996

996997
kdamond_usleep(ctx->sample_interval);
997998

998-
if (ctx->primitive.check_accesses)
999-
max_nr_accesses = ctx->primitive.check_accesses(ctx);
999+
if (ctx->ops.check_accesses)
1000+
max_nr_accesses = ctx->ops.check_accesses(ctx);
10001001

10011002
if (kdamond_aggregate_interval_passed(ctx)) {
10021003
kdamond_merge_regions(ctx,
@@ -1008,13 +1009,13 @@ static int kdamond_fn(void *data)
10081009
kdamond_apply_schemes(ctx);
10091010
kdamond_reset_aggregated(ctx);
10101011
kdamond_split_regions(ctx);
1011-
if (ctx->primitive.reset_aggregated)
1012-
ctx->primitive.reset_aggregated(ctx);
1012+
if (ctx->ops.reset_aggregated)
1013+
ctx->ops.reset_aggregated(ctx);
10131014
}
10141015

1015-
if (kdamond_need_update_primitive(ctx)) {
1016-
if (ctx->primitive.update)
1017-
ctx->primitive.update(ctx);
1016+
if (kdamond_need_update_operations(ctx)) {
1017+
if (ctx->ops.update)
1018+
ctx->ops.update(ctx);
10181019
sz_limit = damon_region_sz_limit(ctx);
10191020
}
10201021
}
@@ -1025,8 +1026,8 @@ static int kdamond_fn(void *data)
10251026

10261027
if (ctx->callback.before_terminate)
10271028
ctx->callback.before_terminate(ctx);
1028-
if (ctx->primitive.cleanup)
1029-
ctx->primitive.cleanup(ctx);
1029+
if (ctx->ops.cleanup)
1030+
ctx->ops.cleanup(ctx);
10301031

10311032
pr_debug("kdamond (%d) finishes\n", current->pid);
10321033
mutex_lock(&ctx->kdamond_lock);

0 commit comments

Comments
 (0)