From: Ye Bin <yebin10@xxxxxxxxxx> If the memory is sufficient, a large number of inodes that do not meet the conditions may exist in the 'sb->s_inodes' list when evict_inodes()/invalidate_inodes() traverse the 'sb->s_inodes' list. Then it maybe trigger soft lockup. To solve potential soft lockup, move need_resched() check from tail to head when traverse the 'sb->s_inodes' list. Signed-off-by: Ye Bin <yebin10@xxxxxxxxxx> --- fs/inode.c | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index b78895af8779..e865fc1f5a95 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -867,6 +867,21 @@ void evict_inodes(struct super_block *sb) again: spin_lock(&sb->s_inode_list_lock); sb_for_each_inodes_continue_safe(inode, next, &sb->s_inodes) { + /* + * We can have a ton of inodes to evict at unmount time given + * enough memory, check to see if we need to go to sleep for a + * bit so we don't livelock. + */ + if (need_resched()) { + list_del(&cursor.i_sb_list); + list_add_tail(&cursor.i_sb_list, &inode->i_sb_list); + inode = &cursor; + spin_unlock(&sb->s_inode_list_lock); + cond_resched(); + dispose_list(&dispose); + goto again; + } + if (atomic_read(&inode->i_count)) continue; @@ -884,21 +899,6 @@ void evict_inodes(struct super_block *sb) inode_lru_list_del(inode); spin_unlock(&inode->i_lock); list_add(&inode->i_lru, &dispose); - - /* - * We can have a ton of inodes to evict at unmount time given - * enough memory, check to see if we need to go to sleep for a - * bit so we don't livelock. - */ - if (need_resched()) { - list_del(&cursor.i_sb_list); - list_add(&cursor.i_sb_list, &inode->i_sb_list); - inode = &cursor; - spin_unlock(&sb->s_inode_list_lock); - cond_resched(); - dispose_list(&dispose); - goto again; - } } list_del(&cursor.i_sb_list); spin_unlock(&sb->s_inode_list_lock); @@ -926,6 +926,16 @@ void invalidate_inodes(struct super_block *sb) again: spin_lock(&sb->s_inode_list_lock); sb_for_each_inodes_continue_safe(inode, next, &sb->s_inodes) { + if (need_resched()) { + list_del(&cursor.i_sb_list); + list_add_tail(&cursor.i_sb_list, &inode->i_sb_list); + inode = &cursor; + spin_unlock(&sb->s_inode_list_lock); + cond_resched(); + dispose_list(&dispose); + goto again; + } + spin_lock(&inode->i_lock); if (inode->i_state & (I_NEW | I_FREEING | I_WILL_FREE)) { spin_unlock(&inode->i_lock); @@ -940,15 +950,6 @@ void invalidate_inodes(struct super_block *sb) inode_lru_list_del(inode); spin_unlock(&inode->i_lock); list_add(&inode->i_lru, &dispose); - if (need_resched()) { - list_del(&cursor.i_sb_list); - list_add(&cursor.i_sb_list, &inode->i_sb_list); - inode = &cursor; - spin_unlock(&sb->s_inode_list_lock); - cond_resched(); - dispose_list(&dispose); - goto again; - } } list_del(&cursor.i_sb_list); spin_unlock(&sb->s_inode_list_lock); -- 2.34.1