Skip to content

Commit b5ba75b

Browse files
committed
cgroup: simplify threadgroup locking
Now that threadgroup locking is made global, code paths around it can be simplified. * lock-verify-unlock-retry dancing removed from __cgroup_procs_write(). * Race protection against de_thread() removed from cgroup_update_dfl_csses(). Signed-off-by: Tejun Heo <[email protected]>
1 parent d59cfc0 commit b5ba75b

File tree

1 file changed

+13
-35
lines changed

1 file changed

+13
-35
lines changed

kernel/cgroup.c

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2402,14 +2402,13 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf,
24022402
if (!cgrp)
24032403
return -ENODEV;
24042404

2405-
retry_find_task:
2405+
percpu_down_write(&cgroup_threadgroup_rwsem);
24062406
rcu_read_lock();
24072407
if (pid) {
24082408
tsk = find_task_by_vpid(pid);
24092409
if (!tsk) {
2410-
rcu_read_unlock();
24112410
ret = -ESRCH;
2412-
goto out_unlock_cgroup;
2411+
goto out_unlock_rcu;
24132412
}
24142413
/*
24152414
* even if we're attaching all tasks in the thread group, we
@@ -2419,9 +2418,8 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf,
24192418
if (!uid_eq(cred->euid, GLOBAL_ROOT_UID) &&
24202419
!uid_eq(cred->euid, tcred->uid) &&
24212420
!uid_eq(cred->euid, tcred->suid)) {
2422-
rcu_read_unlock();
24232421
ret = -EACCES;
2424-
goto out_unlock_cgroup;
2422+
goto out_unlock_rcu;
24252423
}
24262424
} else
24272425
tsk = current;
@@ -2436,35 +2434,21 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf,
24362434
*/
24372435
if (tsk == kthreadd_task || (tsk->flags & PF_NO_SETAFFINITY)) {
24382436
ret = -EINVAL;
2439-
rcu_read_unlock();
2440-
goto out_unlock_cgroup;
2437+
goto out_unlock_rcu;
24412438
}
24422439

24432440
get_task_struct(tsk);
24442441
rcu_read_unlock();
24452442

2446-
percpu_down_write(&cgroup_threadgroup_rwsem);
2447-
if (threadgroup) {
2448-
if (!thread_group_leader(tsk)) {
2449-
/*
2450-
* a race with de_thread from another thread's exec()
2451-
* may strip us of our leadership, if this happens,
2452-
* there is no choice but to throw this task away and
2453-
* try again; this is
2454-
* "double-double-toil-and-trouble-check locking".
2455-
*/
2456-
percpu_up_write(&cgroup_threadgroup_rwsem);
2457-
put_task_struct(tsk);
2458-
goto retry_find_task;
2459-
}
2460-
}
2461-
24622443
ret = cgroup_attach_task(cgrp, tsk, threadgroup);
24632444

2464-
percpu_up_write(&cgroup_threadgroup_rwsem);
2465-
24662445
put_task_struct(tsk);
2467-
out_unlock_cgroup:
2446+
goto out_unlock_threadgroup;
2447+
2448+
out_unlock_rcu:
2449+
rcu_read_unlock();
2450+
out_unlock_threadgroup:
2451+
percpu_up_write(&cgroup_threadgroup_rwsem);
24682452
cgroup_kn_unlock(of->kn);
24692453
return ret ?: nbytes;
24702454
}
@@ -2611,6 +2595,8 @@ static int cgroup_update_dfl_csses(struct cgroup *cgrp)
26112595

26122596
lockdep_assert_held(&cgroup_mutex);
26132597

2598+
percpu_down_write(&cgroup_threadgroup_rwsem);
2599+
26142600
/* look up all csses currently attached to @cgrp's subtree */
26152601
down_read(&css_set_rwsem);
26162602
css_for_each_descendant_pre(css, cgroup_css(cgrp, NULL)) {
@@ -2666,17 +2652,8 @@ static int cgroup_update_dfl_csses(struct cgroup *cgrp)
26662652
goto out_finish;
26672653
last_task = task;
26682654

2669-
percpu_down_write(&cgroup_threadgroup_rwsem);
2670-
/* raced against de_thread() from another thread? */
2671-
if (!thread_group_leader(task)) {
2672-
percpu_up_write(&cgroup_threadgroup_rwsem);
2673-
put_task_struct(task);
2674-
continue;
2675-
}
2676-
26772655
ret = cgroup_migrate(src_cset->dfl_cgrp, task, true);
26782656

2679-
percpu_up_write(&cgroup_threadgroup_rwsem);
26802657
put_task_struct(task);
26812658

26822659
if (WARN(ret, "cgroup: failed to update controllers for the default hierarchy (%d), further operations may crash or hang\n", ret))
@@ -2686,6 +2663,7 @@ static int cgroup_update_dfl_csses(struct cgroup *cgrp)
26862663

26872664
out_finish:
26882665
cgroup_migrate_finish(&preloaded_csets);
2666+
percpu_up_write(&cgroup_threadgroup_rwsem);
26892667
return ret;
26902668
}
26912669

0 commit comments

Comments
 (0)