mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
cgroup/dmem: accept only one region per limit write
Accept only one "region value" pair entry for the dmem.max, dmem.min, dmem.low files. This changes the UAPI that otherwise accepted multiple lines for setting multiple entries in one write. No existing user is known to rely on writing multiple regions in a single write. Processing multiple regions in dmemcg_limit_write() could quietly change first limits before failing on a later one and returning an error to the writer, with no indication some changes occurred. Acked-by: Tejun Heo <tj@kernel.org> Signed-off-by: Eric Chanudet <echanude@redhat.com> Reviewed-by: Maxime Ripard <mripard@kernel.org> Reviewed-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com> Tested-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com> Reviewed-by: Natalie Vock <natalie.vock@gmx.de> Link: https://patch.msgid.link/20260608-cgroup-dmem-write-single-region-v2-1-b0cd6c4ccf1b@redhat.com Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
This commit is contained in:
parent
e3335ccbf4
commit
7296004bd2
|
|
@ -734,57 +734,38 @@ static ssize_t dmemcg_limit_write(struct kernfs_open_file *of,
|
|||
void (*apply)(struct dmem_cgroup_pool_state *, u64))
|
||||
{
|
||||
struct dmemcg_state *dmemcs = css_to_dmemcs(of_css(of));
|
||||
int err = 0;
|
||||
struct dmem_cgroup_pool_state *pool;
|
||||
struct dmem_cgroup_region *region;
|
||||
char *region_name;
|
||||
u64 new_limit;
|
||||
int err;
|
||||
|
||||
while (buf && !err) {
|
||||
struct dmem_cgroup_pool_state *pool = NULL;
|
||||
char *options, *region_name;
|
||||
struct dmem_cgroup_region *region;
|
||||
u64 new_limit;
|
||||
buf = strstrip(buf);
|
||||
region_name = strsep(&buf, " \t");
|
||||
if (!buf || !region_name[0])
|
||||
return -EINVAL;
|
||||
|
||||
options = buf;
|
||||
buf = strchr(buf, '\n');
|
||||
if (buf)
|
||||
*buf++ = '\0';
|
||||
rcu_read_lock();
|
||||
region = dmemcg_get_region_by_name(region_name);
|
||||
rcu_read_unlock();
|
||||
if (!region)
|
||||
return -EINVAL;
|
||||
|
||||
options = strstrip(options);
|
||||
err = dmemcg_parse_limit(buf, &new_limit);
|
||||
if (err < 0)
|
||||
goto out_put;
|
||||
|
||||
/* eat empty lines */
|
||||
if (!options[0])
|
||||
continue;
|
||||
|
||||
region_name = strsep(&options, " \t");
|
||||
if (!region_name[0])
|
||||
continue;
|
||||
|
||||
if (!options || !*options)
|
||||
return -EINVAL;
|
||||
|
||||
rcu_read_lock();
|
||||
region = dmemcg_get_region_by_name(region_name);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (!region)
|
||||
return -EINVAL;
|
||||
|
||||
err = dmemcg_parse_limit(options, &new_limit);
|
||||
if (err < 0)
|
||||
goto out_put;
|
||||
|
||||
pool = get_cg_pool_unlocked(dmemcs, region);
|
||||
if (IS_ERR(pool)) {
|
||||
err = PTR_ERR(pool);
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
/* And commit */
|
||||
apply(pool, new_limit);
|
||||
dmemcg_pool_put(pool);
|
||||
|
||||
out_put:
|
||||
kref_put(®ion->ref, dmemcg_free_region);
|
||||
pool = get_cg_pool_unlocked(dmemcs, region);
|
||||
if (IS_ERR(pool)) {
|
||||
err = PTR_ERR(pool);
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
apply(pool, new_limit);
|
||||
dmemcg_pool_put(pool);
|
||||
|
||||
out_put:
|
||||
kref_put(®ion->ref, dmemcg_free_region);
|
||||
|
||||
return err ?: nbytes;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user