]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.19.29/fs-drop_caches.c-avoid-softlockups-in-drop_pagecache.patch
fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 4.19.29 / fs-drop_caches.c-avoid-softlockups-in-drop_pagecache.patch
CommitLineData
7748c0ed
SL
1From fb2e3c9c2984fe5a073e12893132fd0b8dacfb72 Mon Sep 17 00:00:00 2001
2From: Jan Kara <jack@suse.cz>
3Date: Fri, 1 Feb 2019 14:21:23 -0800
4Subject: fs/drop_caches.c: avoid softlockups in drop_pagecache_sb()
5
6[ Upstream commit c27d82f52f75fc9d8d9d40d120d2a96fdeeada5e ]
7
8When superblock has lots of inodes without any pagecache (like is the
9case for /proc), drop_pagecache_sb() will iterate through all of them
10without dropping sb->s_inode_list_lock which can lead to softlockups
11(one of our customers hit this).
12
13Fix the problem by going to the slow path and doing cond_resched() in
14case the process needs rescheduling.
15
16Link: http://lkml.kernel.org/r/20190114085343.15011-1-jack@suse.cz
17Signed-off-by: Jan Kara <jack@suse.cz>
18Acked-by: Michal Hocko <mhocko@suse.com>
19Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
20Cc: Al Viro <viro@ZenIV.linux.org.uk>
21Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
22Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
23Signed-off-by: Sasha Levin <sashal@kernel.org>
24---
25 fs/drop_caches.c | 8 +++++++-
26 1 file changed, 7 insertions(+), 1 deletion(-)
27
28diff --git a/fs/drop_caches.c b/fs/drop_caches.c
29index 82377017130f..d31b6c72b476 100644
30--- a/fs/drop_caches.c
31+++ b/fs/drop_caches.c
32@@ -21,8 +21,13 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
33 spin_lock(&sb->s_inode_list_lock);
34 list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
35 spin_lock(&inode->i_lock);
36+ /*
37+ * We must skip inodes in unusual state. We may also skip
38+ * inodes without pages but we deliberately won't in case
39+ * we need to reschedule to avoid softlockups.
40+ */
41 if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) ||
42- (inode->i_mapping->nrpages == 0)) {
43+ (inode->i_mapping->nrpages == 0 && !need_resched())) {
44 spin_unlock(&inode->i_lock);
45 continue;
46 }
47@@ -30,6 +35,7 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
48 spin_unlock(&inode->i_lock);
49 spin_unlock(&sb->s_inode_list_lock);
50
51+ cond_resched();
52 invalidate_mapping_pages(inode->i_mapping, 0, -1);
53 iput(toput_inode);
54 toput_inode = inode;
55--
562.19.1
57