]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kernel/fork.c: new function for max_threads
authorHeinrich Schuchardt <xypron.glpk@gmx.de>
Tue, 7 Apr 2015 23:45:21 +0000 (09:45 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Tue, 7 Apr 2015 23:45:21 +0000 (09:45 +1000)
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>
init/main.c
kernel/fork.c

index 119cdf13348ef275894dd00a38b467d4ef3bf645..80ea96e6db28ea126c9063c3308c61efd00a227f 100644 (file)
@@ -91,7 +91,7 @@
 static int kernel_init(void *);
 
 extern void init_IRQ(void);
-extern void fork_init(unsigned long);
+extern void fork_init(void);
 extern void radix_tree_init(void);
 #ifndef CONFIG_DEBUG_RODATA
 static inline void mark_rodata_ro(void) { }
@@ -644,7 +644,7 @@ asmlinkage __visible void __init start_kernel(void)
 #endif
        thread_info_cache_init();
        cred_init();
-       fork_init(totalram_pages);
+       fork_init();
        proc_caches_init();
        buffer_init();
        key_init();
index 7cddc461023ebaa889123361cc5bb4bc20f21d0f..04a871d7384f0dc5e87cdc7e6725913f07e12921 100644 (file)
@@ -253,7 +253,26 @@ EXPORT_SYMBOL_GPL(__put_task_struct);
 
 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 ARCH_MIN_TASKALIGN
@@ -268,18 +287,7 @@ void __init fork_init(unsigned long mempages)
        /* do the arch specific task caches init */
        arch_task_cache_init();
 
-       /*
-        * 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;
+       set_max_threads();
 
        init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
        init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;