diff options
author | Heinrich Schuchardt <xypron.glpk@gmx.de> | 2015-04-16 15:47:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-17 09:04:06 -0400 |
commit | ff691f6e03815dc8f99461ea509df863a879fc3a (patch) | |
tree | acc3b3c61ff40365d15cbe89952c743b301016af | |
parent | 3ea7f5e25ec271909451b7dc17be37581b888de6 (diff) |
kernel/fork.c: new function for max_threads
PAGE_SIZE is not guaranteed to be equal to or less than 8 times the
THREAD_SIZE.
E.g. architecture hexagon may have page size 1M and thread size 4096.
This would lead to a division by zero in the calculation of max_threads.
With this patch the buggy code is moved to a separate function
set_max_threads. The error is not fixed.
After fixing the problem in a separate patch the new function can be
reused to adjust max_threads after adding or removing memory.
Argument mempages of function fork_init() is removed as totalram_pages is
an exported symbol.
The creation of separate patches for refactoring to a new function and for
fixing the logic was suggested by Ingo Molnar.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | init/main.c | 4 | ||||
-rw-r--r-- | kernel/fork.c | 34 |
2 files changed, 23 insertions, 15 deletions
diff --git a/init/main.c b/init/main.c index a7e969d12f51..2115055faeac 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -91,7 +91,7 @@ | |||
91 | static int kernel_init(void *); | 91 | static int kernel_init(void *); |
92 | 92 | ||
93 | extern void init_IRQ(void); | 93 | extern void init_IRQ(void); |
94 | extern void fork_init(unsigned long); | 94 | extern void fork_init(void); |
95 | extern void radix_tree_init(void); | 95 | extern void radix_tree_init(void); |
96 | #ifndef CONFIG_DEBUG_RODATA | 96 | #ifndef CONFIG_DEBUG_RODATA |
97 | static inline void mark_rodata_ro(void) { } | 97 | static inline void mark_rodata_ro(void) { } |
@@ -645,7 +645,7 @@ asmlinkage __visible void __init start_kernel(void) | |||
645 | #endif | 645 | #endif |
646 | thread_info_cache_init(); | 646 | thread_info_cache_init(); |
647 | cred_init(); | 647 | cred_init(); |
648 | fork_init(totalram_pages); | 648 | fork_init(); |
649 | proc_caches_init(); | 649 | proc_caches_init(); |
650 | buffer_init(); | 650 | buffer_init(); |
651 | key_init(); | 651 | key_init(); |
diff --git a/kernel/fork.c b/kernel/fork.c index c507e29bcb01..01038e6f51a8 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -253,7 +253,26 @@ EXPORT_SYMBOL_GPL(__put_task_struct); | |||
253 | 253 | ||
254 | void __init __weak arch_task_cache_init(void) { } | 254 | void __init __weak arch_task_cache_init(void) { } |
255 | 255 | ||
256 | void __init fork_init(unsigned long mempages) | 256 | /* |
257 | * set_max_threads | ||
258 | */ | ||
259 | static void set_max_threads(void) | ||
260 | { | ||
261 | /* | ||
262 | * The default maximum number of threads is set to a safe | ||
263 | * value: the thread structures can take up at most one | ||
264 | * eighth of the memory. | ||
265 | */ | ||
266 | max_threads = totalram_pages / (8 * THREAD_SIZE / PAGE_SIZE); | ||
267 | |||
268 | /* | ||
269 | * we need to allow at least 20 threads to boot a system | ||
270 | */ | ||
271 | if (max_threads < 20) | ||
272 | max_threads = 20; | ||
273 | } | ||
274 | |||
275 | void __init fork_init(void) | ||
257 | { | 276 | { |
258 | #ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR | 277 | #ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR |
259 | #ifndef ARCH_MIN_TASKALIGN | 278 | #ifndef ARCH_MIN_TASKALIGN |
@@ -268,18 +287,7 @@ void __init fork_init(unsigned long mempages) | |||
268 | /* do the arch specific task caches init */ | 287 | /* do the arch specific task caches init */ |
269 | arch_task_cache_init(); | 288 | arch_task_cache_init(); |
270 | 289 | ||
271 | /* | 290 | set_max_threads(); |
272 | * The default maximum number of threads is set to a safe | ||
273 | * value: the thread structures can take up at most one | ||
274 | * eighth of the memory. | ||
275 | */ | ||
276 | max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE); | ||
277 | |||
278 | /* | ||
279 | * we need to allow at least 20 threads to boot a system | ||
280 | */ | ||
281 | if (max_threads < 20) | ||
282 | max_threads = 20; | ||
283 | 291 | ||
284 | init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2; | 292 | init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2; |
285 | init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2; | 293 | init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2; |