cgroup-cpuset-add-cpuset.remap_cpus.patch 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. From 40d641241a5399afc93d4eb75d8794f72fe3c0fb Mon Sep 17 00:00:00 2001
  2. From: Wolfgang Bumiller <[email protected]>
  3. Date: Wed, 21 Dec 2016 15:37:20 +0100
  4. Subject: [PATCH] cgroup, cpuset: add cpuset.remap_cpus
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. Changes a cpuset, recursively remapping all its descendants
  9. to the new range.
  10. Signed-off-by: Wolfgang Bumiller <[email protected]>
  11. Signed-off-by: Fabian Grünbichler <[email protected]>
  12. ---
  13. include/linux/cpumask.h | 17 ++++++++++++++++
  14. kernel/cpuset.c | 54 +++++++++++++++++++++++++++++++++++++++----------
  15. 2 files changed, 60 insertions(+), 11 deletions(-)
  16. diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
  17. index 59915ea..f5487c8 100644
  18. --- a/include/linux/cpumask.h
  19. +++ b/include/linux/cpumask.h
  20. @@ -514,6 +514,23 @@ static inline void cpumask_copy(struct cpumask *dstp,
  21. }
  22. /**
  23. + * cpumask_remap - *dstp = map(old, new)(*srcp)
  24. + * @dstp: the result
  25. + * @srcp: the input cpumask
  26. + * @oldp: the old mask
  27. + * @newp: the new mask
  28. + */
  29. +static inline void cpumask_remap(struct cpumask *dstp,
  30. + const struct cpumask *srcp,
  31. + const struct cpumask *oldp,
  32. + const struct cpumask *newp)
  33. +{
  34. + bitmap_remap(cpumask_bits(dstp), cpumask_bits(srcp),
  35. + cpumask_bits(oldp), cpumask_bits(newp),
  36. + nr_cpumask_bits);
  37. +}
  38. +
  39. +/**
  40. * cpumask_any - pick a "random" cpu from *srcp
  41. * @srcp: the input cpumask
  42. *
  43. diff --git a/kernel/cpuset.c b/kernel/cpuset.c
  44. index 7e78cfe..ff5ff3a 100644
  45. --- a/kernel/cpuset.c
  46. +++ b/kernel/cpuset.c
  47. @@ -462,7 +462,8 @@ static void free_trial_cpuset(struct cpuset *trial)
  48. * Return 0 if valid, -errno if not.
  49. */
  50. -static int validate_change(struct cpuset *cur, struct cpuset *trial)
  51. +static int validate_change(struct cpuset *cur, struct cpuset *trial,
  52. + int remap)
  53. {
  54. struct cgroup_subsys_state *css;
  55. struct cpuset *c, *par;
  56. @@ -470,11 +471,13 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial)
  57. rcu_read_lock();
  58. - /* Each of our child cpusets must be a subset of us */
  59. - ret = -EBUSY;
  60. - cpuset_for_each_child(c, css, cur)
  61. - if (!is_cpuset_subset(c, trial))
  62. - goto out;
  63. + if (!remap) {
  64. + /* Each of our child cpusets must be a subset of us */
  65. + ret = -EBUSY;
  66. + cpuset_for_each_child(c, css, cur)
  67. + if (!is_cpuset_subset(c, trial))
  68. + goto out;
  69. + }
  70. /* Remaining checks don't apply to root cpuset */
  71. ret = 0;
  72. @@ -937,11 +940,15 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus)
  73. * @cs: the cpuset to consider
  74. * @trialcs: trial cpuset
  75. * @buf: buffer of cpu numbers written to this cpuset
  76. + * @remap: recursively remap all child nodes
  77. */
  78. static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
  79. - const char *buf)
  80. + const char *buf, int remap)
  81. {
  82. int retval;
  83. + struct cpuset *cp;
  84. + struct cgroup_subsys_state *pos_css;
  85. + struct cpumask tempmask;
  86. /* top_cpuset.cpus_allowed tracks cpu_online_mask; it's read-only */
  87. if (cs == &top_cpuset)
  88. @@ -969,11 +976,25 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs,
  89. if (cpumask_equal(cs->cpus_allowed, trialcs->cpus_allowed))
  90. return 0;
  91. - retval = validate_change(cs, trialcs);
  92. + retval = validate_change(cs, trialcs, remap);
  93. if (retval < 0)
  94. return retval;
  95. spin_lock_irq(&callback_lock);
  96. + if (remap) {
  97. + rcu_read_lock();
  98. + cpuset_for_each_descendant_pre(cp, pos_css, cs) {
  99. + /* skip empty subtrees */
  100. + if (cpumask_empty(cp->cpus_allowed)) {
  101. + pos_css = css_rightmost_descendant(pos_css);
  102. + continue;
  103. + }
  104. + cpumask_copy(&tempmask, cp->cpus_allowed);
  105. + cpumask_remap(cp->cpus_allowed, &tempmask,
  106. + cs->cpus_allowed, trialcs->cpus_allowed);
  107. + }
  108. + rcu_read_unlock();
  109. + }
  110. cpumask_copy(cs->cpus_allowed, trialcs->cpus_allowed);
  111. spin_unlock_irq(&callback_lock);
  112. @@ -1250,7 +1271,7 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs,
  113. retval = 0; /* Too easy - nothing to do */
  114. goto done;
  115. }
  116. - retval = validate_change(cs, trialcs);
  117. + retval = validate_change(cs, trialcs, 0);
  118. if (retval < 0)
  119. goto done;
  120. @@ -1337,7 +1358,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
  121. else
  122. clear_bit(bit, &trialcs->flags);
  123. - err = validate_change(cs, trialcs);
  124. + err = validate_change(cs, trialcs, 0);
  125. if (err < 0)
  126. goto out;
  127. @@ -1596,6 +1617,7 @@ static void cpuset_attach(struct cgroup_taskset *tset)
  128. typedef enum {
  129. FILE_MEMORY_MIGRATE,
  130. FILE_CPULIST,
  131. + FILE_REMAP_CPULIST,
  132. FILE_MEMLIST,
  133. FILE_EFFECTIVE_CPULIST,
  134. FILE_EFFECTIVE_MEMLIST,
  135. @@ -1728,7 +1750,10 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
  136. switch (of_cft(of)->private) {
  137. case FILE_CPULIST:
  138. - retval = update_cpumask(cs, trialcs, buf);
  139. + retval = update_cpumask(cs, trialcs, buf, 0);
  140. + break;
  141. + case FILE_REMAP_CPULIST:
  142. + retval = update_cpumask(cs, trialcs, buf, 1);
  143. break;
  144. case FILE_MEMLIST:
  145. retval = update_nodemask(cs, trialcs, buf);
  146. @@ -1845,6 +1870,13 @@ static struct cftype files[] = {
  147. },
  148. {
  149. + .name = "remap_cpus",
  150. + .write = cpuset_write_resmask,
  151. + .max_write_len = (100U + 6 * NR_CPUS),
  152. + .private = FILE_REMAP_CPULIST,
  153. + },
  154. +
  155. + {
  156. .name = "mems",
  157. .seq_show = cpuset_common_seq_show,
  158. .write = cpuset_write_resmask,
  159. --
  160. 2.1.4