Commit 9a9686b634acc5cb6b7c601c171ae64af0318a24

Authored by Li Zefan
Committed by Paul E. McKenney
1 parent e35ec2d2c1

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>

Showing 1 changed file with 9 additions and 3 deletions Side-by-side Diff

... ... @@ -1646,7 +1646,9 @@
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 /*
1653 1655  
1654 1656  
... ... @@ -1662,13 +1664,17 @@
1662 1664 *--start = '\0';
1663 1665 for (;;) {
1664 1666 int len = dentry->d_name.len;
  1667 +
1665 1668 if ((start -= len) < buf)
1666 1669 return -ENAMETOOLONG;
1667   - memcpy(start, cgrp->dentry->d_name.name, len);
  1670 + memcpy(start, dentry->d_name.name, len);
1668 1671 cgrp = cgrp->parent;
1669 1672 if (!cgrp)
1670 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 1678 if (!cgrp->parent)
1673 1679 continue;
1674 1680 if (--start < buf)