Re: [PATCH 2/2] cgroup: check cgroup liveliness before unbreaking kernfs protection

2014-09-02 Thread Tejun Heo
On Tue, Sep 02, 2014 at 06:57:54PM +0800, Li Zefan wrote:
> diff --git a/kernel/cgroup.c b/kernel/cgroup.c
> index e03fc62..c8d07e5 100644
> --- a/kernel/cgroup.c
> +++ b/kernel/cgroup.c
> @@ -1025,6 +1025,11 @@ static umode_t cgroup_file_mode(const struct cftype 
> *cft)
>   return mode;
>  }
>  
> +static bool cgroup_tryget(struct cgroup *cgrp)
> +{
> + return css_tryget(>self);
> +}

Can you please move this right below cgroup_get() definition?

Thanks.

-- 
tejun
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] cgroup: check cgroup liveliness before unbreaking kernfs protection

2014-09-02 Thread Li Zefan
When cgroup_kn_lock_live() is called through some kernfs operation and
another thread is calling cgroup_rmdir(), we may trigger the warning in
cgroup_get().

[ cut here ]
WARNING: CPU: 1 PID: 1228 at kernel/cgroup.c:1034 cgroup_get+0x89/0xa0()
...
Call Trace:
 [] dump_stack+0x41/0x52
 [] warn_slowpath_common+0x7f/0xa0
 [] warn_slowpath_null+0x1d/0x20
 [] cgroup_get+0x89/0xa0
 [] cgroup_kn_lock_live+0x28/0x70
 [] __cgroup_procs_write.isra.26+0x51/0x230
 [] cgroup_tasks_write+0x12/0x20
 [] cgroup_file_write+0x40/0x130
 [] kernfs_fop_write+0xd1/0x160
 [] vfs_write+0x98/0x1e0
 [] SyS_write+0x4d/0xa0
 [] sysenter_do_call+0x12/0x12
---[ end trace 6f2e0c38c2108a74 ]---

Fix this by calling css_tryget() instead of cgroup_get().

Reported-by: Toralf Förster 
Signed-off-by: Li Zefan 
---
 kernel/cgroup.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index e03fc62..c8d07e5 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1025,6 +1025,11 @@ static umode_t cgroup_file_mode(const struct cftype *cft)
return mode;
 }
 
+static bool cgroup_tryget(struct cgroup *cgrp)
+{
+   return css_tryget(>self);
+}
+
 static void cgroup_get(struct cgroup *cgrp)
 {
WARN_ON_ONCE(cgroup_is_dead(cgrp));
@@ -1091,7 +1096,8 @@ static struct cgroup *cgroup_kn_lock_live(struct 
kernfs_node *kn)
 * protection against removal.  Ensure @cgrp stays accessible and
 * break the active_ref protection.
 */
-   cgroup_get(cgrp);
+   if (!cgroup_tryget(cgrp))
+   return NULL;
kernfs_break_active_protection(kn);
 
mutex_lock(_mutex);
-- 
1.8.0.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] cgroup: check cgroup liveliness before unbreaking kernfs protection

2014-09-02 Thread Li Zefan
When cgroup_kn_lock_live() is called through some kernfs operation and
another thread is calling cgroup_rmdir(), we may trigger the warning in
cgroup_get().

[ cut here ]
WARNING: CPU: 1 PID: 1228 at kernel/cgroup.c:1034 cgroup_get+0x89/0xa0()
...
Call Trace:
 [c16ee73d] dump_stack+0x41/0x52
 [c10468ef] warn_slowpath_common+0x7f/0xa0
 [c104692d] warn_slowpath_null+0x1d/0x20
 [c10bb999] cgroup_get+0x89/0xa0
 [c10bbe58] cgroup_kn_lock_live+0x28/0x70
 [c10be3c1] __cgroup_procs_write.isra.26+0x51/0x230
 [c10be5b2] cgroup_tasks_write+0x12/0x20
 [c10bb7b0] cgroup_file_write+0x40/0x130
 [c11aee71] kernfs_fop_write+0xd1/0x160
 [c1148e58] vfs_write+0x98/0x1e0
 [c114934d] SyS_write+0x4d/0xa0
 [c16f656b] sysenter_do_call+0x12/0x12
---[ end trace 6f2e0c38c2108a74 ]---

Fix this by calling css_tryget() instead of cgroup_get().

Reported-by: Toralf Förster toralf.foers...@gmx.de
Signed-off-by: Li Zefan lize...@huawei.com
---
 kernel/cgroup.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index e03fc62..c8d07e5 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1025,6 +1025,11 @@ static umode_t cgroup_file_mode(const struct cftype *cft)
return mode;
 }
 
+static bool cgroup_tryget(struct cgroup *cgrp)
+{
+   return css_tryget(cgrp-self);
+}
+
 static void cgroup_get(struct cgroup *cgrp)
 {
WARN_ON_ONCE(cgroup_is_dead(cgrp));
@@ -1091,7 +1096,8 @@ static struct cgroup *cgroup_kn_lock_live(struct 
kernfs_node *kn)
 * protection against removal.  Ensure @cgrp stays accessible and
 * break the active_ref protection.
 */
-   cgroup_get(cgrp);
+   if (!cgroup_tryget(cgrp))
+   return NULL;
kernfs_break_active_protection(kn);
 
mutex_lock(cgroup_mutex);
-- 
1.8.0.2
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] cgroup: check cgroup liveliness before unbreaking kernfs protection

2014-09-02 Thread Tejun Heo
On Tue, Sep 02, 2014 at 06:57:54PM +0800, Li Zefan wrote:
 diff --git a/kernel/cgroup.c b/kernel/cgroup.c
 index e03fc62..c8d07e5 100644
 --- a/kernel/cgroup.c
 +++ b/kernel/cgroup.c
 @@ -1025,6 +1025,11 @@ static umode_t cgroup_file_mode(const struct cftype 
 *cft)
   return mode;
  }
  
 +static bool cgroup_tryget(struct cgroup *cgrp)
 +{
 + return css_tryget(cgrp-self);
 +}

Can you please move this right below cgroup_get() definition?

Thanks.

-- 
tejun
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/