aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorHeinrich Schuchardt <xypron.glpk@gmx.de>2015-04-16 15:47:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-17 09:04:07 -0400
commit16db3d3f1170fb0efca652c9378ce7c5f5cb4232 (patch)
treef85f846c4e8a4761449aeca34dbd1055bb693828 /kernel
parentac1b398de1ef94aeee8ba87b0120763526572a6e (diff)
kernel/sysctl.c: threads-max observe limits
Users can change the maximum number of threads by writing to /proc/sys/kernel/threads-max. With the patch the value entered is checked against the same limits that apply when fork_init is called. 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>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/fork.c31
-rw-r--r--kernel/sysctl.c6
2 files changed, 31 insertions, 6 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index c7f2e1a4187a..8807a129711b 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -74,6 +74,7 @@
74#include <linux/uprobes.h> 74#include <linux/uprobes.h>
75#include <linux/aio.h> 75#include <linux/aio.h>
76#include <linux/compiler.h> 76#include <linux/compiler.h>
77#include <linux/sysctl.h>
77 78
78#include <asm/pgtable.h> 79#include <asm/pgtable.h>
79#include <asm/pgalloc.h> 80#include <asm/pgalloc.h>
@@ -266,7 +267,7 @@ void __init __weak arch_task_cache_init(void) { }
266/* 267/*
267 * set_max_threads 268 * set_max_threads
268 */ 269 */
269static void set_max_threads(void) 270static void set_max_threads(unsigned int max_threads_suggested)
270{ 271{
271 u64 threads; 272 u64 threads;
272 273
@@ -280,6 +281,9 @@ static void set_max_threads(void)
280 threads = div64_u64((u64) totalram_pages * (u64) PAGE_SIZE, 281 threads = div64_u64((u64) totalram_pages * (u64) PAGE_SIZE,
281 (u64) THREAD_SIZE * 8UL); 282 (u64) THREAD_SIZE * 8UL);
282 283
284 if (threads > max_threads_suggested)
285 threads = max_threads_suggested;
286
283 max_threads = clamp_t(u64, threads, MIN_THREADS, MAX_THREADS); 287 max_threads = clamp_t(u64, threads, MIN_THREADS, MAX_THREADS);
284} 288}
285 289
@@ -298,7 +302,7 @@ void __init fork_init(void)
298 /* do the arch specific task caches init */ 302 /* do the arch specific task caches init */
299 arch_task_cache_init(); 303 arch_task_cache_init();
300 304
301 set_max_threads(); 305 set_max_threads(MAX_THREADS);
302 306
303 init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2; 307 init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
304 init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2; 308 init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
@@ -2020,3 +2024,26 @@ int unshare_files(struct files_struct **displaced)
2020 task_unlock(task); 2024 task_unlock(task);
2021 return 0; 2025 return 0;
2022} 2026}
2027
2028int sysctl_max_threads(struct ctl_table *table, int write,
2029 void __user *buffer, size_t *lenp, loff_t *ppos)
2030{
2031 struct ctl_table t;
2032 int ret;
2033 int threads = max_threads;
2034 int min = MIN_THREADS;
2035 int max = MAX_THREADS;
2036
2037 t = *table;
2038 t.data = &threads;
2039 t.extra1 = &min;
2040 t.extra2 = &max;
2041
2042 ret = proc_dointvec_minmax(&t, write, buffer, lenp, ppos);
2043 if (ret || !write)
2044 return ret;
2045
2046 set_max_threads(threads);
2047
2048 return 0;
2049}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 42b7fc2860c1..3c0998426b57 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -93,11 +93,9 @@
93#include <linux/nmi.h> 93#include <linux/nmi.h>
94#endif 94#endif
95 95
96
97#if defined(CONFIG_SYSCTL) 96#if defined(CONFIG_SYSCTL)
98 97
99/* External variables not in a header file. */ 98/* External variables not in a header file. */
100extern int max_threads;
101extern int suid_dumpable; 99extern int suid_dumpable;
102#ifdef CONFIG_COREDUMP 100#ifdef CONFIG_COREDUMP
103extern int core_uses_pid; 101extern int core_uses_pid;
@@ -710,10 +708,10 @@ static struct ctl_table kern_table[] = {
710#endif 708#endif
711 { 709 {
712 .procname = "threads-max", 710 .procname = "threads-max",
713 .data = &max_threads, 711 .data = NULL,
714 .maxlen = sizeof(int), 712 .maxlen = sizeof(int),
715 .mode = 0644, 713 .mode = 0644,
716 .proc_handler = proc_dointvec, 714 .proc_handler = sysctl_max_threads,
717 }, 715 },
718 { 716 {
719 .procname = "random", 717 .procname = "random",