The sample filter directory is not really having the file to set up for
the properties of the representing DAMON sample filter. Implement files
for setting the properties.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
mm/damon/sysfs.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 101 insertions(+)
diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
index ba0c76c1300c..74594e6e461c 100644
--- a/mm/damon/sysfs.c
+++ b/mm/damon/sysfs.c
@@ -755,6 +755,9 @@ static const struct kobj_type damon_sysfs_intervals_ktype = {
struct damon_sysfs_sample_filter {
struct kobject kobj;
+ enum damon_sample_filter_type type;
+ bool matching;
+ bool allow;
};
static struct damon_sysfs_sample_filter *damon_sysfs_sample_filter_alloc(void)
@@ -762,6 +765,92 @@ static struct damon_sysfs_sample_filter *damon_sysfs_sample_filter_alloc(void)
return kzalloc(sizeof(struct damon_sysfs_sample_filter), GFP_KERNEL);
}
+static ssize_t type_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_sample_filter *filter = container_of(kobj,
+ struct damon_sysfs_sample_filter, kobj);
+ int i = 0;
+
+ for (; i < ARRAY_SIZE(damon_sysfs_sample_filter_type_names); i++) {
+ const struct damon_sysfs_sample_filter_type_name *type_name;
+
+ type_name = &damon_sysfs_sample_filter_type_names[i];
+ if (type_name->type == filter->type)
+ return sysfs_emit(buf, "%s\n", type_name->name);
+ }
+ return -EINVAL;
+}
+
+static ssize_t type_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_sample_filter *filter = container_of(kobj,
+ struct damon_sysfs_sample_filter, kobj);
+ ssize_t ret = -EINVAL;
+ int i = 0;
+
+ for (; i < ARRAY_SIZE(damon_sysfs_sample_filter_type_names); i++) {
+ const struct damon_sysfs_sample_filter_type_name *type_name;
+
+ type_name = &damon_sysfs_sample_filter_type_names[i];
+ if (sysfs_streq(buf, type_name->name)) {
+ filter->type = type_name->type;
+ ret = count;
+ break;
+ }
+ }
+ return ret;
+}
+
+static ssize_t matching_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_sample_filter *filter = container_of(kobj,
+ struct damon_sysfs_sample_filter, kobj);
+
+ return sysfs_emit(buf, "%c\n", filter->matching ? 'Y' : 'N');
+}
+
+static ssize_t matching_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_sample_filter *filter = container_of(kobj,
+ struct damon_sysfs_sample_filter, kobj);
+ bool matching;
+ int err = kstrtobool(buf, &matching);
+
+ if (err)
+ return err;
+
+ filter->matching = matching;
+ return count;
+}
+
+static ssize_t allow_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_sample_filter *filter = container_of(kobj,
+ struct damon_sysfs_sample_filter, kobj);
+
+ return sysfs_emit(buf, "%c\n", filter->allow ? 'Y' : 'N');
+}
+
+static ssize_t allow_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_sample_filter *filter = container_of(kobj,
+ struct damon_sysfs_sample_filter, kobj);
+ bool allow;
+ int err = kstrtobool(buf, &allow);
+
+ if (err)
+ return err;
+
+ filter->allow = allow;
+ return count;
+}
+
static void damon_sysfs_sample_filter_release(struct kobject *kobj)
{
struct damon_sysfs_sample_filter *filter = container_of(kobj,
@@ -770,7 +859,19 @@ static void damon_sysfs_sample_filter_release(struct kobject *kobj)
kfree(filter);
}
+static struct kobj_attribute damon_sysfs_sample_filter_type_attr =
+ __ATTR_RW_MODE(type, 0600);
+
+static struct kobj_attribute damon_sysfs_sample_filter_matching_attr =
+ __ATTR_RW_MODE(matching, 0600);
+
+static struct kobj_attribute damon_sysfs_sample_filter_allow_attr =
+ __ATTR_RW_MODE(allow, 0600);
+
static struct attribute *damon_sysfs_sample_filter_attrs[] = {
+ &damon_sysfs_sample_filter_type_attr.attr,
+ &damon_sysfs_sample_filter_matching_attr.attr,
+ &damon_sysfs_sample_filter_allow_attr.attr,
NULL,
};
ATTRIBUTE_GROUPS(damon_sysfs_sample_filter);
--
2.47.3