This patch adds loadable kernel module compilation support for the three DAMON sample modules. While preserving the existing built-in compilation option, the change introduces necessary code exports and configuration updates, enabling these modules to also be built as independent loadable modules. Key modifications include exporting required function symbols from damon/core.c and changing relevant Kconfig options from bool to tristate. This allows users to select between "built-in", "module", and "disabled" configurations. This enhancement provides greater flexibility for both development and deployment. Users can now compile the sample modules as loadable modules and manage them dynamically at runtime without reconfiguration or system reboots. Signed-off-by: Enze Li --- mm/damon/core.c | 18 ++++++++++++++++++ samples/damon/Kconfig | 12 ++++++------ samples/damon/mtier.c | 3 +++ samples/damon/prcl.c | 3 +++ samples/damon/wsse.c | 3 +++ 5 files changed, 33 insertions(+), 6 deletions(-) diff --git a/mm/damon/core.c b/mm/damon/core.c index f9fc0375890a..2e16684e512d 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -108,6 +108,7 @@ int damon_select_ops(struct damon_ctx *ctx, enum damon_ops_id id) mutex_unlock(&damon_ops_lock); return err; } +EXPORT_SYMBOL_GPL(damon_select_ops); /* * Construct a damon_region struct @@ -133,12 +134,14 @@ struct damon_region *damon_new_region(unsigned long start, unsigned long end) return region; } +EXPORT_SYMBOL_GPL(damon_new_region); void damon_add_region(struct damon_region *r, struct damon_target *t) { list_add_tail(&r->list, &t->regions_list); t->nr_regions++; } +EXPORT_SYMBOL_GPL(damon_add_region); static void damon_del_region(struct damon_region *r, struct damon_target *t) { @@ -276,6 +279,7 @@ struct damos_filter *damos_new_filter(enum damos_filter_type type, INIT_LIST_HEAD(&filter->list); return filter; } +EXPORT_SYMBOL_GPL(damos_new_filter); /** * damos_filter_for_ops() - Return if the filter is ops-hndled one. @@ -303,6 +307,7 @@ void damos_add_filter(struct damos *s, struct damos_filter *f) else list_add_tail(&f->list, &s->core_filters); } +EXPORT_SYMBOL_GPL(damos_add_filter); static void damos_del_filter(struct damos_filter *f) { @@ -334,11 +339,13 @@ struct damos_quota_goal *damos_new_quota_goal( INIT_LIST_HEAD(&goal->list); return goal; } +EXPORT_SYMBOL_GPL(damos_new_quota_goal); void damos_add_quota_goal(struct damos_quota *q, struct damos_quota_goal *g) { list_add_tail(&g->list, &q->goals); } +EXPORT_SYMBOL_GPL(damos_add_quota_goal); static void damos_del_quota_goal(struct damos_quota_goal *g) { @@ -409,6 +416,7 @@ struct damos *damon_new_scheme(struct damos_access_pattern *pattern, return scheme; } +EXPORT_SYMBOL_GPL(damon_new_scheme); static void damos_set_next_apply_sis(struct damos *s, struct damon_ctx *ctx) { @@ -478,11 +486,13 @@ struct damon_target *damon_new_target(void) return t; } +EXPORT_SYMBOL_GPL(damon_new_target); void damon_add_target(struct damon_ctx *ctx, struct damon_target *t) { list_add_tail(&t->list, &ctx->adaptive_targets); } +EXPORT_SYMBOL_GPL(damon_add_target); bool damon_targets_empty(struct damon_ctx *ctx) { @@ -553,6 +563,7 @@ struct damon_ctx *damon_new_ctx(void) return ctx; } +EXPORT_SYMBOL_GPL(damon_new_ctx); static void damon_destroy_targets(struct damon_ctx *ctx) { @@ -573,6 +584,7 @@ void damon_destroy_ctx(struct damon_ctx *ctx) kfree(ctx); } +EXPORT_SYMBOL_GPL(damon_destroy_ctx); static bool damon_attrs_equals(const struct damon_attrs *attrs1, const struct damon_attrs *attrs2) @@ -742,6 +754,7 @@ int damon_set_attrs(struct damon_ctx *ctx, struct damon_attrs *attrs) return 0; } +EXPORT_SYMBOL_GPL(damon_set_attrs); /** * damon_set_schemes() - Set data access monitoring based operation schemes. @@ -763,6 +776,7 @@ void damon_set_schemes(struct damon_ctx *ctx, struct damos **schemes, for (i = 0; i < nr_schemes; i++) damon_add_scheme(ctx, schemes[i]); } +EXPORT_SYMBOL_GPL(damon_set_schemes); static struct damos_quota_goal *damos_nth_quota_goal( int n, struct damos_quota *q) @@ -1371,6 +1385,7 @@ int damon_start(struct damon_ctx **ctxs, int nr_ctxs, bool exclusive) return err; } +EXPORT_SYMBOL_GPL(damon_start); /* * __damon_stop() - Stops monitoring of a given context. @@ -1414,6 +1429,7 @@ int damon_stop(struct damon_ctx **ctxs, int nr_ctxs) } return err; } +EXPORT_SYMBOL_GPL(damon_stop); /** * damon_is_running() - Returns if a given DAMON context is running. @@ -1469,6 +1485,7 @@ int damon_call(struct damon_ctx *ctx, struct damon_call_control *control) return -ECANCELED; return 0; } +EXPORT_SYMBOL_GPL(damon_call); /** * damos_walk() - Invoke a given functions while DAMOS walk regions. @@ -2924,6 +2941,7 @@ bool damon_initialized(void) { return damon_region_cache != NULL; } +EXPORT_SYMBOL_GPL(damon_initialized); static int __init damon_init(void) { diff --git a/samples/damon/Kconfig b/samples/damon/Kconfig index cbf96fd8a8bf..87abb8c10926 100644 --- a/samples/damon/Kconfig +++ b/samples/damon/Kconfig @@ -3,8 +3,8 @@ menu "DAMON Samples" config SAMPLE_DAMON_WSSE - bool "DAMON sample module for working set size estimation" - depends on DAMON && DAMON_VADDR + tristate "DAMON sample module for working set size estimation" + depends on DAMON && DAMON_VADDR && m help This builds DAMON sample module for working set size estimation. @@ -15,8 +15,8 @@ config SAMPLE_DAMON_WSSE If unsure, say N. config SAMPLE_DAMON_PRCL - bool "DAMON sample module for access-aware proactive reclamation" - depends on DAMON && DAMON_VADDR + tristate "DAMON sample module for access-aware proactive reclamation" + depends on DAMON && DAMON_VADDR && m help This builds DAMON sample module for access-aware proactive reclamation. @@ -28,8 +28,8 @@ config SAMPLE_DAMON_PRCL If unsure, say N. config SAMPLE_DAMON_MTIER - bool "DAMON sample module for memory tiering" - depends on DAMON && DAMON_PADDR + tristate "DAMON sample module for memory tiering" + depends on DAMON && DAMON_PADDR && m help Thps builds DAMON sample module for memory tierign. diff --git a/samples/damon/mtier.c b/samples/damon/mtier.c index 775838a23d93..3e9efc67a3ea 100644 --- a/samples/damon/mtier.c +++ b/samples/damon/mtier.c @@ -238,3 +238,6 @@ static int __init damon_sample_mtier_init(void) } module_init(damon_sample_mtier_init); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("A DAMON module for memory tiering"); +MODULE_AUTHOR("SeongJae Park "); diff --git a/samples/damon/prcl.c b/samples/damon/prcl.c index b7c50f2656ce..290a3335aa06 100644 --- a/samples/damon/prcl.c +++ b/samples/damon/prcl.c @@ -167,3 +167,6 @@ static int __init damon_sample_prcl_init(void) } module_init(damon_sample_prcl_init); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("A DAMON module for proactive reclamation"); +MODULE_AUTHOR("SeongJae Park "); diff --git a/samples/damon/wsse.c b/samples/damon/wsse.c index 799ad4443943..183bcb7b8516 100644 --- a/samples/damon/wsse.c +++ b/samples/damon/wsse.c @@ -147,3 +147,6 @@ static int __init damon_sample_wsse_init(void) } module_init(damon_sample_wsse_init); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("A DAMON module for working set size estimation"); +MODULE_AUTHOR("SeongJae Park "); base-commit: d358e5254674b70f34c847715ca509e46eb81e6f -- 2.43.0