mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	fs/drop_caches.c: avoid softlockups in drop_pagecache_sb()
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. Link: http://lkml.kernel.org/r/20190114085343.15011-1-jack@suse.cz Signed-off-by: Jan Kara <jack@suse.cz> Acked-by: Michal Hocko <mhocko@suse.com> Reviewed-by: Andrew Morton <akpm@linux-foundation.org> Cc: Al Viro <viro@ZenIV.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									e0a352fabc
								
							
						
					
					
						commit
						c27d82f52f
					
				
					 1 changed files with 7 additions and 1 deletions
				
			
		|  | @ -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; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Jan Kara
						Jan Kara