提交 9a9686b6 编写于 作者: L Li Zefan 提交者: Paul E. McKenney

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: NLi Zefan <lizf@cn.fujitsu.com>
Signed-off-by: NPaul E. McKenney <paulmck@linux.vnet.ibm.com>
上级 e35ec2d2
...@@ -1646,7 +1646,9 @@ static inline struct cftype *__d_cft(struct dentry *dentry) ...@@ -1646,7 +1646,9 @@ static inline struct cftype *__d_cft(struct dentry *dentry)
int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen) int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
{ {
char *start; char *start;
struct dentry *dentry = rcu_dereference(cgrp->dentry); struct dentry *dentry = rcu_dereference_check(cgrp->dentry,
rcu_read_lock_held() ||
cgroup_lock_is_held());
if (!dentry || cgrp == dummytop) { if (!dentry || cgrp == dummytop) {
/* /*
...@@ -1662,13 +1664,17 @@ int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen) ...@@ -1662,13 +1664,17 @@ int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
*--start = '\0'; *--start = '\0';
for (;;) { for (;;) {
int len = dentry->d_name.len; int len = dentry->d_name.len;
if ((start -= len) < buf) if ((start -= len) < buf)
return -ENAMETOOLONG; return -ENAMETOOLONG;
memcpy(start, cgrp->dentry->d_name.name, len); memcpy(start, dentry->d_name.name, len);
cgrp = cgrp->parent; cgrp = cgrp->parent;
if (!cgrp) if (!cgrp)
break; break;
dentry = rcu_dereference(cgrp->dentry);
dentry = rcu_dereference_check(cgrp->dentry,
rcu_read_lock_held() ||
cgroup_lock_is_held());
if (!cgrp->parent) if (!cgrp->parent)
continue; continue;
if (--start < buf) if (--start < buf)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册