Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
rcu: create rcu_my_thread_group_empty() wrapper
memcg: css_id() must be called under rcu_read_lock()
cgroup: Check task_lock in task_subsys_state()
sched: Fix an RCU warning in print_task()
cgroup: Fix an RCU warning in alloc_css_id()
cgroup: Fix an RCU warning in cgroup_path()
KEYS: Fix an RCU warning in the reading of user keys
KEYS: Fix an RCU warning

+43 -10
+1
include/linux/cgroup.h
··· 530 530 { 531 531 return rcu_dereference_check(task->cgroups->subsys[subsys_id], 532 532 rcu_read_lock_held() || 533 + lockdep_is_held(&task->alloc_lock) || 533 534 cgroup_lock_is_held()); 534 535 } 535 536
+2
include/linux/rcupdate.h
··· 190 190 191 191 #ifdef CONFIG_PROVE_RCU 192 192 193 + extern int rcu_my_thread_group_empty(void); 194 + 193 195 /** 194 196 * rcu_dereference_check - rcu_dereference with debug checking 195 197 * @p: The pointer to read, prior to dereferencing
+11 -5
kernel/cgroup.c
··· 1646 1646 int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen) 1647 1647 { 1648 1648 char *start; 1649 - struct dentry *dentry = rcu_dereference(cgrp->dentry); 1649 + struct dentry *dentry = rcu_dereference_check(cgrp->dentry, 1650 + rcu_read_lock_held() || 1651 + cgroup_lock_is_held()); 1650 1652 1651 1653 if (!dentry || cgrp == dummytop) { 1652 1654 /* ··· 1664 1662 *--start = '\0'; 1665 1663 for (;;) { 1666 1664 int len = dentry->d_name.len; 1665 + 1667 1666 if ((start -= len) < buf) 1668 1667 return -ENAMETOOLONG; 1669 - memcpy(start, cgrp->dentry->d_name.name, len); 1668 + memcpy(start, dentry->d_name.name, len); 1670 1669 cgrp = cgrp->parent; 1671 1670 if (!cgrp) 1672 1671 break; 1673 - dentry = rcu_dereference(cgrp->dentry); 1672 + 1673 + dentry = rcu_dereference_check(cgrp->dentry, 1674 + rcu_read_lock_held() || 1675 + cgroup_lock_is_held()); 1674 1676 if (!cgrp->parent) 1675 1677 continue; 1676 1678 if (--start < buf) ··· 4561 4555 { 4562 4556 int subsys_id, i, depth = 0; 4563 4557 struct cgroup_subsys_state *parent_css, *child_css; 4564 - struct css_id *child_id, *parent_id = NULL; 4558 + struct css_id *child_id, *parent_id; 4565 4559 4566 4560 subsys_id = ss->subsys_id; 4567 4561 parent_css = parent->subsys[subsys_id]; 4568 4562 child_css = child->subsys[subsys_id]; 4569 - depth = css_depth(parent_css) + 1; 4570 4563 parent_id = parent_css->id; 4564 + depth = parent_id->depth; 4571 4565 4572 4566 child_id = get_new_cssid(ss, depth); 4573 4567 if (IS_ERR(child_id))
+11
kernel/rcupdate.c
··· 122 122 rcu = container_of(head, struct rcu_synchronize, head); 123 123 complete(&rcu->completion); 124 124 } 125 + 126 + #ifdef CONFIG_PROVE_RCU 127 + /* 128 + * wrapper function to avoid #include problems. 129 + */ 130 + int rcu_my_thread_group_empty(void) 131 + { 132 + return thread_group_empty(current); 133 + } 134 + EXPORT_SYMBOL_GPL(rcu_my_thread_group_empty); 135 + #endif /* #ifdef CONFIG_PROVE_RCU */
+2
kernel/sched_debug.c
··· 114 114 { 115 115 char path[64]; 116 116 117 + rcu_read_lock(); 117 118 cgroup_path(task_group(p)->css.cgroup, path, sizeof(path)); 119 + rcu_read_unlock(); 118 120 SEQ_printf(m, " %s", path); 119 121 } 120 122 #endif
+16 -5
mm/memcontrol.c
··· 811 811 * enabled in "curr" and "curr" is a child of "mem" in *cgroup* 812 812 * hierarchy(even if use_hierarchy is disabled in "mem"). 813 813 */ 814 + rcu_read_lock(); 814 815 if (mem->use_hierarchy) 815 816 ret = css_is_ancestor(&curr->css, &mem->css); 816 817 else 817 818 ret = (curr == mem); 819 + rcu_read_unlock(); 818 820 css_put(&curr->css); 819 821 return ret; 820 822 } ··· 2314 2312 2315 2313 /* record memcg information */ 2316 2314 if (do_swap_account && swapout && memcg) { 2315 + rcu_read_lock(); 2317 2316 swap_cgroup_record(ent, css_id(&memcg->css)); 2317 + rcu_read_unlock(); 2318 2318 mem_cgroup_get(memcg); 2319 2319 } 2320 2320 if (swapout && memcg) ··· 2373 2369 { 2374 2370 unsigned short old_id, new_id; 2375 2371 2372 + rcu_read_lock(); 2376 2373 old_id = css_id(&from->css); 2377 2374 new_id = css_id(&to->css); 2375 + rcu_read_unlock(); 2378 2376 2379 2377 if (swap_cgroup_cmpxchg(entry, old_id, new_id) == old_id) { 2380 2378 mem_cgroup_swap_statistics(from, false); ··· 4044 4038 put_page(page); 4045 4039 } 4046 4040 /* throught */ 4047 - if (ent.val && do_swap_account && !ret && 4048 - css_id(&mc.from->css) == lookup_swap_cgroup(ent)) { 4049 - ret = MC_TARGET_SWAP; 4050 - if (target) 4051 - target->ent = ent; 4041 + if (ent.val && do_swap_account && !ret) { 4042 + unsigned short id; 4043 + rcu_read_lock(); 4044 + id = css_id(&mc.from->css); 4045 + rcu_read_unlock(); 4046 + if (id == lookup_swap_cgroup(ent)) { 4047 + ret = MC_TARGET_SWAP; 4048 + if (target) 4049 + target->ent = ent; 4050 + } 4052 4051 } 4053 4052 return ret; 4054 4053 }