Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_kthread.c
Show All 26 Lines | |||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/cpuset.h> | #include <sys/cpuset.h> | ||||
#include <sys/jail.h> | |||||
#include <sys/kthread.h> | #include <sys/kthread.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/resourcevar.h> | #include <sys/resourcevar.h> | ||||
#include <sys/rwlock.h> | #include <sys/rwlock.h> | ||||
#include <sys/signalvar.h> | #include <sys/signalvar.h> | ||||
#include <sys/sx.h> | #include <sys/sx.h> | ||||
#include <sys/umtx.h> | #include <sys/umtx.h> | ||||
#include <sys/unistd.h> | #include <sys/unistd.h> | ||||
#include <sys/wait.h> | #include <sys/wait.h> | ||||
#include <sys/sched.h> | #include <sys/sched.h> | ||||
#include <sys/tslog.h> | #include <sys/tslog.h> | ||||
#include <sys/vps.h> | |||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/vm_extern.h> | #include <vm/vm_extern.h> | ||||
#include <machine/stdarg.h> | #include <machine/stdarg.h> | ||||
/* | /* | ||||
* Start a kernel process. This is called after a fork() call in | * Start a kernel process. This is called after a fork() call in | ||||
* mi_startup() in the file kern/init_main.c. | * mi_startup() in the file kern/init_main.c. | ||||
▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | kproc_exit(int ecode) | ||||
td = curthread; | td = curthread; | ||||
p = td->td_proc; | p = td->td_proc; | ||||
/* | /* | ||||
* Reparent curthread from proc0 to init so that the zombie | * Reparent curthread from proc0 to init so that the zombie | ||||
* is harvested. | * is harvested. | ||||
*/ | */ | ||||
sx_xlock(&proctree_lock); | sx_xlock(&V_proctree_lock); | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
proc_reparent(p, initproc); | #ifdef VIMAGE | ||||
/* | |||||
* In the VIMAGE case if the kproc is our virtual "swapper" | |||||
* do not reparent it to our init as otherwise it would create | |||||
* a circle and never go away. Let the parent vps reap it | |||||
* as it was setup. And it needs to be the init there and | |||||
* not the swapper(kernel). | |||||
*/ | |||||
if (!IS_DEFAULT_VPS(TD_TO_VPS(FIRST_THREAD_IN_PROC(p))) && | |||||
p->p_pid == 0) { | |||||
struct proc *init0; | |||||
CURVPS_SET_QUIET(vps0) | |||||
init0 = V_initproc; | |||||
CURVPS_RESTORE(); | |||||
proc_reparent(p, init0); | |||||
} else | |||||
#endif | |||||
proc_reparent(p, V_initproc); | |||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
sx_xunlock(&proctree_lock); | sx_xunlock(&V_proctree_lock); | ||||
/* | /* | ||||
* Wakeup anyone waiting for us to exit. | * Wakeup anyone waiting for us to exit. | ||||
*/ | */ | ||||
wakeup(p); | wakeup(p); | ||||
/* Buh-bye! */ | /* Buh-bye! */ | ||||
exit1(td, ecode, 0); | exit1(td, ecode, 0); | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | kthread_add(void (*func)(void *), void *arg, struct proc *p, | ||||
va_list ap; | va_list ap; | ||||
struct thread *newtd, *oldtd; | struct thread *newtd, *oldtd; | ||||
if (!proc0.p_stats) | if (!proc0.p_stats) | ||||
panic("kthread_add called too soon"); | panic("kthread_add called too soon"); | ||||
/* If no process supplied, put it on proc0 */ | /* If no process supplied, put it on proc0 */ | ||||
if (p == NULL) | if (p == NULL) | ||||
p = &proc0; | p = V_vproc0; | ||||
/* Initialize our new td */ | /* Initialize our new td */ | ||||
newtd = thread_alloc(pages); | newtd = thread_alloc(pages); | ||||
if (newtd == NULL) | if (newtd == NULL) | ||||
return (ENOMEM); | return (ENOMEM); | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
oldtd = FIRST_THREAD_IN_PROC(p); | oldtd = FIRST_THREAD_IN_PROC(p); | ||||
bzero(&newtd->td_startzero, | bzero(&newtd->td_startzero, | ||||
__rangeof(struct thread, td_startzero, td_endzero)); | __rangeof(struct thread, td_startzero, td_endzero)); | ||||
bcopy(&oldtd->td_startcopy, &newtd->td_startcopy, | bcopy(&oldtd->td_startcopy, &newtd->td_startcopy, | ||||
__rangeof(struct thread, td_startcopy, td_endcopy)); | __rangeof(struct thread, td_startcopy, td_endcopy)); | ||||
/* set up arg0 for 'ps', et al */ | /* set up arg0 for 'ps', et al */ | ||||
va_start(ap, fmt); | va_start(ap, fmt); | ||||
vsnprintf(newtd->td_name, sizeof(newtd->td_name), fmt, ap); | vsnprintf(newtd->td_name, sizeof(newtd->td_name), fmt, ap); | ||||
va_end(ap); | va_end(ap); | ||||
TSTHREAD(newtd, newtd->td_name); | TSTHREAD(newtd, newtd->td_name); | ||||
newtd->td_proc = p; /* needed for cpu_copy_thread */ | newtd->td_proc = p; /* needed for cpu_copy_thread */ | ||||
#ifdef VIMAGE | |||||
newtd->td_vps = TD_TO_VPS(oldtd); | |||||
#endif | |||||
/* might be further optimized for kthread */ | /* might be further optimized for kthread */ | ||||
cpu_copy_thread(newtd, oldtd); | cpu_copy_thread(newtd, oldtd); | ||||
/* put the designated function(arg) as the resume context */ | /* put the designated function(arg) as the resume context */ | ||||
cpu_fork_kthread_handler(newtd, func, arg); | cpu_fork_kthread_handler(newtd, func, arg); | ||||
newtd->td_pflags |= TDP_KTHREAD; | newtd->td_pflags |= TDP_KTHREAD; | ||||
thread_cow_get_proc(newtd, p); | thread_cow_get_proc(newtd, p); | ||||
▲ Show 20 Lines • Show All 185 Lines • Show Last 20 Lines |