From: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
Subject: [Devel] [PATCH VZ10 v7 6/9] ve/ve.c: Generate VE resource accessors using macros
Date: Mon, 24 Aug 2026 13:54:48 +0000 [thread overview]
Message-ID: <a965ccb4262a426a356efb96e7b8df84aa7fbb03.1787579160.git.vladimir.riabchun@virtuozzo.com> (raw)
In-Reply-To: <cover.1787579160.git.vladimir.riabchun@virtuozzo.com>
We have a bunch of almost identical code, which takes place
and has some unclear variations in it. Unify all resource
getters and setters using macros.
This changes behavior a little bit: some resources (netns number
for example) required stopped VE. Now such limits could be updated
with a running VE.
Also, some max_nr_write functions didn't verify provided value,
now it is not possible to pass overflowing value.
https://virtuozzo.atlassian.net/browse/VSTOR-135520
Feature: per-ve failcounters
Signed-off-by: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
---
kernel/ve/ve.c | 209 +++++++++++++------------------------------------
1 file changed, 54 insertions(+), 155 deletions(-)
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index 582fc17e4810..0f02835765ff 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -43,6 +43,39 @@
#include <linux/cpuset.h> /* For css_tg() */
#include "../sched/sched.h" /* For css_tg() */
+#define VE_RESOURCE(name) \
+static u64 ve_##name##_max_nr_read(struct cgroup_subsys_state *css, \
+ struct cftype *cft) \
+{ \
+ return css_to_ve(css)->name##_max_nr; \
+} \
+ \
+static int ve_##name##_max_nr_write(struct cgroup_subsys_state *css, \
+ struct cftype *cft, u64 val) \
+{ \
+ struct ve_struct *ve = css_to_ve(css); \
+ int delta; \
+ \
+ if (!ve_is_super(get_exec_env())) \
+ return -EPERM; \
+ \
+ if (val > INT_MAX) \
+ return -EOVERFLOW; \
+ \
+ down_write(&ve->op_sem); \
+ delta = val - ve->name##_max_nr; \
+ ve->name##_max_nr = val; \
+ atomic_add(delta, &ve->name##_avail_nr); \
+ up_write(&ve->op_sem); \
+ return 0; \
+} \
+ \
+static s64 ve_##name##_avail_nr_read(struct cgroup_subsys_state *css, \
+ struct cftype *cft) \
+{ \
+ return atomic_read(&css_to_ve(css)->name##_avail_nr); \
+}
+
extern struct kmapset_set sysfs_ve_perms_set;
#ifdef CONFIG_PROC_FS
extern struct kmapset_set proc_ve_perms_set;
@@ -1027,121 +1060,10 @@ static int ve_features_write(struct cgroup_subsys_state *css, struct cftype *cft
return 0;
}
-static u64 ve_netns_max_nr_read(struct cgroup_subsys_state *css, struct cftype *cft)
-{
- return css_to_ve(css)->netns_max_nr;
-}
-
-static int ve_netns_max_nr_write(struct cgroup_subsys_state *css, struct cftype *cft, u64 val)
-{
- struct ve_struct *ve = css_to_ve(css);
- int delta;
-
- if (!ve_is_super(get_exec_env()))
- return -EPERM;
-
- down_write(&ve->op_sem);
- if (VE_IS_RUNNING(ve) || ve->ve_nsproxy) {
- up_write(&ve->op_sem);
- return -EBUSY;
- }
- delta = val - ve->netns_max_nr;
- ve->netns_max_nr = val;
- atomic_add(delta, &ve->netns_avail_nr);
- up_write(&ve->op_sem);
- return 0;
-}
-static u64 ve_netns_avail_nr_read(struct cgroup_subsys_state *css, struct cftype *cft)
-{
- return atomic_read(&css_to_ve(css)->netns_avail_nr);
-}
-
-static s64 ve_mnt_avail_nr_read(struct cgroup_subsys_state *css, struct cftype *cft)
-{
- return atomic_read(&css_to_ve(css)->mnt_avail_nr);
-}
-
-static u64 ve_mnt_max_nr_read(struct cgroup_subsys_state *css, struct cftype *cft)
-{
- return css_to_ve(css)->mnt_max_nr;
-}
-
-static int ve_mnt_max_nr_write(struct cgroup_subsys_state *css, struct cftype *cft, u64 val)
-{
- struct ve_struct *ve = css_to_ve(css);
- int delta;
-
- if (!ve_is_super(get_exec_env()))
- return -EPERM;
-
- if (val > INT_MAX)
- return -EOVERFLOW;
-
- down_write(&ve->op_sem);
- delta = val - ve->mnt_max_nr;
- ve->mnt_max_nr = val;
- atomic_add(delta, &ve->mnt_avail_nr);
- up_write(&ve->op_sem);
- return 0;
-}
-
-static u64 ve_netif_max_nr_read(struct cgroup_subsys_state *css, struct cftype *cft)
-{
- return css_to_ve(css)->netif_max_nr;
-}
-
-static int ve_netif_max_nr_write(struct cgroup_subsys_state *css, struct cftype *cft, u64 val)
-{
- struct ve_struct *ve = css_to_ve(css);
- int delta;
-
- if (!ve_is_super(get_exec_env()))
- return -EPERM;
-
- if (val > INT_MAX)
- return -EOVERFLOW;
-
- down_write(&ve->op_sem);
- delta = val - ve->netif_max_nr;
- ve->netif_max_nr = val;
- atomic_add(delta, &ve->netif_avail_nr);
- up_write(&ve->op_sem);
- return 0;
-}
-
-static s64 ve_netif_avail_nr_read(struct cgroup_subsys_state *css, struct cftype *cft)
-{
- return atomic_read(&css_to_ve(css)->netif_avail_nr);
-}
-
-static u64 ve_bpf_prog_max_nr_read(struct cgroup_subsys_state *css, struct cftype *cft)
-{
- return css_to_ve(css)->bpf_prog_max_nr;
-}
-
-static int ve_bpf_prog_max_nr_write(struct cgroup_subsys_state *css, struct cftype *cft, u64 val)
-{
- struct ve_struct *ve = css_to_ve(css);
- int delta;
-
- if (!ve_is_super(get_exec_env()))
- return -EPERM;
-
- if (val > INT_MAX)
- return -EOVERFLOW;
-
- down_write(&ve->op_sem);
- delta = val - ve->bpf_prog_max_nr;
- ve->bpf_prog_max_nr = val;
- atomic_add(delta, &ve->bpf_prog_avail_nr);
- up_write(&ve->op_sem);
- return 0;
-}
-
-static s64 ve_bpf_prog_avail_nr_read(struct cgroup_subsys_state *css, struct cftype *cft)
-{
- return atomic_read(&css_to_ve(css)->bpf_prog_avail_nr);
-}
+VE_RESOURCE(netns);
+VE_RESOURCE(mnt);
+VE_RESOURCE(netif);
+VE_RESOURCE(bpf_prog);
static int ve_os_release_read(struct seq_file *sf, void *v)
{
@@ -1587,6 +1509,19 @@ static int ve_rpc_kill_write(struct cgroup_subsys_state *css,
return 0;
}
+/* checkpatch will report it, can't enclose this in parentheses. */
+#define VE_RESOURCE_CFTYPE(res) \
+{ \
+ .name = #res "_max_nr", \
+ .flags = CFTYPE_NOT_ON_ROOT, \
+ .read_u64 = ve_##res##_max_nr_read, \
+ .write_u64 = ve_##res##_max_nr_write, \
+}, \
+{ \
+ .name = #res "_avail_nr", \
+ .read_s64 = ve_##res##_avail_nr_read, \
+}
+
static struct cftype ve_cftypes[] = {
{
@@ -1631,46 +1566,10 @@ static struct cftype ve_cftypes[] = {
.read_u64 = ve_pid_max_read_u64,
.write_u64 = ve_pid_max_write_running_u64,
},
- {
- .name = "netns_max_nr",
- .flags = CFTYPE_NOT_ON_ROOT,
- .read_u64 = ve_netns_max_nr_read,
- .write_u64 = ve_netns_max_nr_write,
- },
- {
- .name = "netns_avail_nr",
- .read_u64 = ve_netns_avail_nr_read,
- },
- {
- .name = "mnt_avail_nr",
- .read_s64 = ve_mnt_avail_nr_read,
- },
- {
- .name = "mnt_max_nr",
- .flags = CFTYPE_NOT_ON_ROOT,
- .read_u64 = ve_mnt_max_nr_read,
- .write_u64 = ve_mnt_max_nr_write,
- },
- {
- .name = "netif_max_nr",
- .flags = CFTYPE_NOT_ON_ROOT,
- .read_u64 = ve_netif_max_nr_read,
- .write_u64 = ve_netif_max_nr_write,
- },
- {
- .name = "netif_avail_nr",
- .read_s64 = ve_netif_avail_nr_read,
- },
- {
- .name = "bpf_prog_max_nr",
- .flags = CFTYPE_NOT_ON_ROOT,
- .read_u64 = ve_bpf_prog_max_nr_read,
- .write_u64 = ve_bpf_prog_max_nr_write,
- },
- {
- .name = "bpf_prog_avail_nr",
- .read_s64 = ve_bpf_prog_avail_nr_read,
- },
+ VE_RESOURCE_CFTYPE(netns),
+ VE_RESOURCE_CFTYPE(mnt),
+ VE_RESOURCE_CFTYPE(netif),
+ VE_RESOURCE_CFTYPE(bpf_prog),
{
.name = "os_release",
.max_write_len = __NEW_UTS_LEN + 1,
--
2.47.1
next prev parent reply other threads:[~2026-08-24 13:54 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-24 13:54 [Devel] [PATCH VZ10 v7 0/9] Add per-VE failcount support Vladimir Riabchun
2026-08-24 13:54 ` [Devel] [PATCH VZ10 v7 1/9] ve/ve.{h, c}: Farewell to spaces as indents Vladimir Riabchun
2026-08-24 13:54 ` [Devel] [PATCH VZ10 v7 2/9] ve/namespace: Fix UAF in alloc_mnt_ns Vladimir Riabchun
2026-08-24 13:54 ` [Devel] [PATCH VZ10 v7 3/9] ve/fs: Rework per-ve mount count Vladimir Riabchun
2026-08-24 13:54 ` [Devel] [PATCH VZ10 v7 4/9] selftests/ve: Update ve_ns_owner_test Vladimir Riabchun
2026-08-24 13:54 ` [Devel] [PATCH VZ10 v7 5/9] ve: Move from global VE mounts limit to per-VE limit Vladimir Riabchun
2026-08-24 13:54 ` Vladimir Riabchun [this message]
2026-08-24 13:54 ` [Devel] [PATCH VZ10 v7 7/9] ve: Introduce per-VE failcount Vladimir Riabchun
2026-08-28 16:52 ` Pavel Tikhomirov
2026-08-28 17:32 ` Vladimir Riabchun
2026-08-24 13:54 ` [Devel] [PATCH VZ10 v7 8/9] selftests/ve: Add more helpers Vladimir Riabchun
2026-08-24 13:54 ` [Devel] [PATCH VZ10 v7 9/9] selftests/ve: Add mount accounting selftest Vladimir Riabchun
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=a965ccb4262a426a356efb96e7b8df84aa7fbb03.1787579160.git.vladimir.riabchun@virtuozzo.com \
--to=vladimir.riabchun@virtuozzo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox