Skip to content

Commit cc3b6bd

Browse files
Mel Gormansfrothwell
Mel Gorman
authored andcommitted
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]>
1 parent 8ceffd2 commit cc3b6bd

File tree

5 files changed

+25
-22
lines changed

5 files changed

+25
-22
lines changed

fs/dcache.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3442,22 +3442,15 @@ void __init vfs_caches_init_early(void)
34423442
inode_init_early();
34433443
}
34443444

3445-
void __init vfs_caches_init(unsigned long mempages)
3445+
void __init vfs_caches_init(void)
34463446
{
3447-
unsigned long reserve;
3448-
3449-
/* Base hash sizes on available memory, with a reserve equal to
3450-
150% of current kernel size */
3451-
3452-
reserve = min((mempages - nr_free_pages()) * 3/2, mempages - 1);
3453-
mempages -= reserve;
3454-
34553447
names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0,
34563448
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
34573449

34583450
dcache_init();
34593451
inode_init();
3460-
files_init(mempages);
3452+
files_init();
3453+
files_maxfiles_init();
34613454
mnt_init();
34623455
bdev_cache_init();
34633456
chrdev_init();

fs/file_table.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <linux/hardirq.h>
2626
#include <linux/task_work.h>
2727
#include <linux/ima.h>
28+
#include <linux/swap.h>
2829

2930
#include <linux/atomic.h>
3031

@@ -308,19 +309,24 @@ void put_filp(struct file *file)
308309
}
309310
}
310311

311-
void __init files_init(unsigned long mempages)
312+
void __init files_init(void)
312313
{
313-
unsigned long n;
314-
315314
filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0,
316315
SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
316+
percpu_counter_init(&nr_files, 0, GFP_KERNEL);
317+
}
317318

318-
/*
319-
* One file with associated inode and dcache is very roughly 1K.
320-
* Per default don't use more than 10% of our memory for files.
321-
*/
319+
/*
320+
* One file with associated inode and dcache is very roughly 1K. Per default
321+
* do not use more than 10% of our memory for files.
322+
*/
323+
void __init files_maxfiles_init(void)
324+
{
325+
unsigned long n;
326+
unsigned long memreserve = (totalram_pages - nr_free_pages()) * 3/2;
327+
328+
memreserve = min(memreserve, totalram_pages - 1);
329+
n = ((totalram_pages - memreserve) * (PAGE_SIZE / 1024)) / 10;
322330

323-
n = (mempages * (PAGE_SIZE / 1024)) / 10;
324331
files_stat.max_files = max_t(unsigned long, n, NR_FILE);
325-
percpu_counter_init(&nr_files, 0, GFP_KERNEL);
326332
}

include/linux/fs.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ struct vm_fault;
5555

5656
extern void __init inode_init(void);
5757
extern void __init inode_init_early(void);
58-
extern void __init files_init(unsigned long);
58+
extern void __init files_init(void);
59+
extern void __init files_maxfiles_init(void);
5960

6061
extern struct files_stat_struct files_stat;
6162
extern unsigned long get_max_files(void);
@@ -2245,7 +2246,7 @@ extern int ioctl_preallocate(struct file *filp, void __user *argp);
22452246

22462247
/* fs/dcache.c */
22472248
extern void __init vfs_caches_init_early(void);
2248-
extern void __init vfs_caches_init(unsigned long);
2249+
extern void __init vfs_caches_init(void);
22492250

22502251
extern struct kmem_cache *names_cachep;
22512252

init/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,7 @@ asmlinkage __visible void __init start_kernel(void)
656656
key_init();
657657
security_init();
658658
dbg_late_init();
659-
vfs_caches_init(totalram_pages);
659+
vfs_caches_init();
660660
signals_init();
661661
/* rootfs populating might need page-writeback */
662662
page_writeback_init();

mm/page_alloc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,9 @@ void __init page_alloc_init_late(void)
12011201

12021202
/* Block until all are initialised */
12031203
wait_for_completion(&pgdat_init_all_done_comp);
1204+
1205+
/* Reinit limits that are based on free pages after the kernel is up */
1206+
files_maxfiles_init();
12041207
}
12051208
#endif /* CONFIG_DEFERRED_STRUCT_PAGE_INIT */
12061209

0 commit comments

Comments
 (0)