mm/damon/sysfs-schemes: implement fail_charge_{num,denom} files

Implement the user-space ABI for the DAMOS action failed region
quota-charge ratio setup.  For this, add two new sysfs files under the
DAMON sysfs interface for DAMOS quotas.  Names of the files are
fail_charge_num and fail_charge_denom, and work for reading and setting
the numerator and denominator of the failed regions charge ratio.

Link: https://lore.kernel.org/20260428013402.115171-5-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Brendan Higgins <brendan.higgins@linux.dev>
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: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
SeongJae Park 2026-04-27 18:33:53 -07:00 committed by Andrew Morton
parent 4ee4fb3214
commit fad1124120

View File

@ -1512,6 +1512,8 @@ struct damon_sysfs_quotas {
unsigned long reset_interval_ms;
unsigned long effective_sz; /* Effective size quota in bytes */
enum damos_quota_goal_tuner goal_tuner;
unsigned int fail_charge_num;
unsigned int fail_charge_denom;
};
static struct damon_sysfs_quotas *damon_sysfs_quotas_alloc(void)
@ -1686,6 +1688,48 @@ static ssize_t goal_tuner_store(struct kobject *kobj,
return -EINVAL;
}
static ssize_t fail_charge_num_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
struct damon_sysfs_quotas *quotas = container_of(kobj,
struct damon_sysfs_quotas, kobj);
return sysfs_emit(buf, "%u\n", quotas->fail_charge_num);
}
static ssize_t fail_charge_num_store(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t count)
{
struct damon_sysfs_quotas *quotas = container_of(kobj,
struct damon_sysfs_quotas, kobj);
int err = kstrtouint(buf, 0, &quotas->fail_charge_num);
if (err)
return -EINVAL;
return count;
}
static ssize_t fail_charge_denom_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
struct damon_sysfs_quotas *quotas = container_of(kobj,
struct damon_sysfs_quotas, kobj);
return sysfs_emit(buf, "%u\n", quotas->fail_charge_denom);
}
static ssize_t fail_charge_denom_store(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t count)
{
struct damon_sysfs_quotas *quotas = container_of(kobj,
struct damon_sysfs_quotas, kobj);
int err = kstrtouint(buf, 0, &quotas->fail_charge_denom);
if (err)
return -EINVAL;
return count;
}
static void damon_sysfs_quotas_release(struct kobject *kobj)
{
kfree(container_of(kobj, struct damon_sysfs_quotas, kobj));
@ -1706,12 +1750,20 @@ static struct kobj_attribute damon_sysfs_quotas_effective_bytes_attr =
static struct kobj_attribute damon_sysfs_quotas_goal_tuner_attr =
__ATTR_RW_MODE(goal_tuner, 0600);
static struct kobj_attribute damon_sysfs_quotas_fail_charge_num_attr =
__ATTR_RW_MODE(fail_charge_num, 0600);
static struct kobj_attribute damon_sysfs_quotas_fail_charge_denom_attr =
__ATTR_RW_MODE(fail_charge_denom, 0600);
static struct attribute *damon_sysfs_quotas_attrs[] = {
&damon_sysfs_quotas_ms_attr.attr,
&damon_sysfs_quotas_sz_attr.attr,
&damon_sysfs_quotas_reset_interval_ms_attr.attr,
&damon_sysfs_quotas_effective_bytes_attr.attr,
&damon_sysfs_quotas_goal_tuner_attr.attr,
&damon_sysfs_quotas_fail_charge_num_attr.attr,
&damon_sysfs_quotas_fail_charge_denom_attr.attr,
NULL,
};
ATTRIBUTE_GROUPS(damon_sysfs_quotas);
@ -2803,6 +2855,8 @@ static struct damos *damon_sysfs_mk_scheme(
.weight_nr_accesses = sysfs_weights->nr_accesses,
.weight_age = sysfs_weights->age,
.goal_tuner = sysfs_quotas->goal_tuner,
.fail_charge_num = sysfs_quotas->fail_charge_num,
.fail_charge_denom = sysfs_quotas->fail_charge_denom,
};
struct damos_watermarks wmarks = {
.metric = sysfs_wmarks->metric,