[Devel] [PATCH RH7 2/2] cgroup/net_cls: virtualize ifpriomap per-ve
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Fri Aug 13 19:02:14 MSK 2021
Also make net_prio.ifpriomap writable in ve.
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
net/core/netprio_cgroup.c | 74 +++++++++++++++++++++++++++++++++++++--
1 file changed, 72 insertions(+), 2 deletions(-)
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index 0d2180df669c..901d3b93b44c 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -24,6 +24,7 @@
#include <net/pkt_cls.h>
#include <net/sock.h>
#include <net/netprio_cgroup.h>
+#include <linux/ve.h>
#include <linux/fdtable.h>
@@ -144,6 +145,7 @@ static struct cgroup_subsys_state *cgrp_css_alloc(struct cgroup *cgrp)
static int cgrp_css_online(struct cgroup *cgrp)
{
struct cgroup *parent = cgrp->parent;
+ struct ve_struct *ve;
struct net_device *dev;
int ret = 0;
@@ -162,6 +164,39 @@ static int cgrp_css_online(struct cgroup *cgrp)
if (ret)
break;
}
+
+ /* get_exec_env is safe under cgroup_mutex */
+ lockdep_assert_held(&cgroup_mutex);
+ ve = get_exec_env();
+ /*
+ * Inherit prios from the parent cgroup in scope of ve init netns.
+ */
+ if (!ve_is_super(ve)) {
+ struct nsproxy *ve_ns;
+ struct net *net = NULL;
+
+ /*
+ * Take rcu read lock to check that ve's net is not freed under
+ * us after we release rcu read lock we still have rtnl lock to
+ * insure net remains non-freed, pairs with rtnl lock in
+ * cleanup_net().
+ */
+ rcu_read_lock();
+ ve_ns = rcu_dereference(ve->ve_ns);
+ if (ve_ns)
+ net = ve_ns->net_ns;
+ rcu_read_unlock();
+
+ if (net && net != &init_net) {
+ for_each_netdev(net, dev) {
+ u32 prio = netprio_prio(parent, dev);
+
+ ret = netprio_set_prio(cgrp, dev, prio);
+ if (ret)
+ break;
+ }
+ }
+ }
rtnl_unlock();
return ret;
}
@@ -179,18 +214,37 @@ static u64 read_prioidx(struct cgroup *cgrp, struct cftype *cft)
static int read_priomap(struct cgroup *cont, struct cftype *cft,
struct cgroup_map_cb *cb)
{
+ struct ve_struct *ve;
+ struct net *net, *_net = NULL;
struct net_device *dev;
+ ve = get_curr_ve();
+ if (!ve_is_super(ve)) {
+ struct nsproxy *ve_ns;
+
+ rcu_read_lock();
+ ve_ns = rcu_dereference(ve->ve_ns);
+ if (ve_ns)
+ _net = get_net(ve_ns->net_ns);
+ rcu_read_unlock();
+ }
+ put_ve(ve);
+
+ net = _net ? : &init_net;
rcu_read_lock();
- for_each_netdev_rcu(&init_net, dev)
+ for_each_netdev_rcu(net, dev)
cb->fill(cb, dev->name, netprio_prio(cont, dev));
rcu_read_unlock();
+ if (_net)
+ put_net(_net);
return 0;
}
static int write_priomap(struct cgroup *cgrp, struct cftype *cft,
const char *buffer)
{
+ struct ve_struct *ve;
+ struct net *net, *_net = NULL;
char devname[IFNAMSIZ + 1];
struct net_device *dev;
u32 prio;
@@ -199,7 +253,22 @@ static int write_priomap(struct cgroup *cgrp, struct cftype *cft,
if (sscanf(buffer, "%"__stringify(IFNAMSIZ)"s %u", devname, &prio) != 2)
return -EINVAL;
- dev = dev_get_by_name(&init_net, devname);
+ ve = get_curr_ve();
+ if (!ve_is_super(ve)) {
+ struct nsproxy *ve_ns;
+
+ rcu_read_lock();
+ ve_ns = rcu_dereference(ve->ve_ns);
+ if (ve_ns)
+ _net = get_net(ve_ns->net_ns);
+ rcu_read_unlock();
+ }
+ put_ve(ve);
+
+ net = _net ? : &init_net;
+ dev = dev_get_by_name(net, devname);
+ if (_net)
+ put_net(_net);
if (!dev)
return -ENODEV;
@@ -241,6 +310,7 @@ static struct cftype ss_files[] = {
},
{
.name = "ifpriomap",
+ .flags = CFTYPE_VE_WRITABLE,
.read_map = read_priomap,
.write_string = write_priomap,
},
--
2.31.1
More information about the Devel
mailing list