diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 31 |
1 files changed, 29 insertions, 2 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 | */ |
| 269 | static void set_max_threads(void) | 270 | static 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 | |||
| 2028 | int 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 | } | ||
