]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mm/damon/sysfs: implement filter dir files
authorSeongJae Park <sj@kernel.org>
Mon, 18 May 2026 23:41:01 +0000 (16:41 -0700)
committerAndrew Morton <akpm@linux-foundation.org>
Tue, 2 Jun 2026 22:22:27 +0000 (15:22 -0700)
Implement sysfs files under the data probe filter directory for letting
users to configure each filter.

Link: https://lore.kernel.org/20260518234119.97569-14-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/damon/sysfs.c

index 2dc475ea0f0f783cd751777258a5392b257f506b..51a4f05c9275c605b83994d81574c4c62c2b96e7 100644 (file)
@@ -753,6 +753,9 @@ static const struct kobj_type damon_sysfs_intervals_ktype = {
 
 struct damon_sysfs_filter {
        struct kobject kobj;
+       enum damon_filter_type type;
+       bool matching;
+       bool allow;
 };
 
 static struct damon_sysfs_filter *damon_sysfs_filter_alloc(void)
@@ -760,6 +763,105 @@ static struct damon_sysfs_filter *damon_sysfs_filter_alloc(void)
        return kzalloc_obj(struct damon_sysfs_filter);
 }
 
+struct damon_sysfs_filter_type_name {
+       enum damon_filter_type type;
+       char *name;
+};
+
+static const struct damon_sysfs_filter_type_name
+damon_sysfs_filter_type_names[] = {
+       {
+               .type = DAMON_FILTER_TYPE_ANON,
+               .name = "anon",
+       },
+};
+
+static ssize_t type_show(struct kobject *kobj,
+               struct kobj_attribute *attr, char *buf)
+{
+       struct damon_sysfs_filter *filter = container_of(kobj,
+                       struct damon_sysfs_filter, kobj);
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(damon_sysfs_filter_type_names); i++) {
+               const struct damon_sysfs_filter_type_name *type_name;
+
+               type_name = &damon_sysfs_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_filter *filter = container_of(kobj,
+                       struct damon_sysfs_filter, kobj);
+       ssize_t ret = -EINVAL;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(damon_sysfs_filter_type_names); i++) {
+               const struct damon_sysfs_filter_type_name *type_name;
+
+               type_name = &damon_sysfs_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_filter *filter = container_of(kobj,
+                       struct damon_sysfs_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_filter *filter = container_of(kobj,
+                       struct damon_sysfs_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_filter *filter = container_of(kobj,
+                       struct damon_sysfs_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_filter *filter = container_of(kobj,
+                       struct damon_sysfs_filter, kobj);
+       bool allow;
+       int err = kstrtobool(buf, &allow);
+
+       if (err)
+               return err;
+
+       filter->allow = allow;
+       return count;
+}
+
 static void damon_sysfs_filter_release(struct kobject *kobj)
 {
        struct damon_sysfs_filter *filter = container_of(kobj,
@@ -768,7 +870,19 @@ static void damon_sysfs_filter_release(struct kobject *kobj)
        kfree(filter);
 }
 
+static struct kobj_attribute damon_sysfs_filter_type_attr =
+               __ATTR_RW_MODE(type, 0600);
+
+static struct kobj_attribute damon_sysfs_filter_matching_attr =
+               __ATTR_RW_MODE(matching, 0600);
+
+static struct kobj_attribute damon_sysfs_filter_allow_attr =
+               __ATTR_RW_MODE(allow, 0600);
+
 static struct attribute *damon_sysfs_filter_attrs[] = {
+       &damon_sysfs_filter_type_attr.attr,
+       &damon_sysfs_filter_matching_attr.attr,
+       &damon_sysfs_filter_allow_attr.attr,
        NULL,
 };
 ATTRIBUTE_GROUPS(damon_sysfs_filter);