aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_fork.c
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2009-08-29 13:28:02 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2009-08-29 13:28:02 +0000
commitc3cf0b476fa28f2fddbfbbbb371011cc90d17d61 (patch)
tree82b12109af3318558a1e8c250b9fe6dbbb1bb53d /sys/kern/kern_fork.c
parente0fdd85ff701d47c8464509d73d405bfc4b19d55 (diff)
downloadsrc-c3cf0b476fa28f2fddbfbbbb371011cc90d17d61.tar.gz
src-c3cf0b476fa28f2fddbfbbbb371011cc90d17d61.zip
Remove the altkstacks, instead instantiate threads with kernel stack
allocated with the right size from the start. For the thread that has kernel stack cached, verify that requested stack size is equial to the actual, and reallocate the stack if sizes differ [1]. This fixes the bug introduced by r173361 that was committed several days after r173004 and consisted of kthread_add(9) ignoring the non-default kernel stack size. Also, r173361 removed the caching of the kernel stacks for a non-first thread in the process. Introduce separate kernel stack cache that keeps some limited amount of preallocated kernel stacks to lower the latency of thread allocation. Add vm_lowmem handler to prune the cache on low memory condition. This way, system with reasonable amount of the threads get lower latency of thread creation, while still not exhausting significant portion of KVA for unused kstacks. Submitted by: peter [1] Discussed with: jhb, julian, peter Reviewed by: jhb Tested by: pho MFC after: 1 week
Notes
Notes: svn path=/head/; revision=196640
Diffstat (limited to 'sys/kern/kern_fork.c')
-rw-r--r--sys/kern/kern_fork.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 4e2eaa98f3aa..b5a40828a483 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include "opt_kdtrace.h"
#include "opt_ktrace.h"
+#include "opt_kstack_pages.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -276,25 +277,29 @@ norfproc_fail:
mem_charged = 0;
vm2 = NULL;
+ if (pages == 0)
+ pages = KSTACK_PAGES;
/* Allocate new proc. */
newproc = uma_zalloc(proc_zone, M_WAITOK);
- if (TAILQ_EMPTY(&newproc->p_threads)) {
- td2 = thread_alloc();
+ td2 = FIRST_THREAD_IN_PROC(newproc);
+ if (td2 == NULL) {
+ td2 = thread_alloc(pages);
if (td2 == NULL) {
error = ENOMEM;
goto fail1;
}
proc_linkup(newproc, td2);
- } else
- td2 = FIRST_THREAD_IN_PROC(newproc);
-
- /* Allocate and switch to an alternate kstack if specified. */
- if (pages != 0) {
- if (!vm_thread_new_altkstack(td2, pages)) {
- error = ENOMEM;
- goto fail1;
+ } else {
+ if (td2->td_kstack == 0 || td2->td_kstack_pages != pages) {
+ if (td2->td_kstack != 0)
+ vm_thread_dispose(td);
+ if (!thread_alloc_stack(td2, pages)) {
+ error = ENOMEM;
+ goto fail1;
+ }
}
}
+
if ((flags & RFMEM) == 0) {
vm2 = vmspace_fork(p1->p_vmspace, &mem_charged);
if (vm2 == NULL) {