Commit ff691f6e authored by Heinrich Schuchardt's avatar Heinrich Schuchardt Committed by Linus Torvalds

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: default avatarHeinrich 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 3ea7f5e2
...@@ -91,7 +91,7 @@ ...@@ -91,7 +91,7 @@
static int kernel_init(void *); static int kernel_init(void *);
extern void init_IRQ(void); extern void init_IRQ(void);
extern void fork_init(unsigned long); extern void fork_init(void);
extern void radix_tree_init(void); extern void radix_tree_init(void);
#ifndef CONFIG_DEBUG_RODATA #ifndef CONFIG_DEBUG_RODATA
static inline void mark_rodata_ro(void) { } static inline void mark_rodata_ro(void) { }
...@@ -645,7 +645,7 @@ asmlinkage __visible void __init start_kernel(void) ...@@ -645,7 +645,7 @@ asmlinkage __visible void __init start_kernel(void)
#endif #endif
thread_info_cache_init(); thread_info_cache_init();
cred_init(); cred_init();
fork_init(totalram_pages); fork_init();
proc_caches_init(); proc_caches_init();
buffer_init(); buffer_init();
key_init(); key_init();
......
...@@ -253,7 +253,26 @@ EXPORT_SYMBOL_GPL(__put_task_struct); ...@@ -253,7 +253,26 @@ EXPORT_SYMBOL_GPL(__put_task_struct);
void __init __weak arch_task_cache_init(void) { } void __init __weak arch_task_cache_init(void) { }
void __init fork_init(unsigned long mempages) /*
* set_max_threads
*/
static void set_max_threads(void)
{
/*
* The default maximum number of threads is set to a safe
* value: the thread structures can take up at most one
* eighth of the memory.
*/
max_threads = totalram_pages / (8 * THREAD_SIZE / PAGE_SIZE);
/*
* we need to allow at least 20 threads to boot a system
*/
if (max_threads < 20)
max_threads = 20;
}
void __init fork_init(void)
{ {
#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR #ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR
#ifndef ARCH_MIN_TASKALIGN #ifndef ARCH_MIN_TASKALIGN
...@@ -268,18 +287,7 @@ void __init fork_init(unsigned long mempages) ...@@ -268,18 +287,7 @@ void __init fork_init(unsigned long mempages)
/* do the arch specific task caches init */ /* do the arch specific task caches init */
arch_task_cache_init(); arch_task_cache_init();
/* set_max_threads();
* The default maximum number of threads is set to a safe
* value: the thread structures can take up at most one
* eighth of the memory.
*/
max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);
/*
* we need to allow at least 20 threads to boot a system
*/
if (max_threads < 20)
max_threads = 20;
init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2; init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2; init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment