OpenVZ / Virtuozzo kernel development (devel@openvz.org)
 help / color / mirror / Atom feed
From: Vladimir Riabchun <vladimir.riabchun@virtuozzo.com>
To: devel@openvz.org
Subject: Re: [Devel] [PATCH VZ10 v9 5/8] ve/ve.c: Generate VE resource accessors using macros
Date: Fri, 18 Sep 2026 16:36:08 +0200	[thread overview]
Message-ID: <645ef9c7-d64e-4858-a740-cd1f3186b33a@virtuozzo.com> (raw)
In-Reply-To: <49cc3ffce4a639e79220ce27f0c6bbfc84681d3b.1789491989.git.vladimir.riabchun@virtuozzo.com>

Sashiko review:

On 9/15/26 19:22, Vladimir Riabchun wrote:
> 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 a33e55991e52..5ebdb4b7baa7 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);					\

Sashiko says:
  Does the change to use macros for VE resource management impact the safety
  of runtime VE modifications? The original ve_netns_max_nr_write function
  included a check on VE_IS_RUNNING(ve) || ve->ve_nsproxy, which prevented
  modifications unless these conditions were met.
  The new macro VE_RESOURCE seems to omit this check, which might lead to
  inconsistencies if resource limits are altered during VE operation.

max values are used only in these helpers to adjust avail number.
There is no reason for enforcing stopped VE - only host can update
the value anyway. And having the ability to adjust limits without stopping
CT seems really useful.

This is the anser for the next Sashiko comment:
  Is the current permission check sufficient in the VE_RESOURCE macro? By checking only
  ve_is_super(get_exec_env()), it seems you now allow modifications without verifying
  the VE's actual running state.
  Would this oversight instate authorizations in inappropriate scenarios where
  VE should disallow updates?
> +	delta = val - ve->name##_max_nr;				\

Sashiko says:
  Could the calculation of delta = val - ve->name_max_nr in VE_RESOURCE lead
  to integer overflow?

No, same reasoning as in previous patch.

> +	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;
> @@ -1036,121 +1069,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)
>   {
> @@ -1598,6 +1520,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[] = {
>   
>   	{
> @@ -1642,46 +1577,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,

-- 
Best regards, Riabchun Vladimir
Linux Kernel Developer, Virtuozzo

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

  reply	other threads:[~2026-09-18 14:37 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
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 [this message]
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=645ef9c7-d64e-4858-a740-cd1f3186b33a@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox