[Devel] [PATCH rh7] Port diff-fairsched-cpuset-add-fake-cpuset-for-containers
Vladimir Davydov
vdavydov at parallels.com
Sun May 31 10:03:15 PDT 2015
Author: Pavel Tikhomirov
Email: ptikhomirov at parallels.com
Subject: cpuset: add fake cpuset for containers
Date: Tue, 27 Jan 2015 15:40:12 +0300
If container want to write/read cpumask or nodemask of cpuset through
cgroupfs for incontainer cgroup, fake it - add special ve_* fields
to cpuset structure and operate with them. We don't want to validate
change as it is just fake, so allow any.
For flags, relax_domain_level, mem_migration_pending do not
allow access from container.
for docker integration-cli test: TestRunWithCpuset
https://jira.sw.ru/browse/PSBM-30878
v2: add for mems, cpus_allowed, mems_allowed; simplify checks in
update_cpumask/update_nodemask, no excessive code in alloc_trial_cpuset
and change naming for masks
v3: do not take the callback_mutex for printing ve_cpus_allowed,
do not permit r/w to cpuset_cpus_allowed, cpuset_mems_allowed,
add ve_flags and ve_relax_domain_level.
v4: leave only ve_cpus/mems_allowed, others are not faked,
block access to others from CT
v5: cleanup code
Signed-off-by: Pavel Tikhomirov <ptikhomirov at parallels.com>
Reviewed-by: Vladimir Davydov <vdavydov at parallels.com>
=============================================================================
Related to https://jira.sw.ru/browse/PSBM-33642
Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
kernel/cpuset.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 3c4355e07dc4..ef08c194288b 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -87,6 +87,9 @@ struct cpuset {
cpumask_var_t cpus_allowed; /* CPUs allowed to tasks in cpuset */
nodemask_t mems_allowed; /* Memory Nodes allowed to tasks */
+ cpumask_var_t ve_cpus_allowed;
+ nodemask_t ve_mems_allowed;
+
struct fmeter fmeter; /* memory_pressure filter */
/*
@@ -866,6 +869,15 @@ static int __update_cpumask(struct cpuset *cs,
if (cs == &top_cpuset)
return -EACCES;
+ /*
+ * If we are in CT use fake cpu mask
+ * can set and read, but no effect
+ */
+ if (!ve_is_super(get_exec_env())) {
+ cpumask_copy(cs->ve_cpus_allowed, cpus_allowed);
+ return 0;
+ }
+
if (!cpumask_subset(cpus_allowed, cpu_active_mask))
return -EINVAL;
@@ -1127,6 +1139,16 @@ static int __update_nodemask(struct cpuset *cs,
goto done;
}
+ /*
+ * If we are in CT use fake node mask
+ * can set and read, but no effect
+ */
+ if (!ve_is_super(get_exec_env())) {
+ cs->ve_mems_allowed = *mems_allowed;
+ retval = 0;
+ goto done;
+ }
+
if (!nodes_subset(*mems_allowed, node_states[N_MEMORY])) {
retval = -EINVAL;
goto done;
@@ -1563,6 +1585,9 @@ static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val)
cpuset_filetype_t type = cft->private;
int retval = 0;
+ if (!ve_is_super(get_exec_env()))
+ return -EACCES;
+
mutex_lock(&cpuset_mutex);
if (!is_cpuset_online(cs)) {
retval = -ENODEV;
@@ -1612,6 +1637,9 @@ static int cpuset_write_s64(struct cgroup *cgrp, struct cftype *cft, s64 val)
cpuset_filetype_t type = cft->private;
int retval = -ENODEV;
+ if (!ve_is_super(get_exec_env()))
+ return -EACCES;
+
mutex_lock(&cpuset_mutex);
if (!is_cpuset_online(cs))
goto out_unlock;
@@ -1693,6 +1721,9 @@ static size_t cpuset_sprintf_cpulist(char *page, struct cpuset *cs)
{
size_t count;
+ if (!ve_is_super(get_exec_env()))
+ return cpulist_scnprintf(page, PAGE_SIZE, cs->ve_cpus_allowed);
+
mutex_lock(&callback_mutex);
count = cpulist_scnprintf(page, PAGE_SIZE, cs->cpus_allowed);
mutex_unlock(&callback_mutex);
@@ -1704,6 +1735,9 @@ static size_t cpuset_sprintf_memlist(char *page, struct cpuset *cs)
{
size_t count;
+ if (!ve_is_super(get_exec_env()))
+ return nodelist_scnprintf(page, PAGE_SIZE, cs->ve_mems_allowed);
+
mutex_lock(&callback_mutex);
count = nodelist_scnprintf(page, PAGE_SIZE, cs->mems_allowed);
mutex_unlock(&callback_mutex);
@@ -1751,6 +1785,10 @@ static u64 cpuset_read_u64(struct cgroup *cont, struct cftype *cft)
{
struct cpuset *cs = cgroup_cs(cont);
cpuset_filetype_t type = cft->private;
+
+ if (!ve_is_super(get_exec_env()))
+ return 0;
+
switch (type) {
case FILE_CPU_EXCLUSIVE:
return is_cpu_exclusive(cs);
@@ -1782,6 +1820,10 @@ static s64 cpuset_read_s64(struct cgroup *cont, struct cftype *cft)
{
struct cpuset *cs = cgroup_cs(cont);
cpuset_filetype_t type = cft->private;
+
+ if (!ve_is_super(get_exec_env()))
+ return 0;
+
switch (type) {
case FILE_SCHED_RELAX_DOMAIN_LEVEL:
return cs->relax_domain_level;
@@ -1909,10 +1951,17 @@ static struct cgroup_subsys_state *cpuset_css_alloc(struct cgroup *cont)
kfree(cs);
return ERR_PTR(-ENOMEM);
}
+ if (!alloc_cpumask_var(&cs->ve_cpus_allowed, GFP_KERNEL)) {
+ free_cpumask_var(cs->cpus_allowed);
+ kfree(cs);
+ return ERR_PTR(-ENOMEM);
+ }
set_bit(CS_SCHED_LOAD_BALANCE, &cs->flags);
cpumask_clear(cs->cpus_allowed);
nodes_clear(cs->mems_allowed);
+ cpumask_clear(cs->ve_cpus_allowed);
+ nodes_clear(cs->ve_mems_allowed);
fmeter_init(&cs->fmeter);
INIT_WORK(&cs->hotplug_work, cpuset_propagate_hotplug_workfn);
cs->relax_domain_level = -1;
@@ -2000,6 +2049,7 @@ static void cpuset_css_free(struct cgroup *cont)
struct cpuset *cs = cgroup_cs(cont);
free_cpumask_var(cs->cpus_allowed);
+ free_cpumask_var(cs->ve_cpus_allowed);
kfree(cs);
}
@@ -2029,10 +2079,15 @@ int __init cpuset_init(void)
if (!alloc_cpumask_var(&top_cpuset.cpus_allowed, GFP_KERNEL))
BUG();
+ if (!alloc_cpumask_var(&top_cpuset.ve_cpus_allowed, GFP_KERNEL))
+ BUG();
cpumask_setall(top_cpuset.cpus_allowed);
nodes_setall(top_cpuset.mems_allowed);
+ cpumask_clear(top_cpuset.ve_cpus_allowed);
+ nodes_clear(top_cpuset.ve_mems_allowed);
+
fmeter_init(&top_cpuset.fmeter);
set_bit(CS_SCHED_LOAD_BALANCE, &top_cpuset.flags);
top_cpuset.relax_domain_level = -1;
--
2.1.4
More information about the Devel
mailing list