diff options
author | scottl <scottl@FreeBSD.org> | 2002-10-02 07:44:29 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2002-10-02 07:44:29 +0000 |
commit | 3a150bca9cc1b9ca767ca73d95fd54081237210b (patch) | |
tree | 0a9cc28f7570a42ae4e5df4cfc55dee42c36d9d8 /sys/kern | |
parent | 734ef490b8cfe3acc5f45425a63fac5e7c5173a3 (diff) | |
download | FreeBSD-src-3a150bca9cc1b9ca767ca73d95fd54081237210b.zip FreeBSD-src-3a150bca9cc1b9ca767ca73d95fd54081237210b.tar.gz |
Some kernel threads try to do significant work, and the default KSTACK_PAGES
doesn't give them enough stack to do much before blowing away the pcb.
This adds MI and MD code to allow the allocation of an alternate kstack
who's size can be speficied when calling kthread_create. Passing the
value 0 prevents the alternate kstack from being created. Note that the
ia64 MD code is missing for now, and PowerPC was only partially written
due to the pmap.c being incomplete there.
Though this patch does not modify anything to make use of the alternate
kstack, acpi and usb are good candidates.
Reviewed by: jake, peter, jhb
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/init_main.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 13 | ||||
-rw-r--r-- | sys/kern/kern_idle.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_intr.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_kse.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_kthread.c | 6 | ||||
-rw-r--r-- | sys/kern/kern_ktrace.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_proc.c | 9 | ||||
-rw-r--r-- | sys/kern/kern_thread.c | 2 | ||||
-rw-r--r-- | sys/kern/vfs_aio.c | 2 |
10 files changed, 29 insertions, 15 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 49bb739..66b58d2 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -685,7 +685,7 @@ create_init(const void *udata __unused) struct ucred *newcred, *oldcred; int error; - error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, &initproc); + error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc); if (error) panic("cannot fork init: %d\n", error); /* divorce init's credentials from the kernel's */ diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index da7ca7d..9fbf602 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -118,7 +118,7 @@ fork(td, uap) struct proc *p2; mtx_lock(&Giant); - error = fork1(td, RFFDG | RFPROC, &p2); + error = fork1(td, RFFDG | RFPROC, 0, &p2); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -140,7 +140,7 @@ vfork(td, uap) struct proc *p2; mtx_lock(&Giant); - error = fork1(td, RFFDG | RFPROC | RFPPWAIT | RFMEM, &p2); + error = fork1(td, RFFDG | RFPROC | RFPPWAIT | RFMEM, 0, &p2); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -164,7 +164,7 @@ rfork(td, uap) if ((uap->flags & RFKERNELONLY) != 0) return (EINVAL); mtx_lock(&Giant); - error = fork1(td, uap->flags, &p2); + error = fork1(td, uap->flags, 0, &p2); if (error == 0) { td->td_retval[0] = p2 ? p2->p_pid : 0; td->td_retval[1] = 0; @@ -215,9 +215,10 @@ SYSCTL_PROC(_kern, OID_AUTO, randompid, CTLTYPE_INT|CTLFLAG_RW, 0, 0, sysctl_kern_randompid, "I", "Random PID modulus"); int -fork1(td, flags, procp) +fork1(td, flags, pages, procp) struct thread *td; /* parent proc */ int flags; + int pages; struct proc **procp; /* child proc */ { struct proc *p2, *pptr; @@ -471,6 +472,10 @@ again: kg2 = FIRST_KSEGRP_IN_PROC(p2); ke2 = FIRST_KSE_IN_KSEGRP(kg2); + /* Allocate and switch to an alternate kstack if specified */ + if (pages != 0) + pmap_new_altkstack(td2, pages); + #define RANGEOF(type, start, end) (offsetof(type, end) - offsetof(type, start)) bzero(&p2->p_startzero, diff --git a/sys/kern/kern_idle.c b/sys/kern/kern_idle.c index b0f4fda..bf8e922 100644 --- a/sys/kern/kern_idle.c +++ b/sys/kern/kern_idle.c @@ -46,7 +46,7 @@ idle_setup(void *dummy) #ifdef SMP SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { error = kthread_create(idle_proc, NULL, &p, - RFSTOPPED | RFHIGHPID, "idle: cpu%d", pc->pc_cpuid); + RFSTOPPED | RFHIGHPID, 0, "idle: cpu%d", pc->pc_cpuid); pc->pc_idlethread = FIRST_THREAD_IN_PROC(p); if (pc->pc_curthread == NULL) { pc->pc_curthread = pc->pc_idlethread; @@ -54,7 +54,7 @@ idle_setup(void *dummy) } #else error = kthread_create(idle_proc, NULL, &p, - RFSTOPPED | RFHIGHPID, "idle"); + RFSTOPPED | RFHIGHPID, 0, "idle"); PCPU_SET(idlethread, FIRST_THREAD_IN_PROC(p)); #endif if (error) diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c index 61f6579..2d7b160 100644 --- a/sys/kern/kern_intr.c +++ b/sys/kern/kern_intr.c @@ -188,7 +188,7 @@ ithread_create(struct ithd **ithread, int vector, int flags, va_end(ap); error = kthread_create(ithread_loop, ithd, &p, RFSTOPPED | RFHIGHPID, - "%s", ithd->it_name); + 0, "%s", ithd->it_name); if (error) { mtx_destroy(&ithd->it_lock); free(ithd, M_ITHREAD); diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c index 907eba7..7123616 100644 --- a/sys/kern/kern_kse.c +++ b/sys/kern/kern_kse.c @@ -142,7 +142,7 @@ thread_init(void *mem, int size) td = (struct thread *)mem; mtx_lock(&Giant); - pmap_new_thread(td); + pmap_new_thread(td, 0); mtx_unlock(&Giant); cpu_thread_setup(td); } diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c index 08ef71f..e785d0b 100644 --- a/sys/kern/kern_kthread.c +++ b/sys/kern/kern_kthread.c @@ -55,7 +55,7 @@ kproc_start(udata) int error; error = kthread_create((void (*)(void *))kp->func, NULL, - kp->global_procpp, 0, "%s", kp->arg0); + kp->global_procpp, 0, 0, "%s", kp->arg0); if (error) panic("kproc_start: %s: error %d", kp->arg0, error); } @@ -72,7 +72,7 @@ kproc_start(udata) */ int kthread_create(void (*func)(void *), void *arg, - struct proc **newpp, int flags, const char *fmt, ...) + struct proc **newpp, int flags, int pages, const char *fmt, ...) { int error; va_list ap; @@ -83,7 +83,7 @@ kthread_create(void (*func)(void *), void *arg, panic("kthread_create called too soon"); error = fork1(&thread0, RFMEM | RFFDG | RFPROC | RFSTOPPED | flags, - &p2); + pages, &p2); if (error) return error; diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index 0ad2df3..bb4642c 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -134,7 +134,7 @@ ktrace_init(void *dummy) req = malloc(sizeof(struct ktr_request), M_KTRACE, M_WAITOK); STAILQ_INSERT_HEAD(&ktr_free, req, ktr_list); } - kthread_create(ktr_loop, NULL, NULL, RFHIGHPID, "ktrace"); + kthread_create(ktr_loop, NULL, NULL, RFHIGHPID, 0, "ktrace"); } SYSINIT(ktrace_init, SI_SUB_KTRACE, SI_ORDER_ANY, ktrace_init, NULL); diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 633c66e..9f20562 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -164,6 +164,15 @@ proc_dtor(void *mem, int size, void *arg) KASSERT((kg != NULL), ("proc_dtor: bad kg pointer")); ke = FIRST_KSE_IN_KSEGRP(kg); KASSERT((ke != NULL), ("proc_dtor: bad ke pointer")); + + /* Dispose of an alternate kstack, if it exists. + * XXX What if there are more than one thread in the proc? + * The first thread in the proc is special and not + * freed, so you gotta do this here. + */ + if (((p->p_flag & P_KTHREAD) != 0) && (td->td_altkstack != 0)) + pmap_dispose_altkstack(td); + /* * We want to make sure we know the initial linkages. * so for now tear them down and remake them. diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index 907eba7..7123616 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -142,7 +142,7 @@ thread_init(void *mem, int size) td = (struct thread *)mem; mtx_lock(&Giant); - pmap_new_thread(td); + pmap_new_thread(td, 0); mtx_unlock(&Giant); cpu_thread_setup(td); } diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index b3a2670..d4230cb 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -1001,7 +1001,7 @@ aio_newproc() int error; struct proc *p; - error = kthread_create(aio_daemon, curproc, &p, RFNOWAIT, "aiod%d", + error = kthread_create(aio_daemon, curproc, &p, RFNOWAIT, 0, "aiod%d", num_aio_procs); if (error) return error; |