@@ -221,6 +221,8 @@ static struct cftype cgroup_legacy_base_files[];
221221
222222static int rebind_subsystems (struct cgroup_root * dst_root , u16 ss_mask );
223223static void cgroup_lock_and_drain_offline (struct cgroup * cgrp );
224+ static int cgroup_apply_control (struct cgroup * cgrp );
225+ static void cgroup_finalize_control (struct cgroup * cgrp , int ret );
224226static void css_task_iter_advance (struct css_task_iter * it );
225227static int cgroup_destroy_locked (struct cgroup * cgrp );
226228static struct cgroup_subsys_state * css_create (struct cgroup * cgrp ,
@@ -1160,13 +1162,13 @@ static void cgroup_destroy_root(struct cgroup_root *root)
11601162 struct cgroup * cgrp = & root -> cgrp ;
11611163 struct cgrp_cset_link * link , * tmp_link ;
11621164
1163- mutex_lock ( & cgroup_mutex );
1165+ cgroup_lock_and_drain_offline ( & cgrp_dfl_root . cgrp );
11641166
11651167 BUG_ON (atomic_read (& root -> nr_cgrps ));
11661168 BUG_ON (!list_empty (& cgrp -> self .children ));
11671169
11681170 /* Rebind all subsystems back to the default hierarchy */
1169- rebind_subsystems (& cgrp_dfl_root , root -> subsys_mask );
1171+ WARN_ON ( rebind_subsystems (& cgrp_dfl_root , root -> subsys_mask ) );
11701172
11711173 /*
11721174 * Release all the links from cset_links to this hierarchy's
@@ -1351,19 +1353,6 @@ static u16 cgroup_calc_subtree_ss_mask(struct cgroup *cgrp, u16 subtree_control)
13511353 return cur_ss_mask ;
13521354}
13531355
1354- /**
1355- * cgroup_refresh_subtree_ss_mask - update subtree_ss_mask
1356- * @cgrp: the target cgroup
1357- *
1358- * Update @cgrp->subtree_ss_mask according to the current
1359- * @cgrp->subtree_control using cgroup_calc_subtree_ss_mask().
1360- */
1361- static void cgroup_refresh_subtree_ss_mask (struct cgroup * cgrp )
1362- {
1363- cgrp -> subtree_ss_mask =
1364- cgroup_calc_subtree_ss_mask (cgrp , cgrp -> subtree_control );
1365- }
1366-
13671356/**
13681357 * cgroup_kn_unlock - unlocking helper for cgroup kernfs methods
13691358 * @kn: the kernfs_node being serviced
@@ -1459,12 +1448,10 @@ static void cgroup_rm_file(struct cgroup *cgrp, const struct cftype *cft)
14591448/**
14601449 * css_clear_dir - remove subsys files in a cgroup directory
14611450 * @css: taget css
1462- * @cgrp_override: specify if target cgroup is different from css->cgroup
14631451 */
1464- static void css_clear_dir (struct cgroup_subsys_state * css ,
1465- struct cgroup * cgrp_override )
1452+ static void css_clear_dir (struct cgroup_subsys_state * css )
14661453{
1467- struct cgroup * cgrp = cgrp_override ?: css -> cgroup ;
1454+ struct cgroup * cgrp = css -> cgroup ;
14681455 struct cftype * cfts ;
14691456
14701457 if (!(css -> flags & CSS_VISIBLE ))
@@ -1479,14 +1466,12 @@ static void css_clear_dir(struct cgroup_subsys_state *css,
14791466/**
14801467 * css_populate_dir - create subsys files in a cgroup directory
14811468 * @css: target css
1482- * @cgrp_overried: specify if target cgroup is different from css->cgroup
14831469 *
14841470 * On failure, no file is added.
14851471 */
1486- static int css_populate_dir (struct cgroup_subsys_state * css ,
1487- struct cgroup * cgrp_override )
1472+ static int css_populate_dir (struct cgroup_subsys_state * css )
14881473{
1489- struct cgroup * cgrp = cgrp_override ?: css -> cgroup ;
1474+ struct cgroup * cgrp = css -> cgroup ;
14901475 struct cftype * cfts , * failed_cfts ;
14911476 int ret ;
14921477
@@ -1526,7 +1511,6 @@ static int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask)
15261511{
15271512 struct cgroup * dcgrp = & dst_root -> cgrp ;
15281513 struct cgroup_subsys * ss ;
1529- u16 tmp_ss_mask ;
15301514 int ssid , i , ret ;
15311515
15321516 lockdep_assert_held (& cgroup_mutex );
@@ -1541,46 +1525,6 @@ static int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask)
15411525 return - EBUSY ;
15421526 } while_each_subsys_mask ();
15431527
1544- /* skip creating root files on dfl_root for inhibited subsystems */
1545- tmp_ss_mask = ss_mask ;
1546- if (dst_root == & cgrp_dfl_root )
1547- tmp_ss_mask &= ~cgrp_dfl_inhibit_ss_mask ;
1548-
1549- do_each_subsys_mask (ss , ssid , tmp_ss_mask ) {
1550- struct cgroup * scgrp = & ss -> root -> cgrp ;
1551- int tssid ;
1552-
1553- ret = css_populate_dir (cgroup_css (scgrp , ss ), dcgrp );
1554- if (!ret )
1555- continue ;
1556-
1557- /*
1558- * Rebinding back to the default root is not allowed to
1559- * fail. Using both default and non-default roots should
1560- * be rare. Moving subsystems back and forth even more so.
1561- * Just warn about it and continue.
1562- */
1563- if (dst_root == & cgrp_dfl_root ) {
1564- if (cgrp_dfl_visible ) {
1565- pr_warn ("failed to create files (%d) while rebinding 0x%x to default root\n" ,
1566- ret , ss_mask );
1567- pr_warn ("you may retry by moving them to a different hierarchy and unbinding\n" );
1568- }
1569- continue ;
1570- }
1571-
1572- do_each_subsys_mask (ss , tssid , tmp_ss_mask ) {
1573- if (tssid == ssid )
1574- break ;
1575- css_clear_dir (cgroup_css (scgrp , ss ), dcgrp );
1576- } while_each_subsys_mask ();
1577- return ret ;
1578- } while_each_subsys_mask ();
1579-
1580- /*
1581- * Nothing can fail from this point on. Remove files for the
1582- * removed subsystems and rebind each subsystem.
1583- */
15841528 do_each_subsys_mask (ss , ssid , ss_mask ) {
15851529 struct cgroup_root * src_root = ss -> root ;
15861530 struct cgroup * scgrp = & src_root -> cgrp ;
@@ -1589,8 +1533,12 @@ static int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask)
15891533
15901534 WARN_ON (!css || cgroup_css (dcgrp , ss ));
15911535
1592- css_clear_dir (css , NULL );
1536+ /* disable from the source */
1537+ src_root -> subsys_mask &= ~(1 << ssid );
1538+ WARN_ON (cgroup_apply_control (scgrp ));
1539+ cgroup_finalize_control (scgrp , 0 );
15931540
1541+ /* rebind */
15941542 RCU_INIT_POINTER (scgrp -> subsys [ssid ], NULL );
15951543 rcu_assign_pointer (dcgrp -> subsys [ssid ], css );
15961544 ss -> root = dst_root ;
@@ -1602,20 +1550,20 @@ static int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask)
16021550 & dcgrp -> e_csets [ss -> id ]);
16031551 spin_unlock_bh (& css_set_lock );
16041552
1605- src_root -> subsys_mask &= ~(1 << ssid );
1606- scgrp -> subtree_control &= ~(1 << ssid );
1607- cgroup_refresh_subtree_ss_mask (scgrp );
1608-
16091553 /* default hierarchy doesn't enable controllers by default */
16101554 dst_root -> subsys_mask |= 1 << ssid ;
16111555 if (dst_root == & cgrp_dfl_root ) {
16121556 static_branch_enable (cgroup_subsys_on_dfl_key [ssid ]);
16131557 } else {
16141558 dcgrp -> subtree_control |= 1 << ssid ;
1615- cgroup_refresh_subtree_ss_mask (dcgrp );
16161559 static_branch_disable (cgroup_subsys_on_dfl_key [ssid ]);
16171560 }
16181561
1562+ ret = cgroup_apply_control (dcgrp );
1563+ if (ret )
1564+ pr_warn ("partial failure to rebind %s controller (err=%d)\n" ,
1565+ ss -> name , ret );
1566+
16191567 if (ss -> bind )
16201568 ss -> bind (css );
16211569 } while_each_subsys_mask ();
@@ -1807,7 +1755,7 @@ static int cgroup_remount(struct kernfs_root *kf_root, int *flags, char *data)
18071755 return - EINVAL ;
18081756 }
18091757
1810- mutex_lock ( & cgroup_mutex );
1758+ cgroup_lock_and_drain_offline ( & cgrp_dfl_root . cgrp );
18111759
18121760 /* See what subsystems are wanted */
18131761 ret = parse_cgroupfs_options (data , & opts );
@@ -1840,7 +1788,7 @@ static int cgroup_remount(struct kernfs_root *kf_root, int *flags, char *data)
18401788 if (ret )
18411789 goto out_unlock ;
18421790
1843- rebind_subsystems (& cgrp_dfl_root , removed_mask );
1791+ WARN_ON ( rebind_subsystems (& cgrp_dfl_root , removed_mask ) );
18441792
18451793 if (opts .release_agent ) {
18461794 spin_lock (& release_agent_path_lock );
@@ -1991,7 +1939,7 @@ static int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask)
19911939 }
19921940 root_cgrp -> kn = root -> kf_root -> kn ;
19931941
1994- ret = css_populate_dir (& root_cgrp -> self , NULL );
1942+ ret = css_populate_dir (& root_cgrp -> self );
19951943 if (ret )
19961944 goto destroy_root ;
19971945
@@ -2070,7 +2018,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
20702018 goto out_mount ;
20712019 }
20722020
2073- mutex_lock ( & cgroup_mutex );
2021+ cgroup_lock_and_drain_offline ( & cgrp_dfl_root . cgrp );
20742022
20752023 /* First find the desired set of subsystems */
20762024 ret = parse_cgroupfs_options (data , & opts );
@@ -3123,7 +3071,7 @@ static int cgroup_apply_control_enable(struct cgroup *cgrp)
31233071 }
31243072
31253073 if (cgroup_control (dsct ) & (1 << ss -> id )) {
3126- ret = css_populate_dir (css , NULL );
3074+ ret = css_populate_dir (css );
31273075 if (ret )
31283076 return ret ;
31293077 }
@@ -3162,10 +3110,11 @@ static void cgroup_apply_control_disable(struct cgroup *cgrp)
31623110 if (!css )
31633111 continue ;
31643112
3165- if (!(cgroup_ss_mask (dsct ) & (1 << ss -> id ))) {
3113+ if (css -> parent &&
3114+ !(cgroup_ss_mask (dsct ) & (1 << ss -> id ))) {
31663115 kill_css (css );
31673116 } else if (!(cgroup_control (dsct ) & (1 << ss -> id ))) {
3168- css_clear_dir (css , NULL );
3117+ css_clear_dir (css );
31693118 if (ss -> css_reset )
31703119 ss -> css_reset (css );
31713120 }
@@ -5159,7 +5108,7 @@ static int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name,
51595108 if (ret )
51605109 goto out_destroy ;
51615110
5162- ret = css_populate_dir (& cgrp -> self , NULL );
5111+ ret = css_populate_dir (& cgrp -> self );
51635112 if (ret )
51645113 goto out_destroy ;
51655114
@@ -5231,7 +5180,7 @@ static void kill_css(struct cgroup_subsys_state *css)
52315180 * This must happen before css is disassociated with its cgroup.
52325181 * See seq_css() for details.
52335182 */
5234- css_clear_dir (css , NULL );
5183+ css_clear_dir (css );
52355184
52365185 /*
52375186 * Killing would put the base ref, but we need to keep it alive
0 commit comments