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>
This commit is contained in:
committed by
Linus Torvalds
parent
3ea7f5e25e
commit
ff691f6e03
@@ -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)
|
|||||||
#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);
|
|||||||
|
|
||||||
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)
|
|||||||
/* 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;
|
||||||
|
Reference in New Issue
Block a user