Home Home > GIT Browse > openSUSE-42.3
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2019-01-15 09:49:28 +0100
committerJan Kara <jack@suse.cz>2019-01-15 09:49:28 +0100
commit7cebba12d774e1f18b3bc794d978d564adc1f429 (patch)
tree837ee0b7ce96588e10c6af66d2c89fa23d4fe924
parent045b211c801fd5eebe25bce70ff6eff9878c2c5f (diff)
vfs: Avoid softlockups in drop_pagecache_sb() (bsc#1118505).
-rw-r--r--patches.fixes/vfs-Avoid-softlockups-in-drop_pagecache_sb.patch53
-rw-r--r--series.conf2
2 files changed, 55 insertions, 0 deletions
diff --git a/patches.fixes/vfs-Avoid-softlockups-in-drop_pagecache_sb.patch b/patches.fixes/vfs-Avoid-softlockups-in-drop_pagecache_sb.patch
new file mode 100644
index 0000000000..2d5366d23d
--- /dev/null
+++ b/patches.fixes/vfs-Avoid-softlockups-in-drop_pagecache_sb.patch
@@ -0,0 +1,53 @@
+From 9a6b7c0ff64945366c05338873e2456b990948e9 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 6 Dec 2018 17:06:08 +0100
+Subject: [PATCH] vfs: Avoid softlockups in drop_pagecache_sb()
+Patch-mainline: Submitted, Jan 14 2019
+References: bsc#1118505
+
+When superblock has lots of inodes without any pagecache (like is the
+case for /proc), drop_pagecache_sb() will iterate through all of them
+without dropping sb->s_inode_list_lock which can lead to softlockups
+(one of our customers hit this).
+
+Fix the problem by going to the slow path and doing cond_resched() in
+case the process needs rescheduling.
+
+Acked-by: Michal Hocko <mhocko@suse.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Acked-by: Jan Kara <jack@suse.cz>
+
+---
+ fs/drop_caches.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/fs/drop_caches.c b/fs/drop_caches.c
+index 82377017130f..d31b6c72b476 100644
+--- a/fs/drop_caches.c
++++ b/fs/drop_caches.c
+@@ -21,8 +21,13 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
+ spin_lock(&sb->s_inode_list_lock);
+ list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
+ spin_lock(&inode->i_lock);
++ /*
++ * We must skip inodes in unusual state. We may also skip
++ * inodes without pages but we deliberately won't in case
++ * we need to reschedule to avoid softlockups.
++ */
+ if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) ||
+- (inode->i_mapping->nrpages == 0)) {
++ (inode->i_mapping->nrpages == 0 && !need_resched())) {
+ spin_unlock(&inode->i_lock);
+ continue;
+ }
+@@ -30,6 +35,7 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
+ spin_unlock(&inode->i_lock);
+ spin_unlock(&sb->s_inode_list_lock);
+
++ cond_resched();
+ invalidate_mapping_pages(inode->i_mapping, 0, -1);
+ iput(toput_inode);
+ toput_inode = inode;
+--
+2.16.4
+
diff --git a/series.conf b/series.conf
index 03b0010f88..3d3d54d897 100644
--- a/series.conf
+++ b/series.conf
@@ -24022,6 +24022,8 @@
# bsc#1119204
patches.fixes/0001-fix-huge_pte_alloc-bug-on.patch
+ patches.fixes/vfs-Avoid-softlockups-in-drop_pagecache_sb.patch
+
########################################################
# IPC patches
########################################################