On 5/29/26 14:20, Pavel Tikhomirov wrote:
Expose the per-VE BPF program load limit via two ve cgroup files:

   bpf_prog_max_nr   - rw, writable only from ve0, restricts loads
   bpf_prog_avail_nr - ro, remaining quota

Writes adjust the avail counter by the delta so that already-loaded
programs are not retroactively rejected when the cap is lowered.

https://virtuozzo.atlassian.net/browse/VSTOR-131947
Signed-off-by: Pavel Tikhomirov <[email protected]>
Feature: ve: allow BPF in Containers
---
  kernel/ve/ve.c | 39 +++++++++++++++++++++++++++++++++++++++
  1 file changed, 39 insertions(+)

diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index 48da546117bb7..9c3be61a4366a 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -1315,6 +1315,35 @@ static s64 ve_netif_avail_nr_read(struct 
cgroup_subsys_state *css, struct cftype
        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;

Read is not protected by ve->op_sem, possible race.

+}
+
+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);

We should check ve->bpf_prog_avail_nr + delta >= 0, otherwise we can have more
programs than allowed.

+       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);
+}
+
  static int ve_os_release_read(struct seq_file *sf, void *v)
  {
        struct cgroup_subsys_state *css = seq_css(sf);
@@ -1786,6 +1815,16 @@ static struct cftype ve_cftypes[] = {
                .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,

Why signed value?

+       },
        {
                .name                   = "os_release",
                .max_write_len          = __NEW_UTS_LEN + 1,

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

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to