fs, file table: reinit files_stat.max_files after deferred memory initialisation

Dave Hansen reported the following;

	My laptop has been behaving strangely with 4.2-rc2.  Once I log
	in to my X session, I start getting all kinds of strange errors
	from applications and see this in my dmesg:

        	VFS: file-max limit 8192 reached

The problem is that the file-max is calculated before memory is fully
initialised and miscalculates how much memory the kernel is using.  This
patch recalculates file-max after deferred memory initialisation.  Note
that using memory hotplug infrastructure would not have avoided this
problem as the value is not recalculated after memory hot-add.

4.1:             files_stat.max_files = 6582781
4.2-rc2:         files_stat.max_files = 8192
4.2-rc2 patched: files_stat.max_files = 6562467

Small differences with the patch applied and 4.1 but not enough to matter.

Signed-off-by: Mel Gorman <[email protected]>
Reported-by: Dave Hansen <[email protected]>
Cc: Nicolai Stange <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Alex Ng <[email protected]>
Cc: Fengguang Wu <[email protected]>
Cc: Peter Zijlstra (Intel) <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
Mel Gorman 2015-08-06 15:46:20 -07:00 • committed by Linus Torvalds
commit 4248b0da46
5 changed files with 25 additions and 22 deletions

View file

@ -3442,22 +3442,15 @@ void __init vfs_caches_init_early(void)
inode_init_early();
}
void __init vfs_caches_init(unsigned long mempages)
void __init vfs_caches_init(void)
{
unsigned long reserve;
/* Base hash sizes on available memory, with a reserve equal to
150% of current kernel size */
reserve = min((mempages - nr_free_pages()) * 3/2, mempages - 1);
mempages -= reserve;
names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
dcache_init();
inode_init();
files_init(mempages);
files_init();
files_maxfiles_init();
mnt_init();
bdev_cache_init();
chrdev_init();