kern_kthread.c revision 216921
1139804Simp/*- 248391Speter * Copyright (c) 1999 Peter Wemm <peter@FreeBSD.org> 348391Speter * All rights reserved. 448391Speter * 548391Speter * Redistribution and use in source and binary forms, with or without 648391Speter * modification, are permitted provided that the following conditions 748391Speter * are met: 848391Speter * 1. Redistributions of source code must retain the above copyright 948391Speter * notice, this list of conditions and the following disclaimer. 1048391Speter * 2. Redistributions in binary form must reproduce the above copyright 1148391Speter * notice, this list of conditions and the following disclaimer in the 1248391Speter * documentation and/or other materials provided with the distribution. 1348391Speter * 1448391Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1548391Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1648391Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1748391Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1848391Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1948391Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2048391Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2148391Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2248391Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2348391Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2448391Speter * SUCH DAMAGE. 2548391Speter */ 2648391Speter 27116182Sobrien#include <sys/cdefs.h> 28116182Sobrien__FBSDID("$FreeBSD: head/sys/kern/kern_kthread.c 216921 2011-01-03 16:29:00Z jhb $"); 29116182Sobrien 3048391Speter#include <sys/param.h> 3148391Speter#include <sys/systm.h> 3248391Speter#include <sys/kthread.h> 3370317Sjake#include <sys/lock.h> 3474927Sjhb#include <sys/mutex.h> 3574927Sjhb#include <sys/proc.h> 3655722Simp#include <sys/resourcevar.h> 37214238Sdavidxu#include <sys/rwlock.h> 3855539Sluoqi#include <sys/signalvar.h> 3974927Sjhb#include <sys/sx.h> 4048391Speter#include <sys/unistd.h> 4148391Speter#include <sys/wait.h> 42166188Sjeff#include <sys/sched.h> 43173004Sjulian#include <vm/vm.h> 44173004Sjulian#include <vm/vm_extern.h> 4548391Speter 4648391Speter#include <machine/stdarg.h> 4748391Speter 4848391Speter/* 4948391Speter * Start a kernel process. This is called after a fork() call in 5048391Speter * mi_startup() in the file kern/init_main.c. 5148391Speter * 5248391Speter * This function is used to start "internal" daemons and intended 5348391Speter * to be called from SYSINIT(). 5448391Speter */ 5548391Spetervoid 5648391Speterkproc_start(udata) 5748391Speter const void *udata; 5848391Speter{ 5948391Speter const struct kproc_desc *kp = udata; 6048391Speter int error; 6148391Speter 62172836Sjulian error = kproc_create((void (*)(void *))kp->func, NULL, 63104354Sscottl kp->global_procpp, 0, 0, "%s", kp->arg0); 6448391Speter if (error) 6548391Speter panic("kproc_start: %s: error %d", kp->arg0, error); 6648391Speter} 6748391Speter 6848391Speter/* 6965557Sjasone * Create a kernel process/thread/whatever. It shares its address space 7048391Speter * with proc0 - ie: kernel only. 7165557Sjasone * 7265557Sjasone * func is the function to start. 7365557Sjasone * arg is the parameter to pass to function on first startup. 7465557Sjasone * newpp is the return value pointing to the thread's struct proc. 7565557Sjasone * flags are flags to fork1 (in unistd.h) 7665557Sjasone * fmt and following will be *printf'd into (*newpp)->p_comm (for ps, etc.). 7748391Speter */ 7848391Speterint 79172836Sjuliankproc_create(void (*func)(void *), void *arg, 80104354Sscottl struct proc **newpp, int flags, int pages, const char *fmt, ...) 8148391Speter{ 8248391Speter int error; 8348391Speter va_list ap; 84103216Sjulian struct thread *td; 8548391Speter struct proc *p2; 8648391Speter 87114434Sdes if (!proc0.p_stats) 88172836Sjulian panic("kproc_create called too soon"); 8965557Sjasone 9090375Speter error = fork1(&thread0, RFMEM | RFFDG | RFPROC | RFSTOPPED | flags, 91104354Sscottl pages, &p2); 9248391Speter if (error) 9348391Speter return error; 9448391Speter 9548391Speter /* save a global descriptor, if desired */ 9648391Speter if (newpp != NULL) 9748391Speter *newpp = p2; 9848391Speter 9948391Speter /* this is a non-swapped system process */ 10071559Sjhb PROC_LOCK(p2); 101173004Sjulian td = FIRST_THREAD_IN_PROC(p2); 10271559Sjhb p2->p_flag |= P_SYSTEM | P_KTHREAD; 103173004Sjulian td->td_pflags |= TDP_KTHREAD; 104114983Sjhb mtx_lock(&p2->p_sigacts->ps_mtx); 105114983Sjhb p2->p_sigacts->ps_flag |= PS_NOCLDWAIT; 106114983Sjhb mtx_unlock(&p2->p_sigacts->ps_mtx); 10771559Sjhb PROC_UNLOCK(p2); 10848391Speter 10948391Speter /* set up arg0 for 'ps', et al */ 11048391Speter va_start(ap, fmt); 11148391Speter vsnprintf(p2->p_comm, sizeof(p2->p_comm), fmt, ap); 11248391Speter va_end(ap); 113173004Sjulian /* set up arg0 for 'ps', et al */ 114173004Sjulian va_start(ap, fmt); 115173004Sjulian vsnprintf(td->td_name, sizeof(td->td_name), fmt, ap); 116173004Sjulian va_end(ap); 11748391Speter 11848391Speter /* call the processes' main()... */ 119103216Sjulian cpu_set_fork_handler(td, func, arg); 120103216Sjulian TD_SET_CAN_RUN(td); 12148391Speter 12269657Sjhb /* Delay putting it on the run queue until now. */ 12369657Sjhb if (!(flags & RFSTOPPED)) { 124170307Sjeff thread_lock(td); 125166188Sjeff sched_add(td, SRQ_BORING); 126170307Sjeff thread_unlock(td); 12769657Sjhb } 12869657Sjhb 12948391Speter return 0; 13048391Speter} 13148391Speter 13248391Spetervoid 133172836Sjuliankproc_exit(int ecode) 13448391Speter{ 13586293Speter struct thread *td; 13686293Speter struct proc *p; 13770317Sjake 13886293Speter td = curthread; 13986293Speter p = td->td_proc; 140155400Sjhb 141155400Sjhb /* 142155400Sjhb * Reparent curthread from proc0 to init so that the zombie 143155400Sjhb * is harvested. 144155400Sjhb */ 14574927Sjhb sx_xlock(&proctree_lock); 14686292Sdillon PROC_LOCK(p); 14786292Sdillon proc_reparent(p, initproc); 14886292Sdillon PROC_UNLOCK(p); 14974927Sjhb sx_xunlock(&proctree_lock); 150155400Sjhb 151155400Sjhb /* 152155400Sjhb * Wakeup anyone waiting for us to exit. 153155400Sjhb */ 154155400Sjhb wakeup(p); 155155400Sjhb 156155400Sjhb /* Buh-bye! */ 15786293Speter exit1(td, W_EXITCODE(ecode, 0)); 15848391Speter} 15948391Speter 16055539Sluoqi/* 16155539Sluoqi * Advise a kernel process to suspend (or resume) in its main loop. 16255539Sluoqi * Participation is voluntary. 16355539Sluoqi */ 16455539Sluoqiint 165172836Sjuliankproc_suspend(struct proc *p, int timo) 16655539Sluoqi{ 16755539Sluoqi /* 16855539Sluoqi * Make sure this is indeed a system process and we can safely 169104306Sjmallett * use the p_siglist field. 17055539Sluoqi */ 17173911Sjhb PROC_LOCK(p); 17273911Sjhb if ((p->p_flag & P_KTHREAD) == 0) { 17373911Sjhb PROC_UNLOCK(p); 17455539Sluoqi return (EINVAL); 17573911Sjhb } 176104306Sjmallett SIGADDSET(p->p_siglist, SIGSTOP); 17788160Speter wakeup(p); 178173004Sjulian return msleep(&p->p_siglist, &p->p_mtx, PPAUSE | PDROP, "suspkp", timo); 17955539Sluoqi} 18055539Sluoqi 18155539Sluoqiint 182172836Sjuliankproc_resume(struct proc *p) 18355539Sluoqi{ 18455539Sluoqi /* 18555539Sluoqi * Make sure this is indeed a system process and we can safely 18655539Sluoqi * use the p_siglist field. 18755539Sluoqi */ 18873911Sjhb PROC_LOCK(p); 18973911Sjhb if ((p->p_flag & P_KTHREAD) == 0) { 19073911Sjhb PROC_UNLOCK(p); 19155539Sluoqi return (EINVAL); 19273911Sjhb } 193104306Sjmallett SIGDELSET(p->p_siglist, SIGSTOP); 19473911Sjhb PROC_UNLOCK(p); 195104306Sjmallett wakeup(&p->p_siglist); 19655539Sluoqi return (0); 19755539Sluoqi} 19855539Sluoqi 19955539Sluoqivoid 200172836Sjuliankproc_suspend_check(struct proc *p) 20155539Sluoqi{ 20273911Sjhb PROC_LOCK(p); 203104306Sjmallett while (SIGISMEMBER(p->p_siglist, SIGSTOP)) { 204104306Sjmallett wakeup(&p->p_siglist); 205173004Sjulian msleep(&p->p_siglist, &p->p_mtx, PPAUSE, "kpsusp", 0); 20655539Sluoqi } 20773911Sjhb PROC_UNLOCK(p); 20855539Sluoqi} 209173004Sjulian 210173004Sjulian 211173004Sjulian/* 212173004Sjulian * Start a kernel thread. 213173004Sjulian * 214173004Sjulian * This function is used to start "internal" daemons and intended 215173004Sjulian * to be called from SYSINIT(). 216173004Sjulian */ 217173004Sjulian 218173004Sjulianvoid 219173004Sjuliankthread_start(udata) 220173004Sjulian const void *udata; 221173004Sjulian{ 222173004Sjulian const struct kthread_desc *kp = udata; 223173004Sjulian int error; 224173004Sjulian 225173004Sjulian error = kthread_add((void (*)(void *))kp->func, NULL, 226173004Sjulian NULL, kp->global_threadpp, 0, 0, "%s", kp->arg0); 227173004Sjulian if (error) 228173004Sjulian panic("kthread_start: %s: error %d", kp->arg0, error); 229173004Sjulian} 230173004Sjulian 231173004Sjulian/* 232173004Sjulian * Create a kernel thread. It shares its address space 233173004Sjulian * with proc0 - ie: kernel only. 234173004Sjulian * 235173004Sjulian * func is the function to start. 236173004Sjulian * arg is the parameter to pass to function on first startup. 237173004Sjulian * newtdp is the return value pointing to the thread's struct thread. 238173004Sjulian * ** XXX fix this --> flags are flags to fork1 (in unistd.h) 239173004Sjulian * fmt and following will be *printf'd into (*newtd)->td_name (for ps, etc.). 240173004Sjulian */ 241173004Sjulianint 242173004Sjuliankthread_add(void (*func)(void *), void *arg, struct proc *p, 243173004Sjulian struct thread **newtdp, int flags, int pages, const char *fmt, ...) 244173004Sjulian{ 245173004Sjulian va_list ap; 246173004Sjulian struct thread *newtd, *oldtd; 247173004Sjulian 248173004Sjulian if (!proc0.p_stats) 249173004Sjulian panic("kthread_add called too soon"); 250173004Sjulian 251173052Sjulian /* If no process supplied, put it on proc0 */ 252173004Sjulian if (p == NULL) { 253173004Sjulian p = &proc0; 254173004Sjulian oldtd = &thread0; 255173004Sjulian } else { 256173052Sjulian oldtd = FIRST_THREAD_IN_PROC(p); 257173004Sjulian } 258173004Sjulian 259173052Sjulian /* Initialize our new td */ 260196730Skib newtd = thread_alloc(pages); 261173004Sjulian if (newtd == NULL) 262173004Sjulian return (ENOMEM); 263173004Sjulian 264173004Sjulian bzero(&newtd->td_startzero, 265173004Sjulian __rangeof(struct thread, td_startzero, td_endzero)); 266173004Sjulian/* XXX check if we should zero. */ 267173004Sjulian bcopy(&oldtd->td_startcopy, &newtd->td_startcopy, 268173004Sjulian __rangeof(struct thread, td_startcopy, td_endcopy)); 269173004Sjulian 270173004Sjulian /* set up arg0 for 'ps', et al */ 271173004Sjulian va_start(ap, fmt); 272173004Sjulian vsnprintf(newtd->td_name, sizeof(newtd->td_name), fmt, ap); 273173004Sjulian va_end(ap); 274173004Sjulian 275173004Sjulian newtd->td_proc = p; /* needed for cpu_set_upcall */ 276173004Sjulian 277173004Sjulian /* XXX optimise this probably? */ 278173004Sjulian /* On x86 (and probably the others too) it is way too full of junk */ 279173004Sjulian /* Needs a better name */ 280173004Sjulian cpu_set_upcall(newtd, oldtd); 281173004Sjulian /* put the designated function(arg) as the resume context */ 282173004Sjulian cpu_set_fork_handler(newtd, func, arg); 283173004Sjulian 284173004Sjulian newtd->td_pflags |= TDP_KTHREAD; 285173004Sjulian newtd->td_ucred = crhold(p->p_ucred); 286173004Sjulian 287173004Sjulian /* this code almost the same as create_thread() in kern_thr.c */ 288173004Sjulian PROC_LOCK(p); 289173004Sjulian p->p_flag |= P_HADTHREADS; 290173004Sjulian newtd->td_sigmask = oldtd->td_sigmask; /* XXX dubious */ 291173004Sjulian thread_link(newtd, p); 292173004Sjulian thread_lock(oldtd); 293173004Sjulian /* let the scheduler know about these things. */ 294173004Sjulian sched_fork_thread(oldtd, newtd); 295173004Sjulian TD_SET_CAN_RUN(newtd); 296173004Sjulian thread_unlock(oldtd); 297173004Sjulian PROC_UNLOCK(p); 298173004Sjulian 299213642Sdavidxu tidhash_add(newtd); 300173004Sjulian 301173004Sjulian /* Delay putting it on the run queue until now. */ 302173004Sjulian if (!(flags & RFSTOPPED)) { 303173004Sjulian thread_lock(newtd); 304173004Sjulian sched_add(newtd, SRQ_BORING); 305173004Sjulian thread_unlock(newtd); 306173004Sjulian } 307173004Sjulian if (newtdp) 308173004Sjulian *newtdp = newtd; 309173004Sjulian return 0; 310173004Sjulian} 311173004Sjulian 312173004Sjulianvoid 313173031Sjuliankthread_exit(void) 314173004Sjulian{ 315173658Sjhb struct proc *p; 316173658Sjhb 317204087Sattilio p = curthread->td_proc; 318204087Sattilio 319173658Sjhb /* A module may be waiting for us to exit. */ 320173052Sjulian wakeup(curthread); 321216921Sjhb 322216921Sjhb /* 323216921Sjhb * The last exiting thread in a kernel process must tear down 324216921Sjhb * the whole process. 325216921Sjhb */ 326214238Sdavidxu rw_wlock(&tidhash_lock); 327204087Sattilio PROC_LOCK(p); 328204089Sattilio if (p->p_numthreads == 1) { 329204087Sattilio PROC_UNLOCK(p); 330214238Sdavidxu rw_wunlock(&tidhash_lock); 331204087Sattilio kproc_exit(0); 332216921Sjhb /* NOTREACHED */ 333204087Sattilio } 334214238Sdavidxu LIST_REMOVE(curthread, td_hash); 335214238Sdavidxu rw_wunlock(&tidhash_lock); 336173658Sjhb PROC_SLOCK(p); 337173004Sjulian thread_exit(); 338173004Sjulian} 339173004Sjulian 340173004Sjulian/* 341173004Sjulian * Advise a kernel process to suspend (or resume) in its main loop. 342173004Sjulian * Participation is voluntary. 343173004Sjulian */ 344173004Sjulianint 345173004Sjuliankthread_suspend(struct thread *td, int timo) 346173004Sjulian{ 347202933Sattilio struct proc *p; 348202933Sattilio 349202933Sattilio p = td->td_proc; 350202933Sattilio 351202933Sattilio /* 352204088Sattilio * td_pflags should not be read by any thread other than 353202933Sattilio * curthread, but as long as this flag is invariant during the 354204088Sattilio * thread's lifetime, it is OK to check its state. 355202933Sattilio */ 356202933Sattilio if ((td->td_pflags & TDP_KTHREAD) == 0) 357173004Sjulian return (EINVAL); 358202933Sattilio 359202933Sattilio /* 360202933Sattilio * The caller of the primitive should have already checked that the 361202933Sattilio * thread is up and running, thus not being blocked by other 362202933Sattilio * conditions. 363202933Sattilio */ 364202933Sattilio PROC_LOCK(p); 365173004Sjulian thread_lock(td); 366173004Sjulian td->td_flags |= TDF_KTH_SUSP; 367173004Sjulian thread_unlock(td); 368202933Sattilio return (msleep(&td->td_flags, &p->p_mtx, PPAUSE | PDROP, "suspkt", 369202933Sattilio timo)); 370173004Sjulian} 371173004Sjulian 372173004Sjulian/* 373202933Sattilio * Resume a thread previously put asleep with kthread_suspend(). 374173004Sjulian */ 375173004Sjulianint 376173004Sjuliankthread_resume(struct thread *td) 377173004Sjulian{ 378202933Sattilio struct proc *p; 379202933Sattilio 380202933Sattilio p = td->td_proc; 381202933Sattilio 382202933Sattilio /* 383204088Sattilio * td_pflags should not be read by any thread other than 384202933Sattilio * curthread, but as long as this flag is invariant during the 385204088Sattilio * thread's lifetime, it is OK to check its state. 386202933Sattilio */ 387202933Sattilio if ((td->td_pflags & TDP_KTHREAD) == 0) 388173004Sjulian return (EINVAL); 389202933Sattilio 390202933Sattilio PROC_LOCK(p); 391173004Sjulian thread_lock(td); 392173004Sjulian td->td_flags &= ~TDF_KTH_SUSP; 393173004Sjulian thread_unlock(td); 394202933Sattilio wakeup(&td->td_flags); 395202933Sattilio PROC_UNLOCK(p); 396173004Sjulian return (0); 397173004Sjulian} 398173004Sjulian 399173004Sjulian/* 400173004Sjulian * Used by the thread to poll as to whether it should yield/sleep 401173004Sjulian * and notify the caller that is has happened. 402173004Sjulian */ 403173004Sjulianvoid 404202933Sattiliokthread_suspend_check() 405173004Sjulian{ 406202933Sattilio struct proc *p; 407202933Sattilio struct thread *td; 408202933Sattilio 409202933Sattilio td = curthread; 410202933Sattilio p = td->td_proc; 411202933Sattilio 412202933Sattilio if ((td->td_pflags & TDP_KTHREAD) == 0) 413202933Sattilio panic("%s: curthread is not a valid kthread", __func__); 414202933Sattilio 415202933Sattilio /* 416202933Sattilio * As long as the double-lock protection is used when accessing the 417202933Sattilio * TDF_KTH_SUSP flag, synchronizing the read operation via proc mutex 418202933Sattilio * is fine. 419202933Sattilio */ 420202933Sattilio PROC_LOCK(p); 421173004Sjulian while (td->td_flags & TDF_KTH_SUSP) { 422173004Sjulian wakeup(&td->td_flags); 423202933Sattilio msleep(&td->td_flags, &p->p_mtx, PPAUSE, "ktsusp", 0); 424173004Sjulian } 425202933Sattilio PROC_UNLOCK(p); 426173004Sjulian} 427173004Sjulian 428173004Sjulianint 429173004Sjuliankproc_kthread_add(void (*func)(void *), void *arg, 430173004Sjulian struct proc **procptr, struct thread **tdptr, 431208390Sjhb int flags, int pages, const char *procname, const char *fmt, ...) 432173004Sjulian{ 433173004Sjulian int error; 434173004Sjulian va_list ap; 435173004Sjulian char buf[100]; 436173004Sjulian struct thread *td; 437173004Sjulian 438173004Sjulian if (*procptr == 0) { 439173004Sjulian error = kproc_create(func, arg, 440173004Sjulian procptr, flags, pages, "%s", procname); 441173004Sjulian if (error) 442173004Sjulian return (error); 443173004Sjulian td = FIRST_THREAD_IN_PROC(*procptr); 444178682Sjulian if (tdptr) 445178682Sjulian *tdptr = td; 446173004Sjulian va_start(ap, fmt); 447173004Sjulian vsnprintf(td->td_name, sizeof(td->td_name), fmt, ap); 448173004Sjulian va_end(ap); 449173004Sjulian return (0); 450173004Sjulian } 451173004Sjulian va_start(ap, fmt); 452173004Sjulian vsnprintf(buf, sizeof(buf), fmt, ap); 453173004Sjulian va_end(ap); 454173004Sjulian error = kthread_add(func, arg, *procptr, 455173004Sjulian tdptr, flags, pages, "%s", buf); 456173004Sjulian return (error); 457173004Sjulian} 458