aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-12-11 08:18:45 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-12-11 08:18:45 -0500
commit9374020a78fce13a1cf2edf3d26f6dd7231b5c3d (patch)
tree50c8629e6c6222c5b9681506b52afbde818c5e56 /kernel/cgroup.c
parentd2a0db1ee01aea154ccc460e45a16857e32c4427 (diff)
parent29594404d7fe73cd80eaa4ee8c43dcc53970c60e (diff)
Merge tag 'v3.7' into v4l_for_linus
Linux 3.7 * tag 'v3.7': (1545 commits) Linux 3.7 Input: matrix-keymap - provide proper module license Revert "revert "Revert "mm: remove __GFP_NO_KSWAPD""" and associated damage ipv4: ip_check_defrag must not modify skb before unsharing Revert "mm: avoid waking kswapd for THP allocations when compaction is deferred or contended" inet_diag: validate port comparison byte code to prevent unsafe reads inet_diag: avoid unsafe and nonsensical prefix matches in inet_diag_bc_run() inet_diag: validate byte code to prevent oops in inet_diag_bc_run() inet_diag: fix oops for IPv4 AF_INET6 TCP SYN-RECV state mm: vmscan: fix inappropriate zone congestion clearing vfs: fix O_DIRECT read past end of block device net: gro: fix possible panic in skb_gro_receive() tcp: bug fix Fast Open client retransmission tmpfs: fix shared mempolicy leak mm: vmscan: do not keep kswapd looping forever due to individual uncompactable zones mm: compaction: validate pfn range passed to isolate_freepages_block mmc: sh-mmcif: avoid oops on spurious interrupts (second try) Revert misapplied "mmc: sh-mmcif: avoid oops on spurious interrupts" mmc: sdhci-s3c: fix missing clock for gpio card-detect lib/Makefile: Fix oid_registry build dependency ...
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c41
1 files changed, 10 insertions, 31 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 13774b3b39aa..f24f724620dd 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1962,9 +1962,8 @@ static void cgroup_task_migrate(struct cgroup *cgrp, struct cgroup *oldcgrp,
1962 * trading it for newcg is protected by cgroup_mutex, we're safe to drop 1962 * trading it for newcg is protected by cgroup_mutex, we're safe to drop
1963 * it here; it will be freed under RCU. 1963 * it here; it will be freed under RCU.
1964 */ 1964 */
1965 put_css_set(oldcg);
1966
1967 set_bit(CGRP_RELEASABLE, &oldcgrp->flags); 1965 set_bit(CGRP_RELEASABLE, &oldcgrp->flags);
1966 put_css_set(oldcg);
1968} 1967}
1969 1968
1970/** 1969/**
@@ -4815,31 +4814,20 @@ static const struct file_operations proc_cgroupstats_operations = {
4815 * 4814 *
4816 * A pointer to the shared css_set was automatically copied in 4815 * A pointer to the shared css_set was automatically copied in
4817 * fork.c by dup_task_struct(). However, we ignore that copy, since 4816 * fork.c by dup_task_struct(). However, we ignore that copy, since
4818 * it was not made under the protection of RCU, cgroup_mutex or 4817 * it was not made under the protection of RCU or cgroup_mutex, so
4819 * threadgroup_change_begin(), so it might no longer be a valid 4818 * might no longer be a valid cgroup pointer. cgroup_attach_task() might
4820 * cgroup pointer. cgroup_attach_task() might have already changed 4819 * have already changed current->cgroups, allowing the previously
4821 * current->cgroups, allowing the previously referenced cgroup 4820 * referenced cgroup group to be removed and freed.
4822 * group to be removed and freed.
4823 *
4824 * Outside the pointer validity we also need to process the css_set
4825 * inheritance between threadgoup_change_begin() and
4826 * threadgoup_change_end(), this way there is no leak in any process
4827 * wide migration performed by cgroup_attach_proc() that could otherwise
4828 * miss a thread because it is too early or too late in the fork stage.
4829 * 4821 *
4830 * At the point that cgroup_fork() is called, 'current' is the parent 4822 * At the point that cgroup_fork() is called, 'current' is the parent
4831 * task, and the passed argument 'child' points to the child task. 4823 * task, and the passed argument 'child' points to the child task.
4832 */ 4824 */
4833void cgroup_fork(struct task_struct *child) 4825void cgroup_fork(struct task_struct *child)
4834{ 4826{
4835 /* 4827 task_lock(current);
4836 * We don't need to task_lock() current because current->cgroups
4837 * can't be changed concurrently here. The parent obviously hasn't
4838 * exited and called cgroup_exit(), and we are synchronized against
4839 * cgroup migration through threadgroup_change_begin().
4840 */
4841 child->cgroups = current->cgroups; 4828 child->cgroups = current->cgroups;
4842 get_css_set(child->cgroups); 4829 get_css_set(child->cgroups);
4830 task_unlock(current);
4843 INIT_LIST_HEAD(&child->cg_list); 4831 INIT_LIST_HEAD(&child->cg_list);
4844} 4832}
4845 4833
@@ -4895,19 +4883,10 @@ void cgroup_post_fork(struct task_struct *child)
4895 */ 4883 */
4896 if (use_task_css_set_links) { 4884 if (use_task_css_set_links) {
4897 write_lock(&css_set_lock); 4885 write_lock(&css_set_lock);
4898 if (list_empty(&child->cg_list)) { 4886 task_lock(child);
4899 /* 4887 if (list_empty(&child->cg_list))
4900 * It's safe to use child->cgroups without task_lock()
4901 * here because we are protected through
4902 * threadgroup_change_begin() against concurrent
4903 * css_set change in cgroup_task_migrate(). Also
4904 * the task can't exit at that point until
4905 * wake_up_new_task() is called, so we are protected
4906 * against cgroup_exit() setting child->cgroup to
4907 * init_css_set.
4908 */
4909 list_add(&child->cg_list, &child->cgroups->tasks); 4888 list_add(&child->cg_list, &child->cgroups->tasks);
4910 } 4889 task_unlock(child);
4911 write_unlock(&css_set_lock); 4890 write_unlock(&css_set_lock);
4912 } 4891 }
4913} 4892}