|
@@ -1023,19 +1023,6 @@ int current_cpuset_is_being_rebound(void)
|
|
return task_cs(current) == cpuset_being_rebound;
|
|
return task_cs(current) == cpuset_being_rebound;
|
|
}
|
|
}
|
|
|
|
|
|
-/*
|
|
|
|
- * Call with cgroup_mutex held.
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
-static int update_memory_pressure_enabled(struct cpuset *cs, char *buf)
|
|
|
|
-{
|
|
|
|
- if (simple_strtoul(buf, NULL, 10) != 0)
|
|
|
|
- cpuset_memory_pressure_enabled = 1;
|
|
|
|
- else
|
|
|
|
- cpuset_memory_pressure_enabled = 0;
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static int update_relax_domain_level(struct cpuset *cs, char *buf)
|
|
static int update_relax_domain_level(struct cpuset *cs, char *buf)
|
|
{
|
|
{
|
|
int val = simple_strtol(buf, NULL, 10);
|
|
int val = simple_strtol(buf, NULL, 10);
|
|
@@ -1063,15 +1050,13 @@ static int update_relax_domain_level(struct cpuset *cs, char *buf)
|
|
* Call with cgroup_mutex held.
|
|
* Call with cgroup_mutex held.
|
|
*/
|
|
*/
|
|
|
|
|
|
-static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
|
|
|
|
|
|
+static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
|
|
|
|
+ int turning_on)
|
|
{
|
|
{
|
|
- int turning_on;
|
|
|
|
struct cpuset trialcs;
|
|
struct cpuset trialcs;
|
|
int err;
|
|
int err;
|
|
int cpus_nonempty, balance_flag_changed;
|
|
int cpus_nonempty, balance_flag_changed;
|
|
|
|
|
|
- turning_on = (simple_strtoul(buf, NULL, 10) != 0);
|
|
|
|
-
|
|
|
|
trialcs = *cs;
|
|
trialcs = *cs;
|
|
if (turning_on)
|
|
if (turning_on)
|
|
set_bit(bit, &trialcs.flags);
|
|
set_bit(bit, &trialcs.flags);
|
|
@@ -1289,46 +1274,68 @@ static ssize_t cpuset_common_file_write(struct cgroup *cont,
|
|
case FILE_MEMLIST:
|
|
case FILE_MEMLIST:
|
|
retval = update_nodemask(cs, buffer);
|
|
retval = update_nodemask(cs, buffer);
|
|
break;
|
|
break;
|
|
|
|
+ case FILE_SCHED_RELAX_DOMAIN_LEVEL:
|
|
|
|
+ retval = update_relax_domain_level(cs, buffer);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ retval = -EINVAL;
|
|
|
|
+ goto out2;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (retval == 0)
|
|
|
|
+ retval = nbytes;
|
|
|
|
+out2:
|
|
|
|
+ cgroup_unlock();
|
|
|
|
+out1:
|
|
|
|
+ kfree(buffer);
|
|
|
|
+ return retval;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int cpuset_write_u64(struct cgroup *cgrp, struct cftype *cft, u64 val)
|
|
|
|
+{
|
|
|
|
+ int retval = 0;
|
|
|
|
+ struct cpuset *cs = cgroup_cs(cgrp);
|
|
|
|
+ cpuset_filetype_t type = cft->private;
|
|
|
|
+
|
|
|
|
+ cgroup_lock();
|
|
|
|
+
|
|
|
|
+ if (cgroup_is_removed(cgrp)) {
|
|
|
|
+ cgroup_unlock();
|
|
|
|
+ return -ENODEV;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ switch (type) {
|
|
case FILE_CPU_EXCLUSIVE:
|
|
case FILE_CPU_EXCLUSIVE:
|
|
- retval = update_flag(CS_CPU_EXCLUSIVE, cs, buffer);
|
|
|
|
|
|
+ retval = update_flag(CS_CPU_EXCLUSIVE, cs, val);
|
|
break;
|
|
break;
|
|
case FILE_MEM_EXCLUSIVE:
|
|
case FILE_MEM_EXCLUSIVE:
|
|
- retval = update_flag(CS_MEM_EXCLUSIVE, cs, buffer);
|
|
|
|
|
|
+ retval = update_flag(CS_MEM_EXCLUSIVE, cs, val);
|
|
break;
|
|
break;
|
|
case FILE_SCHED_LOAD_BALANCE:
|
|
case FILE_SCHED_LOAD_BALANCE:
|
|
- retval = update_flag(CS_SCHED_LOAD_BALANCE, cs, buffer);
|
|
|
|
- break;
|
|
|
|
- case FILE_SCHED_RELAX_DOMAIN_LEVEL:
|
|
|
|
- retval = update_relax_domain_level(cs, buffer);
|
|
|
|
|
|
+ retval = update_flag(CS_SCHED_LOAD_BALANCE, cs, val);
|
|
break;
|
|
break;
|
|
case FILE_MEMORY_MIGRATE:
|
|
case FILE_MEMORY_MIGRATE:
|
|
- retval = update_flag(CS_MEMORY_MIGRATE, cs, buffer);
|
|
|
|
|
|
+ retval = update_flag(CS_MEMORY_MIGRATE, cs, val);
|
|
break;
|
|
break;
|
|
case FILE_MEMORY_PRESSURE_ENABLED:
|
|
case FILE_MEMORY_PRESSURE_ENABLED:
|
|
- retval = update_memory_pressure_enabled(cs, buffer);
|
|
|
|
|
|
+ cpuset_memory_pressure_enabled = !!val;
|
|
break;
|
|
break;
|
|
case FILE_MEMORY_PRESSURE:
|
|
case FILE_MEMORY_PRESSURE:
|
|
retval = -EACCES;
|
|
retval = -EACCES;
|
|
break;
|
|
break;
|
|
case FILE_SPREAD_PAGE:
|
|
case FILE_SPREAD_PAGE:
|
|
- retval = update_flag(CS_SPREAD_PAGE, cs, buffer);
|
|
|
|
|
|
+ retval = update_flag(CS_SPREAD_PAGE, cs, val);
|
|
cs->mems_generation = cpuset_mems_generation++;
|
|
cs->mems_generation = cpuset_mems_generation++;
|
|
break;
|
|
break;
|
|
case FILE_SPREAD_SLAB:
|
|
case FILE_SPREAD_SLAB:
|
|
- retval = update_flag(CS_SPREAD_SLAB, cs, buffer);
|
|
|
|
|
|
+ retval = update_flag(CS_SPREAD_SLAB, cs, val);
|
|
cs->mems_generation = cpuset_mems_generation++;
|
|
cs->mems_generation = cpuset_mems_generation++;
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
retval = -EINVAL;
|
|
retval = -EINVAL;
|
|
- goto out2;
|
|
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
-
|
|
|
|
- if (retval == 0)
|
|
|
|
- retval = nbytes;
|
|
|
|
-out2:
|
|
|
|
cgroup_unlock();
|
|
cgroup_unlock();
|
|
-out1:
|
|
|
|
- kfree(buffer);
|
|
|
|
return retval;
|
|
return retval;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1390,33 +1397,9 @@ static ssize_t cpuset_common_file_read(struct cgroup *cont,
|
|
case FILE_MEMLIST:
|
|
case FILE_MEMLIST:
|
|
s += cpuset_sprintf_memlist(s, cs);
|
|
s += cpuset_sprintf_memlist(s, cs);
|
|
break;
|
|
break;
|
|
- case FILE_CPU_EXCLUSIVE:
|
|
|
|
- *s++ = is_cpu_exclusive(cs) ? '1' : '0';
|
|
|
|
- break;
|
|
|
|
- case FILE_MEM_EXCLUSIVE:
|
|
|
|
- *s++ = is_mem_exclusive(cs) ? '1' : '0';
|
|
|
|
- break;
|
|
|
|
- case FILE_SCHED_LOAD_BALANCE:
|
|
|
|
- *s++ = is_sched_load_balance(cs) ? '1' : '0';
|
|
|
|
- break;
|
|
|
|
case FILE_SCHED_RELAX_DOMAIN_LEVEL:
|
|
case FILE_SCHED_RELAX_DOMAIN_LEVEL:
|
|
s += sprintf(s, "%d", cs->relax_domain_level);
|
|
s += sprintf(s, "%d", cs->relax_domain_level);
|
|
break;
|
|
break;
|
|
- case FILE_MEMORY_MIGRATE:
|
|
|
|
- *s++ = is_memory_migrate(cs) ? '1' : '0';
|
|
|
|
- break;
|
|
|
|
- case FILE_MEMORY_PRESSURE_ENABLED:
|
|
|
|
- *s++ = cpuset_memory_pressure_enabled ? '1' : '0';
|
|
|
|
- break;
|
|
|
|
- case FILE_MEMORY_PRESSURE:
|
|
|
|
- s += sprintf(s, "%d", fmeter_getrate(&cs->fmeter));
|
|
|
|
- break;
|
|
|
|
- case FILE_SPREAD_PAGE:
|
|
|
|
- *s++ = is_spread_page(cs) ? '1' : '0';
|
|
|
|
- break;
|
|
|
|
- case FILE_SPREAD_SLAB:
|
|
|
|
- *s++ = is_spread_slab(cs) ? '1' : '0';
|
|
|
|
- break;
|
|
|
|
default:
|
|
default:
|
|
retval = -EINVAL;
|
|
retval = -EINVAL;
|
|
goto out;
|
|
goto out;
|
|
@@ -1429,8 +1412,31 @@ out:
|
|
return retval;
|
|
return retval;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+static u64 cpuset_read_u64(struct cgroup *cont, struct cftype *cft)
|
|
|
|
+{
|
|
|
|
+ struct cpuset *cs = cgroup_cs(cont);
|
|
|
|
+ cpuset_filetype_t type = cft->private;
|
|
|
|
+ switch (type) {
|
|
|
|
+ case FILE_CPU_EXCLUSIVE:
|
|
|
|
+ return is_cpu_exclusive(cs);
|
|
|
|
+ case FILE_MEM_EXCLUSIVE:
|
|
|
|
+ return is_mem_exclusive(cs);
|
|
|
|
+ case FILE_SCHED_LOAD_BALANCE:
|
|
|
|
+ return is_sched_load_balance(cs);
|
|
|
|
+ case FILE_MEMORY_MIGRATE:
|
|
|
|
+ return is_memory_migrate(cs);
|
|
|
|
+ case FILE_MEMORY_PRESSURE_ENABLED:
|
|
|
|
+ return cpuset_memory_pressure_enabled;
|
|
|
|
+ case FILE_MEMORY_PRESSURE:
|
|
|
|
+ return fmeter_getrate(&cs->fmeter);
|
|
|
|
+ case FILE_SPREAD_PAGE:
|
|
|
|
+ return is_spread_page(cs);
|
|
|
|
+ case FILE_SPREAD_SLAB:
|
|
|
|
+ return is_spread_slab(cs);
|
|
|
|
+ default:
|
|
|
|
+ BUG();
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1453,22 +1459,22 @@ static struct cftype cft_mems = {
|
|
|
|
|
|
static struct cftype cft_cpu_exclusive = {
|
|
static struct cftype cft_cpu_exclusive = {
|
|
.name = "cpu_exclusive",
|
|
.name = "cpu_exclusive",
|
|
- .read = cpuset_common_file_read,
|
|
|
|
- .write = cpuset_common_file_write,
|
|
|
|
|
|
+ .read_u64 = cpuset_read_u64,
|
|
|
|
+ .write_u64 = cpuset_write_u64,
|
|
.private = FILE_CPU_EXCLUSIVE,
|
|
.private = FILE_CPU_EXCLUSIVE,
|
|
};
|
|
};
|
|
|
|
|
|
static struct cftype cft_mem_exclusive = {
|
|
static struct cftype cft_mem_exclusive = {
|
|
.name = "mem_exclusive",
|
|
.name = "mem_exclusive",
|
|
- .read = cpuset_common_file_read,
|
|
|
|
- .write = cpuset_common_file_write,
|
|
|
|
|
|
+ .read_u64 = cpuset_read_u64,
|
|
|
|
+ .write_u64 = cpuset_write_u64,
|
|
.private = FILE_MEM_EXCLUSIVE,
|
|
.private = FILE_MEM_EXCLUSIVE,
|
|
};
|
|
};
|
|
|
|
|
|
static struct cftype cft_sched_load_balance = {
|
|
static struct cftype cft_sched_load_balance = {
|
|
.name = "sched_load_balance",
|
|
.name = "sched_load_balance",
|
|
- .read = cpuset_common_file_read,
|
|
|
|
- .write = cpuset_common_file_write,
|
|
|
|
|
|
+ .read_u64 = cpuset_read_u64,
|
|
|
|
+ .write_u64 = cpuset_write_u64,
|
|
.private = FILE_SCHED_LOAD_BALANCE,
|
|
.private = FILE_SCHED_LOAD_BALANCE,
|
|
};
|
|
};
|
|
|
|
|
|
@@ -1481,36 +1487,36 @@ static struct cftype cft_sched_relax_domain_level = {
|
|
|
|
|
|
static struct cftype cft_memory_migrate = {
|
|
static struct cftype cft_memory_migrate = {
|
|
.name = "memory_migrate",
|
|
.name = "memory_migrate",
|
|
- .read = cpuset_common_file_read,
|
|
|
|
- .write = cpuset_common_file_write,
|
|
|
|
|
|
+ .read_u64 = cpuset_read_u64,
|
|
|
|
+ .write_u64 = cpuset_write_u64,
|
|
.private = FILE_MEMORY_MIGRATE,
|
|
.private = FILE_MEMORY_MIGRATE,
|
|
};
|
|
};
|
|
|
|
|
|
static struct cftype cft_memory_pressure_enabled = {
|
|
static struct cftype cft_memory_pressure_enabled = {
|
|
.name = "memory_pressure_enabled",
|
|
.name = "memory_pressure_enabled",
|
|
- .read = cpuset_common_file_read,
|
|
|
|
- .write = cpuset_common_file_write,
|
|
|
|
|
|
+ .read_u64 = cpuset_read_u64,
|
|
|
|
+ .write_u64 = cpuset_write_u64,
|
|
.private = FILE_MEMORY_PRESSURE_ENABLED,
|
|
.private = FILE_MEMORY_PRESSURE_ENABLED,
|
|
};
|
|
};
|
|
|
|
|
|
static struct cftype cft_memory_pressure = {
|
|
static struct cftype cft_memory_pressure = {
|
|
.name = "memory_pressure",
|
|
.name = "memory_pressure",
|
|
- .read = cpuset_common_file_read,
|
|
|
|
- .write = cpuset_common_file_write,
|
|
|
|
|
|
+ .read_u64 = cpuset_read_u64,
|
|
|
|
+ .write_u64 = cpuset_write_u64,
|
|
.private = FILE_MEMORY_PRESSURE,
|
|
.private = FILE_MEMORY_PRESSURE,
|
|
};
|
|
};
|
|
|
|
|
|
static struct cftype cft_spread_page = {
|
|
static struct cftype cft_spread_page = {
|
|
.name = "memory_spread_page",
|
|
.name = "memory_spread_page",
|
|
- .read = cpuset_common_file_read,
|
|
|
|
- .write = cpuset_common_file_write,
|
|
|
|
|
|
+ .read_u64 = cpuset_read_u64,
|
|
|
|
+ .write_u64 = cpuset_write_u64,
|
|
.private = FILE_SPREAD_PAGE,
|
|
.private = FILE_SPREAD_PAGE,
|
|
};
|
|
};
|
|
|
|
|
|
static struct cftype cft_spread_slab = {
|
|
static struct cftype cft_spread_slab = {
|
|
.name = "memory_spread_slab",
|
|
.name = "memory_spread_slab",
|
|
- .read = cpuset_common_file_read,
|
|
|
|
- .write = cpuset_common_file_write,
|
|
|
|
|
|
+ .read_u64 = cpuset_read_u64,
|
|
|
|
+ .write_u64 = cpuset_write_u64,
|
|
.private = FILE_SPREAD_SLAB,
|
|
.private = FILE_SPREAD_SLAB,
|
|
};
|
|
};
|
|
|
|
|
|
@@ -1643,7 +1649,7 @@ static void cpuset_destroy(struct cgroup_subsys *ss, struct cgroup *cont)
|
|
cpuset_update_task_memory_state();
|
|
cpuset_update_task_memory_state();
|
|
|
|
|
|
if (is_sched_load_balance(cs))
|
|
if (is_sched_load_balance(cs))
|
|
- update_flag(CS_SCHED_LOAD_BALANCE, cs, "0");
|
|
|
|
|
|
+ update_flag(CS_SCHED_LOAD_BALANCE, cs, 0);
|
|
|
|
|
|
number_of_cpusets--;
|
|
number_of_cpusets--;
|
|
kfree(cs);
|
|
kfree(cs);
|