summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2002-10-02 07:44:29 +0000
committerscottl <scottl@FreeBSD.org>2002-10-02 07:44:29 +0000
commit3a150bca9cc1b9ca767ca73d95fd54081237210b (patch)
tree0a9cc28f7570a42ae4e5df4cfc55dee42c36d9d8 /sys/kern
parent734ef490b8cfe3acc5f45425a63fac5e7c5173a3 (diff)
downloadFreeBSD-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.c2
-rw-r--r--sys/kern/kern_fork.c13
-rw-r--r--sys/kern/kern_idle.c4
-rw-r--r--sys/kern/kern_intr.c2
-rw-r--r--sys/kern/kern_kse.c2
-rw-r--r--sys/kern/kern_kthread.c6
-rw-r--r--sys/kern/kern_ktrace.c2
-rw-r--r--sys/kern/kern_proc.c9
-rw-r--r--sys/kern/kern_thread.c2
-rw-r--r--sys/kern/vfs_aio.c2
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;
OpenPOWER on IntegriCloud