diff options
| author | Li Zefan <lizf@cn.fujitsu.com> | 2010-04-22 05:29:24 -0400 |
|---|---|---|
| committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2010-05-04 12:24:59 -0400 |
| commit | 9a9686b634acc5cb6b7c601c171ae64af0318a24 (patch) | |
| tree | 4a8431117018d8883c6d34d5c06f2eff99dcfed6 /kernel | |
| parent | e35ec2d2c1fc45dd3e46dde74bb0c4c4366125bf (diff) | |
cgroup: Fix an RCU warning in cgroup_path()
with CONFIG_PROVE_RCU=y, a warning can be triggered:
# mount -t cgroup -o debug xxx /mnt
# cat /proc/$$/cgroup
...
kernel/cgroup.c:1649 invoked rcu_dereference_check() without protection!
...
This is a false-positive, because cgroup_path() can be called
with either rcu_read_lock() held or cgroup_mutex held.
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/cgroup.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index e2769e13980c..4ca928db890c 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
| @@ -1646,7 +1646,9 @@ static inline struct cftype *__d_cft(struct dentry *dentry) | |||
| 1646 | int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen) | 1646 | int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen) |
| 1647 | { | 1647 | { |
| 1648 | char *start; | 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 | if (!dentry || cgrp == dummytop) { | 1653 | if (!dentry || cgrp == dummytop) { |
| 1652 | /* | 1654 | /* |
| @@ -1662,13 +1664,17 @@ int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen) | |||
| 1662 | *--start = '\0'; | 1664 | *--start = '\0'; |
| 1663 | for (;;) { | 1665 | for (;;) { |
| 1664 | int len = dentry->d_name.len; | 1666 | int len = dentry->d_name.len; |
| 1667 | |||
| 1665 | if ((start -= len) < buf) | 1668 | if ((start -= len) < buf) |
| 1666 | return -ENAMETOOLONG; | 1669 | return -ENAMETOOLONG; |
| 1667 | memcpy(start, cgrp->dentry->d_name.name, len); | 1670 | memcpy(start, dentry->d_name.name, len); |
| 1668 | cgrp = cgrp->parent; | 1671 | cgrp = cgrp->parent; |
| 1669 | if (!cgrp) | 1672 | if (!cgrp) |
| 1670 | break; | 1673 | break; |
| 1671 | dentry = rcu_dereference(cgrp->dentry); | 1674 | |
| 1675 | dentry = rcu_dereference_check(cgrp->dentry, | ||
| 1676 | rcu_read_lock_held() || | ||
| 1677 | cgroup_lock_is_held()); | ||
| 1672 | if (!cgrp->parent) | 1678 | if (!cgrp->parent) |
| 1673 | continue; | 1679 | continue; |
| 1674 | if (--start < buf) | 1680 | if (--start < buf) |
