From: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
To: devel@openvz.org
Subject: Re: [Devel] [PATCH VZ10 v9 4/8] ve: Move from global VE mounts limit to per-VE limit
Date: Fri, 18 Sep 2026 16:29:18 +0200 [thread overview]
Message-ID: <03c354c6-6acf-4823-8f59-1f0d1aa18faa@virtuozzo.com> (raw)
In-Reply-To: <1192cb6b90315be4aea86501a203310202147ee2.1789491989.git.vladimir.riabchun@virtuozzo.com>
Sashiko review:
On 9/15/26 19:22, Vladimir Riabchun wrote:
> This change unifies mount limit handling with other VE limits.
> This will simplify refactoring later and allow more precise limits
> control from one place.
>
> https://virtuozzo.atlassian.net/browse/VSTOR-135520
>
> Feature: per-ve failcounters
> Signed-off-by: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
> ---
> include/linux/ve.h | 9 +++--
> kernel/ve/ve.c | 34 ++++++++++++++++++-
> kernel/ve/veowner.c | 19 -----------
> tools/testing/selftests/ve/ve_ns_owner_test.c | 6 +++-
> 4 files changed, 45 insertions(+), 23 deletions(-)
>
> diff --git a/include/linux/ve.h b/include/linux/ve.h
> index 65c058c0f34d..fabc608e31f5 100644
> --- a/include/linux/ve.h
> +++ b/include/linux/ve.h
> @@ -96,7 +96,13 @@ struct ve_struct {
> atomic_t nd_neigh_nr;
> unsigned long meminfo_val;
>
> + /*
> + * Operations with a big amount of mount points can require a lot of time.
> + * These operations take the global lock namespace_sem, so they can affect
> + * other containers.
> + */
> atomic_t mnt_avail_nr; /* number of available VE mounts */
> + int mnt_max_nr;
>
> #ifdef CONFIG_COREDUMP
> char core_pattern[CORENAME_MAX_SIZE];
> @@ -143,8 +149,7 @@ extern int nr_ve;
> #define NETNS_MAX_NR_DEFAULT 256 /* number of net-namespaces per-VE */
> #define NETIF_MAX_NR_DEFAULT 256 /* number of net-interfaces per-VE */
> #define BPF_PROG_MAX_NR_DEFAULT 256 /* number of loaded BPF progs per-VE */
> -
> -extern unsigned int sysctl_ve_mount_nr;
> +#define MNT_MAX_NR_DEFAULT 4096 /* number of mounts per-VE */
>
> #ifdef CONFIG_VE
> static inline void ve_set_state(struct ve_struct *ve, int new_state)
> diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
> index 58a0c4b8e36e..a33e55991e52 100644
> --- a/kernel/ve/ve.c
> +++ b/kernel/ve/ve.c
> @@ -83,6 +83,7 @@ struct ve_struct ve0 = {
> .arp_neigh_nr = ATOMIC_INIT(0),
> .nd_neigh_nr = ATOMIC_INIT(0),
> .mnt_avail_nr = ATOMIC_INIT(INT_MAX),
> + .mnt_max_nr = INT_MAX,
> .meminfo_val = VE_MEMINFO_SYSTEM,
> #ifdef CONFIG_X86
> .umh_running_helpers = ATOMIC_INIT(0),
> @@ -787,7 +788,8 @@ static struct cgroup_subsys_state *ve_create(struct cgroup_subsys_state *parent_
>
> atomic_set(&ve->arp_neigh_nr, 0);
> atomic_set(&ve->nd_neigh_nr, 0);
> - atomic_set(&ve->mnt_avail_nr, sysctl_ve_mount_nr);
> + ve->mnt_max_nr = MNT_MAX_NR_DEFAULT;
> + atomic_set(&ve->mnt_avail_nr, MNT_MAX_NR_DEFAULT);
>
> #ifdef CONFIG_COREDUMP
> strcpy(ve->core_pattern, "core");
> @@ -1068,6 +1070,30 @@ static s64 ve_mnt_avail_nr_read(struct cgroup_subsys_state *css, struct cftype *
> 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);
Sashiko says:
In the function ve_mnt_max_nr_write, the computation delta = val - ve->mnt_max_nr
followed by atomic_add(delta, &ve->mnt_avail_nr) might lead to an integer
overflow. What checks or safeguards are in place to ensure that this operation
will not lead to an overflow, potentially affecting the VE system state?
0 <= val <= INT_MAX
0 <= ve->mnt_max_nr <= INT_MAX
INT_MIN < 0 - INT_MAX <= delta <= INT_MAX - 0
So delta never overflows. Can mnt_avail_nr overflow?
No, it can't. By definition mnt_avail_nr = mnt_max_nr - have_mounts.
It can't overflow INT_MAX since it's always <= mnt_max_nr <= INT_MAX.
It can't overflow INT_MIN - it means we have > |INT_MIN| mounts, which
is not the real case.
> + 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;
> @@ -1630,6 +1656,12 @@ static struct cftype ve_cftypes[] = {
> .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,
> diff --git a/kernel/ve/veowner.c b/kernel/ve/veowner.c
> index 1e631baf0de9..c77735f8c035 100644
> --- a/kernel/ve/veowner.c
> +++ b/kernel/ve/veowner.c
> @@ -48,26 +48,7 @@ static void prepare_proc(void)
> * ------------------------------------------------------------------------
> */
>
> -/*
> - * Operations with a big amount of mount points can require a lot of time.
> - * These operations take the global lock namespace_sem, so they can affect
> - * other containers. Let us allow no more than sysctl_ve_mount_nr mount
> - * points for a VE.
> - */
> -unsigned int sysctl_ve_mount_nr = 4096;
> -static int ve_mount_nr_min = 0;
> -static int ve_mount_nr_max = INT_MAX;
> -
> static struct ctl_table vz_fs_table[] = {
> - {
> - .procname = "ve-mount-nr",
> - .data = &sysctl_ve_mount_nr,
> - .maxlen = sizeof(sysctl_ve_mount_nr),
> - .mode = 0644,
> - .proc_handler = proc_dointvec_minmax,
> - .extra1 = &ve_mount_nr_min,
> - .extra2 = &ve_mount_nr_max,
> - },
Sashiko says:
The removal of sysctl_ve_mount_nr potentially affects users relying
on this sysctl for VE mount limits, impacting backward compatibility.
Is there an alternative provided for monitoring or configuring
VE mount limits dynamically that maintains backward compatibility?
This sysctl mechanism doesn't work well with per-VE limits,
the only solution to maintain the behavior is to iterate over all
VEs and update avail numbers.
IMO this doesn't add that much value to have two separate limiting
mechanisms in different places.
> {
> .procname = "fsync-enable",
> .data = &ve0.fsync_enable,
> diff --git a/tools/testing/selftests/ve/ve_ns_owner_test.c b/tools/testing/selftests/ve/ve_ns_owner_test.c
> index c3fa7d7b7f9c..dcff4d54172d 100644
> --- a/tools/testing/selftests/ve/ve_ns_owner_test.c
> +++ b/tools/testing/selftests/ve/ve_ns_owner_test.c
> @@ -50,7 +50,7 @@
> * any spurious accounting against the parent ve would overflow it.
> */
> #define VE_NETNS_MAX 3
> -#define VE_MOUNTS_MAX 4096
> +#define VE_MOUNTS_MAX 32
>
> /*
> * Synchronisation across the clone() boundary: child does its setup,
> @@ -173,6 +173,10 @@ FIXTURE_SETUP(ve_ns_owner)
> snprintf(val, sizeof(val), "%d", VE_NETNS_MAX);
> ASSERT_EQ(write_file_at(self->cgv2_fd, path, val), 0);
>
> + snprintf(path, sizeof(path), "%d/ve.mnt_max_nr", self->ctid);
> + snprintf(val, sizeof(val), "%d", VE_MOUNTS_MAX);
> + ASSERT_EQ(write_file_at(self->cgv2_fd, path, val), 0);
> +
> /*
> * The new ve cgroup has not been entered by anything yet, so its
> * mnt_avail_nr counter should be VE_MOUNTS_MAX. Each test below
--
Best regards, Riabchun Vladimir
Linux Kernel Developer, Virtuozzo
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel
next prev parent reply other threads:[~2026-09-18 14:31 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-15 17:22 [Devel] [PATCH VZ10 v9 0/8] Add per-VE failcount support Vladimir Riabchun
2026-09-15 17:22 ` [Devel] [PATCH VZ10 v9 1/8] ve/ve.{h, c}: Farewell to spaces as indents Vladimir Riabchun
2026-09-25 15:55 ` Konstantin Khorenko
2026-09-15 17:22 ` [Devel] [PATCH VZ10 v9 2/8] ve/fs: Rework per-ve mount count Vladimir Riabchun
2026-09-18 13:22 ` Vladimir Riabchun
2026-09-15 17:22 ` [Devel] [PATCH VZ10 v9 3/8] selftests/ve: Update ve_ns_owner_test Vladimir Riabchun
2026-09-18 13:28 ` Vladimir Riabchun
2026-09-15 17:22 ` [Devel] [PATCH VZ10 v9 4/8] ve: Move from global VE mounts limit to per-VE limit Vladimir Riabchun
2026-09-18 14:29 ` Vladimir Riabchun [this message]
2026-09-15 17:22 ` [Devel] [PATCH VZ10 v9 5/8] ve/ve.c: Generate VE resource accessors using macros Vladimir Riabchun
2026-09-18 14:36 ` Vladimir Riabchun
2026-09-15 17:22 ` [Devel] [PATCH VZ10 v9 6/8] ve: Introduce per-VE failcount Vladimir Riabchun
2026-09-18 14:42 ` Vladimir Riabchun
2026-09-25 16:02 ` Konstantin Khorenko
2026-09-25 16:08 ` Konstantin Khorenko
2026-09-15 17:22 ` [Devel] [PATCH VZ10 v9 7/8] ve/printk: Don't use ve log outside task context Vladimir Riabchun
2026-09-18 14:50 ` Vladimir Riabchun
2026-09-22 11:21 ` Vladimir Riabchun
2026-09-25 16:02 ` Konstantin Khorenko
2026-09-15 17:22 ` [Devel] [PATCH VZ10 v9 8/8] selftests/ve: Add mount accounting selftest Vladimir Riabchun
2026-09-18 15:06 ` Vladimir Riabchun
2026-09-25 16:04 ` Konstantin Khorenko
2026-09-16 12:30 ` [Devel] [PATCH VZ10 v9 0/8] Add per-VE failcount support Vasileios Almpanis
2026-09-16 17:30 ` Konstantin Khorenko
2026-09-18 15:07 ` Vladimir Riabchun
2026-09-18 16:02 ` 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=03c354c6-6acf-4823-8f59-1f0d1aa18faa@virtuozzo.com \
--to=vladimir.riabchun@virtuozzo.com \
--cc=devel@openvz.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.