From dda65ea86b6c728ee9519d96ea5bd39e4f473543 Mon Sep 17 00:00:00 2001 From: luanshi Date: Tue, 9 Oct 2018 09:26:02 +0800 Subject: [PATCH] fs/writeback: Attach inode's wb to root if needed There might have tons of files queued in the writeback, awaiting for writing back. Unfortunately, the writeback's cgroup has been dead. In this case, we reassociate the inode with another writeback, but we possibly can't because the writeback associated with the dead cgroup is the only valid one. In this case, the new writeback is allocated, initialized and associated with the inode in the non-stopping fashion until all data resident in the inode's page cache are flushed to disk. It causes unnecessary high system load. This fixes the issue by enforce moving the inode to root cgroup when the previous binding cgroup becomes dead. With it, no more unnecessary writebacks are created, populated and the system load decreased by about 6x in the test case we carried out: Without the patch: 30% system load With the patch: 5% system load Signed-off-by: luanshi Signed-off-by: Jiufei Xue Reviewed-by: Joseph Qi --- fs/fs-writeback.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 9544e2f8b79f..96d0d433b7f8 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -704,6 +704,16 @@ void wbc_detach_inode(struct writeback_control *wbc) inode->i_wb_frn_avg_time = min(avg_time, (unsigned long)U16_MAX); inode->i_wb_frn_history = history; + /* + * Without wb list lock i_wb can switch at any point, so it can + * judge on the wrong wb anyway. + * + * The wb is switched to the root memcg unconditionally. We expect + * the correct wb (best candidate) is picked up in next round. + */ + if (wb == inode->i_wb && wb_dying(wb) && !(inode->i_state & I_DIRTY_ALL)) + inode_switch_wbs(inode, root_mem_cgroup->css.id); + wb_put(wbc->wb); wbc->wb = NULL; } -- GitLab