فهرست منبع

Merge branch 'for-4.19-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup

Tejun writes:
  "cgroup fixes for v4.19-rc7

   One cgroup2 threaded mode fix for v4.19-rc7.  While threaded mode
   isn't used widely (yet) and the bug requires somewhat convoluted
   sequence of operations, it causes a userland visible malfunction -
   EINVAL on a valid attempt to enable threaded mode.  This pull request
   contains the fix"

* 'for-4.19-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup:
  cgroup: Fix dom_cgrp propagation when enabling threaded mode
Greg Kroah-Hartman 6 سال پیش
والد
کامیت
0778a9f2dd
2فایلهای تغییر یافته به همراه17 افزوده شده و 9 حذف شده
  1. 1 0
      include/linux/cgroup-defs.h
  2. 16 9
      kernel/cgroup/cgroup.c

+ 1 - 0
include/linux/cgroup-defs.h

@@ -412,6 +412,7 @@ struct cgroup {
 	 * specific task are charged to the dom_cgrp.
 	 * specific task are charged to the dom_cgrp.
 	 */
 	 */
 	struct cgroup *dom_cgrp;
 	struct cgroup *dom_cgrp;
+	struct cgroup *old_dom_cgrp;		/* used while enabling threaded */
 
 
 	/* per-cpu recursive resource statistics */
 	/* per-cpu recursive resource statistics */
 	struct cgroup_rstat_cpu __percpu *rstat_cpu;
 	struct cgroup_rstat_cpu __percpu *rstat_cpu;

+ 16 - 9
kernel/cgroup/cgroup.c

@@ -2836,11 +2836,12 @@ restart:
 }
 }
 
 
 /**
 /**
- * cgroup_save_control - save control masks of a subtree
+ * cgroup_save_control - save control masks and dom_cgrp of a subtree
  * @cgrp: root of the target subtree
  * @cgrp: root of the target subtree
  *
  *
- * Save ->subtree_control and ->subtree_ss_mask to the respective old_
- * prefixed fields for @cgrp's subtree including @cgrp itself.
+ * Save ->subtree_control, ->subtree_ss_mask and ->dom_cgrp to the
+ * respective old_ prefixed fields for @cgrp's subtree including @cgrp
+ * itself.
  */
  */
 static void cgroup_save_control(struct cgroup *cgrp)
 static void cgroup_save_control(struct cgroup *cgrp)
 {
 {
@@ -2850,6 +2851,7 @@ static void cgroup_save_control(struct cgroup *cgrp)
 	cgroup_for_each_live_descendant_pre(dsct, d_css, cgrp) {
 	cgroup_for_each_live_descendant_pre(dsct, d_css, cgrp) {
 		dsct->old_subtree_control = dsct->subtree_control;
 		dsct->old_subtree_control = dsct->subtree_control;
 		dsct->old_subtree_ss_mask = dsct->subtree_ss_mask;
 		dsct->old_subtree_ss_mask = dsct->subtree_ss_mask;
+		dsct->old_dom_cgrp = dsct->dom_cgrp;
 	}
 	}
 }
 }
 
 
@@ -2875,11 +2877,12 @@ static void cgroup_propagate_control(struct cgroup *cgrp)
 }
 }
 
 
 /**
 /**
- * cgroup_restore_control - restore control masks of a subtree
+ * cgroup_restore_control - restore control masks and dom_cgrp of a subtree
  * @cgrp: root of the target subtree
  * @cgrp: root of the target subtree
  *
  *
- * Restore ->subtree_control and ->subtree_ss_mask from the respective old_
- * prefixed fields for @cgrp's subtree including @cgrp itself.
+ * Restore ->subtree_control, ->subtree_ss_mask and ->dom_cgrp from the
+ * respective old_ prefixed fields for @cgrp's subtree including @cgrp
+ * itself.
  */
  */
 static void cgroup_restore_control(struct cgroup *cgrp)
 static void cgroup_restore_control(struct cgroup *cgrp)
 {
 {
@@ -2889,6 +2892,7 @@ static void cgroup_restore_control(struct cgroup *cgrp)
 	cgroup_for_each_live_descendant_post(dsct, d_css, cgrp) {
 	cgroup_for_each_live_descendant_post(dsct, d_css, cgrp) {
 		dsct->subtree_control = dsct->old_subtree_control;
 		dsct->subtree_control = dsct->old_subtree_control;
 		dsct->subtree_ss_mask = dsct->old_subtree_ss_mask;
 		dsct->subtree_ss_mask = dsct->old_subtree_ss_mask;
+		dsct->dom_cgrp = dsct->old_dom_cgrp;
 	}
 	}
 }
 }
 
 
@@ -3196,6 +3200,8 @@ static int cgroup_enable_threaded(struct cgroup *cgrp)
 {
 {
 	struct cgroup *parent = cgroup_parent(cgrp);
 	struct cgroup *parent = cgroup_parent(cgrp);
 	struct cgroup *dom_cgrp = parent->dom_cgrp;
 	struct cgroup *dom_cgrp = parent->dom_cgrp;
+	struct cgroup *dsct;
+	struct cgroup_subsys_state *d_css;
 	int ret;
 	int ret;
 
 
 	lockdep_assert_held(&cgroup_mutex);
 	lockdep_assert_held(&cgroup_mutex);
@@ -3225,12 +3231,13 @@ static int cgroup_enable_threaded(struct cgroup *cgrp)
 	 */
 	 */
 	cgroup_save_control(cgrp);
 	cgroup_save_control(cgrp);
 
 
-	cgrp->dom_cgrp = dom_cgrp;
+	cgroup_for_each_live_descendant_pre(dsct, d_css, cgrp)
+		if (dsct == cgrp || cgroup_is_threaded(dsct))
+			dsct->dom_cgrp = dom_cgrp;
+
 	ret = cgroup_apply_control(cgrp);
 	ret = cgroup_apply_control(cgrp);
 	if (!ret)
 	if (!ret)
 		parent->nr_threaded_children++;
 		parent->nr_threaded_children++;
-	else
-		cgrp->dom_cgrp = cgrp;
 
 
 	cgroup_finalize_control(cgrp, ret);
 	cgroup_finalize_control(cgrp, ret);
 	return ret;
 	return ret;