mm/damon/sysfs-schemes: connect filter directory and filters directory
Implement 'nr_filters' file under 'filters' directory, which will be used to populate specific number of 'filter' directory under the directory, similar to other 'nr_*' files in DAMON sysfs interface. Link: https://lkml.kernel.org/r/20221205230830.144349-8-sj@kernel.org Signed-off-by: SeongJae Park <sj@kernel.org> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Shuah Khan <shuah@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
7ee161f18b
commit
472e2b70ed
|
@ -269,6 +269,11 @@ struct damon_sysfs_scheme_filter {
|
||||||
char *memcg_path;
|
char *memcg_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct damon_sysfs_scheme_filter *damon_sysfs_scheme_filter_alloc(void)
|
||||||
|
{
|
||||||
|
return kzalloc(sizeof(struct damon_sysfs_scheme_filter), GFP_KERNEL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Should match with enum damos_filter_type */
|
/* Should match with enum damos_filter_type */
|
||||||
static const char * const damon_sysfs_scheme_filter_type_strs[] = {
|
static const char * const damon_sysfs_scheme_filter_type_strs[] = {
|
||||||
"anon",
|
"anon",
|
||||||
|
@ -392,6 +397,7 @@ static struct kobj_type damon_sysfs_scheme_filter_ktype = {
|
||||||
|
|
||||||
struct damon_sysfs_scheme_filters {
|
struct damon_sysfs_scheme_filters {
|
||||||
struct kobject kobj;
|
struct kobject kobj;
|
||||||
|
struct damon_sysfs_scheme_filter **filters_arr;
|
||||||
int nr;
|
int nr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -401,6 +407,57 @@ damon_sysfs_scheme_filters_alloc(void)
|
||||||
return kzalloc(sizeof(struct damon_sysfs_scheme_filters), GFP_KERNEL);
|
return kzalloc(sizeof(struct damon_sysfs_scheme_filters), GFP_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void damon_sysfs_scheme_filters_rm_dirs(
|
||||||
|
struct damon_sysfs_scheme_filters *filters)
|
||||||
|
{
|
||||||
|
struct damon_sysfs_scheme_filter **filters_arr = filters->filters_arr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < filters->nr; i++)
|
||||||
|
kobject_put(&filters_arr[i]->kobj);
|
||||||
|
filters->nr = 0;
|
||||||
|
kfree(filters_arr);
|
||||||
|
filters->filters_arr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int damon_sysfs_scheme_filters_add_dirs(
|
||||||
|
struct damon_sysfs_scheme_filters *filters, int nr_filters)
|
||||||
|
{
|
||||||
|
struct damon_sysfs_scheme_filter **filters_arr, *filter;
|
||||||
|
int err, i;
|
||||||
|
|
||||||
|
damon_sysfs_scheme_filters_rm_dirs(filters);
|
||||||
|
if (!nr_filters)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
filters_arr = kmalloc_array(nr_filters, sizeof(*filters_arr),
|
||||||
|
GFP_KERNEL | __GFP_NOWARN);
|
||||||
|
if (!filters_arr)
|
||||||
|
return -ENOMEM;
|
||||||
|
filters->filters_arr = filters_arr;
|
||||||
|
|
||||||
|
for (i = 0; i < nr_filters; i++) {
|
||||||
|
filter = damon_sysfs_scheme_filter_alloc();
|
||||||
|
if (!filter) {
|
||||||
|
damon_sysfs_scheme_filters_rm_dirs(filters);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = kobject_init_and_add(&filter->kobj,
|
||||||
|
&damon_sysfs_scheme_filter_ktype,
|
||||||
|
&filters->kobj, "%d", i);
|
||||||
|
if (err) {
|
||||||
|
kobject_put(&filter->kobj);
|
||||||
|
damon_sysfs_scheme_filters_rm_dirs(filters);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
filters_arr[i] = filter;
|
||||||
|
filters->nr++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t nr_filters_show(struct kobject *kobj,
|
static ssize_t nr_filters_show(struct kobject *kobj,
|
||||||
struct kobj_attribute *attr, char *buf)
|
struct kobj_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
|
@ -413,6 +470,7 @@ static ssize_t nr_filters_show(struct kobject *kobj,
|
||||||
static ssize_t nr_filters_store(struct kobject *kobj,
|
static ssize_t nr_filters_store(struct kobject *kobj,
|
||||||
struct kobj_attribute *attr, const char *buf, size_t count)
|
struct kobj_attribute *attr, const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
|
struct damon_sysfs_scheme_filters *filters;
|
||||||
int nr, err = kstrtoint(buf, 0, &nr);
|
int nr, err = kstrtoint(buf, 0, &nr);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -420,6 +478,15 @@ static ssize_t nr_filters_store(struct kobject *kobj,
|
||||||
if (nr < 0)
|
if (nr < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
filters = container_of(kobj, struct damon_sysfs_scheme_filters, kobj);
|
||||||
|
|
||||||
|
if (!mutex_trylock(&damon_sysfs_lock))
|
||||||
|
return -EBUSY;
|
||||||
|
err = damon_sysfs_scheme_filters_add_dirs(filters, nr);
|
||||||
|
mutex_unlock(&damon_sysfs_lock);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1166,6 +1233,7 @@ static void damon_sysfs_scheme_rm_dirs(struct damon_sysfs_scheme *scheme)
|
||||||
damon_sysfs_quotas_rm_dirs(scheme->quotas);
|
damon_sysfs_quotas_rm_dirs(scheme->quotas);
|
||||||
kobject_put(&scheme->quotas->kobj);
|
kobject_put(&scheme->quotas->kobj);
|
||||||
kobject_put(&scheme->watermarks->kobj);
|
kobject_put(&scheme->watermarks->kobj);
|
||||||
|
damon_sysfs_scheme_filters_rm_dirs(scheme->filters);
|
||||||
kobject_put(&scheme->filters->kobj);
|
kobject_put(&scheme->filters->kobj);
|
||||||
kobject_put(&scheme->stats->kobj);
|
kobject_put(&scheme->stats->kobj);
|
||||||
damon_sysfs_scheme_regions_rm_dirs(scheme->tried_regions);
|
damon_sysfs_scheme_regions_rm_dirs(scheme->tried_regions);
|
||||||
|
|
Loading…
Reference in New Issue