提交 38a9ff8e 编写于 作者: J Jiufei Xue

fs/writeback: fix double free of blkcg_css

We have gotten a WARNNING when releasing blkcg_css:

[332489.681635] WARNING: CPU: 55 PID: 14859 at lib/list_debug.c:56 __list_del_entry+0x81/0xc0
[332489.682191] list_del corruption, ffff883e6b94d450->prev is LIST_POISON2 (dead000000000200)
......
[332489.683895] CPU: 55 PID: 14859 Comm: kworker/55:2 Tainted: G
[332489.684477] Hardware name: Inspur SA5248M4/X10DRT-PS, BIOS 4.05A
10/11/2016
[332489.685061] Workqueue: cgroup_destroy css_release_work_fn
[332489.685654]  ffffc9001d92bd28 ffffffff81380042 ffffc9001d92bd78
0000000000000000
[332489.686269]  ffffc9001d92bd68 ffffffff81088f8b 0000003800000000
ffff883e6b94d4a0
[332489.686867]  ffff883e6b94d400 ffffffff81ce8fe0 ffff88375b24f400
ffff883e6b94d4a0
[332489.687479] Call Trace:
[332489.688078]  [<ffffffff81380042>] dump_stack+0x63/0x81
[332489.688681]  [<ffffffff81088f8b>] __warn+0xcb/0xf0
[332489.689276]  [<ffffffff8108900f>] warn_slowpath_fmt+0x5f/0x80
[332489.689877]  [<ffffffff8139e7c1>] __list_del_entry+0x81/0xc0
[332489.690481]  [<ffffffff81125552>] css_release_work_fn+0x42/0x140
[332489.691090]  [<ffffffff810a2db9>] process_one_work+0x189/0x420
[332489.691693]  [<ffffffff810a309e>] worker_thread+0x4e/0x4b0
[332489.692293]  [<ffffffff810a3050>] ? process_one_work+0x420/0x420
[332489.692905]  [<ffffffff810a9616>] kthread+0xe6/0x100
[332489.693504]  [<ffffffff810a9530>] ? kthread_park+0x60/0x60
[332489.694099]  [<ffffffff817184e1>] ret_from_fork+0x41/0x50
[332489.694722] ---[ end trace 0cf869c4a5cfba87 ]---
......

This is caused by calling css_get after the css is killed by another
thread described below:

           Thread 1                       Thread 2
cgroup_rmdir
  -> kill_css
    -> percpu_ref_kill_and_confirm
      -> css_killed_ref_fn

css_killed_work_fn
  -> css_put
    -> css_release
                                        wb_get_create
					  -> find_blkcg_css
					    -> css_get
					  -> css_put
					    -> css_release (double free)
    -> css_release_workfn
      -> css_free_work_fn
       -> blkcg_css_free

When doublefree happened, it may free the memory still used by
other threads and cause a kernel panic.

Fix this by using css_tryget_online in find_blkcg_css while will return
false if the css is killed.
Signed-off-by: NJiufei Xue <jiufei.xue@linux.alibaba.com>
Reviewed-by: NJoseph Qi <joseph.qi@linux.alibaba.com>
上级 88c2a69e
......@@ -583,15 +583,21 @@ static struct cgroup_subsys_state *find_blkcg_css(struct cgroup_subsys_state *me
rcu_read_lock();
link = radix_tree_lookup(&memcg_blkcg_tree, memcg_css->id);
if (link)
if (link) {
blkcg_css = link->blkcg_css;
else
blkcg_css = blkcg_root_css;
if (css_tryget_online(blkcg_css))
goto out;
}
/*
* If not blkcg_root_css and tryget failed,
* get a reference of blkcg_root_css and return.
*/
blkcg_css = blkcg_root_css;
css_get(blkcg_css);
out:
rcu_read_unlock();
return blkcg_css;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册