|
@@ -4940,17 +4940,17 @@ void cgroup_post_fork(struct task_struct *child)
|
|
|
* and addition to css_set.
|
|
|
*/
|
|
|
if (need_forkexit_callback) {
|
|
|
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
|
|
|
+ /*
|
|
|
+ * fork/exit callbacks are supported only for builtin
|
|
|
+ * subsystems, and the builtin section of the subsys
|
|
|
+ * array is immutable, so we don't need to lock the
|
|
|
+ * subsys array here. On the other hand, modular section
|
|
|
+ * of the array can be freed at module unload, so we
|
|
|
+ * can't touch that.
|
|
|
+ */
|
|
|
+ for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) {
|
|
|
struct cgroup_subsys *ss = subsys[i];
|
|
|
|
|
|
- /*
|
|
|
- * fork/exit callbacks are supported only for
|
|
|
- * builtin subsystems and we don't need further
|
|
|
- * synchronization as they never go away.
|
|
|
- */
|
|
|
- if (!ss || ss->module)
|
|
|
- continue;
|
|
|
-
|
|
|
if (ss->fork)
|
|
|
ss->fork(child);
|
|
|
}
|
|
@@ -5015,13 +5015,13 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks)
|
|
|
tsk->cgroups = &init_css_set;
|
|
|
|
|
|
if (run_callbacks && need_forkexit_callback) {
|
|
|
- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
|
|
|
+ /*
|
|
|
+ * fork/exit callbacks are supported only for builtin
|
|
|
+ * subsystems, see cgroup_post_fork() for details.
|
|
|
+ */
|
|
|
+ for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) {
|
|
|
struct cgroup_subsys *ss = subsys[i];
|
|
|
|
|
|
- /* modular subsystems can't use callbacks */
|
|
|
- if (!ss || ss->module)
|
|
|
- continue;
|
|
|
-
|
|
|
if (ss->exit) {
|
|
|
struct cgroup *old_cgrp =
|
|
|
rcu_dereference_raw(cg->subsys[i])->cgroup;
|