| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- From 40d641241a5399afc93d4eb75d8794f72fe3c0fb Mon Sep 17 00:00:00 2001
- From: Wolfgang Bumiller <[email protected]>
- Date: Wed, 21 Dec 2016 15:37:20 +0100
- Subject: [PATCH] cgroup, cpuset: add cpuset.remap_cpus
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- Changes a cpuset, recursively remapping all its descendants
- to the new range.
- Signed-off-by: Wolfgang Bumiller <[email protected]>
- Signed-off-by: Fabian Grünbichler <[email protected]>
- ---
- include/linux/cpumask.h | 17 ++++++++++++++++
- kernel/cpuset.c | 54 +++++++++++++++++++++++++++++++++++++++----------
- 2 files changed, 60 insertions(+), 11 deletions(-)
- diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
- index 59915ea..f5487c8 100644
- --- a/include/linux/cpumask.h
- +++ b/include/linux/cpumask.h
- @@ -514,6 +514,23 @@ static inline void cpumask_copy(struct cpumask *dstp,
- }
-
- /**
- + * cpumask_remap - *dstp = map(old, new)(*srcp)
- + * @dstp: the result
- + * @srcp: the input cpumask
- + * @oldp: the old mask
- + * @newp: the new mask
- + */
- +static inline void cpumask_remap(struct cpumask *dstp,
- + const struct cpumask *srcp,
- + const struct cpumask *oldp,
- + const struct cpumask *newp)
- +{
- + bitmap_remap(cpumask_bits(dstp), cpumask_bits(srcp),
- + cpumask_bits(oldp), cpumask_bits(newp),
- + nr_cpumask_bits);
- +}
- +
- +/**
- * cpumask_any - pick a "random" cpu from *srcp
- * @srcp: the input cpumask
- *
- diff --git a/kernel/cpuset.c b/kernel/cpuset.c
- index 7e78cfe..ff5ff3a 100644
- --- a/kernel/cpuset.c
- +++ b/kernel/cpuset.c
- @@ -462,7 +462,8 @@ static void free_trial_cpuset(struct cpuset *trial)
- * Return 0 if valid, -errno if not.
- */
-
- -static int validate_change(struct cpuset *cur, struct cpuset *trial)
- +static int validate_change(struct cpuset *cur, struct cpuset *trial,
- + int remap)
- {
- struct cgroup_subsys_state *css;
- struct cpuset *c, *par;
- @@ -470,11 +471,13 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial)
-
- rcu_read_lock();
-
- - /* Each of our child cpusets must be a subset of us */
- - ret = -EBUSY;
- - cpuset_for_each_child(c, css, cur)
- - if (!is_cpuset_subset(c, trial))
- - goto out;
- + if (!remap) {
- + /* Each of our child cpusets must be a subset of us */
- + ret = -EBUSY;
- + cpuset_for_each_child(c, css, cur)
- + if (!is_cpuset_subset(c, trial))
- + goto out;
- + }
-
- /* Remaining checks don't apply to root cpuset */
- ret = 0;
- @@ -937,11 +940,15 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus)
- * @cs: the cpuset to consider
- * @trialcs: trial cpuset
- * @buf: buffer of cpu numbers written to this cpuset
- + * @remap: recursively remap all child nodes
- */
- static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
- - const char *buf)
- + const char *buf, int remap)
- {
- int retval;
- + struct cpuset *cp;
- + struct cgroup_subsys_state *pos_css;
- + struct cpumask tempmask;
-
- /* top_cpuset.cpus_allowed tracks cpu_online_mask; it's read-only */
- if (cs == &top_cpuset)
- @@ -969,11 +976,25 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
- if (cpumask_equal(cs->cpus_allowed, trialcs->cpus_allowed))
- return 0;
-
- - retval = validate_change(cs, trialcs);
- + retval = validate_change(cs, trialcs, remap);
- if (retval < 0)
- return retval;
-
- spin_lock_irq(&callback_lock);
- + if (remap) {
- + rcu_read_lock();
- + cpuset_for_each_descendant_pre(cp, pos_css, cs) {
- + /* skip empty subtrees */
- + if (cpumask_empty(cp->cpus_allowed)) {
- + pos_css = css_rightmost_descendant(pos_css);
- + continue;
- + }
- + cpumask_copy(&tempmask, cp->cpus_allowed);
- + cpumask_remap(cp->cpus_allowed, &tempmask,
- + cs->cpus_allowed, trialcs->cpus_allowed);
- + }
- + rcu_read_unlock();
- + }
- cpumask_copy(cs->cpus_allowed, trialcs->cpus_allowed);
- spin_unlock_irq(&callback_lock);
-
- @@ -1250,7 +1271,7 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs,
- retval = 0; /* Too easy - nothing to do */
- goto done;
- }
- - retval = validate_change(cs, trialcs);
- + retval = validate_change(cs, trialcs, 0);
- if (retval < 0)
- goto done;
-
- @@ -1337,7 +1358,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
- else
- clear_bit(bit, &trialcs->flags);
-
- - err = validate_change(cs, trialcs);
- + err = validate_change(cs, trialcs, 0);
- if (err < 0)
- goto out;
-
- @@ -1596,6 +1617,7 @@ static void cpuset_attach(struct cgroup_taskset *tset)
- typedef enum {
- FILE_MEMORY_MIGRATE,
- FILE_CPULIST,
- + FILE_REMAP_CPULIST,
- FILE_MEMLIST,
- FILE_EFFECTIVE_CPULIST,
- FILE_EFFECTIVE_MEMLIST,
- @@ -1728,7 +1750,10 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
-
- switch (of_cft(of)->private) {
- case FILE_CPULIST:
- - retval = update_cpumask(cs, trialcs, buf);
- + retval = update_cpumask(cs, trialcs, buf, 0);
- + break;
- + case FILE_REMAP_CPULIST:
- + retval = update_cpumask(cs, trialcs, buf, 1);
- break;
- case FILE_MEMLIST:
- retval = update_nodemask(cs, trialcs, buf);
- @@ -1845,6 +1870,13 @@ static struct cftype files[] = {
- },
-
- {
- + .name = "remap_cpus",
- + .write = cpuset_write_resmask,
- + .max_write_len = (100U + 6 * NR_CPUS),
- + .private = FILE_REMAP_CPULIST,
- + },
- +
- + {
- .name = "mems",
- .seq_show = cpuset_common_seq_show,
- .write = cpuset_write_resmask,
- --
- 2.1.4
|