mm/damon/sysfs: decouple from damon_ops_id

Decouple DAMON sysfs interface from damon_ops_id.  For this, define and
use new mm/damon/sysfs.c internal data structure that maps the user-space
keywords and damon_ops_id, instead of having the implicit and unflexible
array index rule.

Link: https://lkml.kernel.org/r/20250622213759.50930-6-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
SeongJae Park
2025-06-22 14:37:59 -07:00
committed by Andrew Morton
parent a39346daec
commit d1600be2f6

View File

@@ -811,11 +811,24 @@ static const struct kobj_type damon_sysfs_attrs_ktype = {
* context directory
*/
/* This should match with enum damon_ops_id */
static const char * const damon_sysfs_ops_strs[] = {
"vaddr",
"fvaddr",
"paddr",
struct damon_sysfs_ops_name {
enum damon_ops_id ops_id;
char *name;
};
static const struct damon_sysfs_ops_name damon_sysfs_ops_names[] = {
{
.ops_id = DAMON_OPS_VADDR,
.name = "vaddr",
},
{
.ops_id = DAMON_OPS_FVADDR,
.name = "fvaddr",
},
{
.ops_id = DAMON_OPS_PADDR,
.name = "paddr",
},
};
struct damon_sysfs_context {
@@ -934,14 +947,16 @@ static void damon_sysfs_context_rm_dirs(struct damon_sysfs_context *context)
static ssize_t avail_operations_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
enum damon_ops_id id;
int len = 0;
int i;
for (id = 0; id < NR_DAMON_OPS; id++) {
if (!damon_is_registered_ops(id))
for (i = 0; i < ARRAY_SIZE(damon_sysfs_ops_names); i++) {
const struct damon_sysfs_ops_name *ops_name;
ops_name = &damon_sysfs_ops_names[i];
if (!damon_is_registered_ops(ops_name->ops_id))
continue;
len += sysfs_emit_at(buf, len, "%s\n",
damon_sysfs_ops_strs[id]);
len += sysfs_emit_at(buf, len, "%s\n", ops_name->name);
}
return len;
}
@@ -951,8 +966,16 @@ static ssize_t operations_show(struct kobject *kobj,
{
struct damon_sysfs_context *context = container_of(kobj,
struct damon_sysfs_context, kobj);
int i;
return sysfs_emit(buf, "%s\n", damon_sysfs_ops_strs[context->ops_id]);
for (i = 0; i < ARRAY_SIZE(damon_sysfs_ops_names); i++) {
const struct damon_sysfs_ops_name *ops_name;
ops_name = &damon_sysfs_ops_names[i];
if (ops_name->ops_id == context->ops_id)
return sysfs_emit(buf, "%s\n", ops_name->name);
}
return -EINVAL;
}
static ssize_t operations_store(struct kobject *kobj,
@@ -960,11 +983,14 @@ static ssize_t operations_store(struct kobject *kobj,
{
struct damon_sysfs_context *context = container_of(kobj,
struct damon_sysfs_context, kobj);
enum damon_ops_id id;
int i;
for (id = 0; id < NR_DAMON_OPS; id++) {
if (sysfs_streq(buf, damon_sysfs_ops_strs[id])) {
context->ops_id = id;
for (i = 0; i < ARRAY_SIZE(damon_sysfs_ops_names); i++) {
const struct damon_sysfs_ops_name *ops_name;
ops_name = &damon_sysfs_ops_names[i];
if (sysfs_streq(buf, ops_name->name)) {
context->ops_id = ops_name->ops_id;
return count;
}
}