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: releng/10.3/sys/kern/kern_kthread.c 284199 2015-06-10 02:04:02Z kib $"); 29116182Sobrien 3048391Speter#include <sys/param.h> 3148391Speter#include <sys/systm.h> 32230984Srstone#include <sys/cpuset.h> 3348391Speter#include <sys/kthread.h> 3470317Sjake#include <sys/lock.h> 3574927Sjhb#include <sys/mutex.h> 3674927Sjhb#include <sys/proc.h> 3755722Simp#include <sys/resourcevar.h> 38214238Sdavidxu#include <sys/rwlock.h> 3955539Sluoqi#include <sys/signalvar.h> 4074927Sjhb#include <sys/sx.h> 41280309Skib#include <sys/umtx.h> 4248391Speter#include <sys/unistd.h> 4348391Speter#include <sys/wait.h> 44166188Sjeff#include <sys/sched.h> 45173004Sjulian#include <vm/vm.h> 46173004Sjulian#include <vm/vm_extern.h> 4748391Speter 4848391Speter#include <machine/stdarg.h> 4948391Speter 5048391Speter/* 5148391Speter * Start a kernel process. This is called after a fork() call in 5248391Speter * mi_startup() in the file kern/init_main.c. 5348391Speter * 5448391Speter * This function is used to start "internal" daemons and intended 5548391Speter * to be called from SYSINIT(). 5648391Speter */ 5748391Spetervoid 5848391Speterkproc_start(udata) 5948391Speter const void *udata; 6048391Speter{ 6148391Speter const struct kproc_desc *kp = udata; 6248391Speter int error; 6348391Speter 64172836Sjulian error = kproc_create((void (*)(void *))kp->func, NULL, 65104354Sscottl kp->global_procpp, 0, 0, "%s", kp->arg0); 6648391Speter if (error) 6748391Speter panic("kproc_start: %s: error %d", kp->arg0, error); 6848391Speter} 6948391Speter 7048391Speter/* 7165557Sjasone * Create a kernel process/thread/whatever. It shares its address space 7248391Speter * with proc0 - ie: kernel only. 7365557Sjasone * 7465557Sjasone * func is the function to start. 7565557Sjasone * arg is the parameter to pass to function on first startup. 7665557Sjasone * newpp is the return value pointing to the thread's struct proc. 7765557Sjasone * flags are flags to fork1 (in unistd.h) 7865557Sjasone * fmt and following will be *printf'd into (*newpp)->p_comm (for ps, etc.). 7948391Speter */ 8048391Speterint 81172836Sjuliankproc_create(void (*func)(void *), void *arg, 82104354Sscottl struct proc **newpp, int flags, int pages, const char *fmt, ...) 8348391Speter{ 8448391Speter int error; 8548391Speter va_list ap; 86103216Sjulian struct thread *td; 8748391Speter struct proc *p2; 8848391Speter 89114434Sdes if (!proc0.p_stats) 90172836Sjulian panic("kproc_create called too soon"); 9165557Sjasone 9290375Speter error = fork1(&thread0, RFMEM | RFFDG | RFPROC | RFSTOPPED | flags, 93224987Sjonathan pages, &p2, NULL, 0); 9448391Speter if (error) 9548391Speter return error; 9648391Speter 9748391Speter /* save a global descriptor, if desired */ 9848391Speter if (newpp != NULL) 9948391Speter *newpp = p2; 10048391Speter 10148391Speter /* this is a non-swapped system process */ 10271559Sjhb PROC_LOCK(p2); 103173004Sjulian td = FIRST_THREAD_IN_PROC(p2); 10471559Sjhb p2->p_flag |= P_SYSTEM | P_KTHREAD; 105173004Sjulian td->td_pflags |= TDP_KTHREAD; 106114983Sjhb mtx_lock(&p2->p_sigacts->ps_mtx); 107114983Sjhb p2->p_sigacts->ps_flag |= PS_NOCLDWAIT; 108114983Sjhb mtx_unlock(&p2->p_sigacts->ps_mtx); 10971559Sjhb PROC_UNLOCK(p2); 11048391Speter 11148391Speter /* set up arg0 for 'ps', et al */ 11248391Speter va_start(ap, fmt); 11348391Speter vsnprintf(p2->p_comm, sizeof(p2->p_comm), fmt, ap); 11448391Speter va_end(ap); 115173004Sjulian /* set up arg0 for 'ps', et al */ 116173004Sjulian va_start(ap, fmt); 117173004Sjulian vsnprintf(td->td_name, sizeof(td->td_name), fmt, ap); 118173004Sjulian va_end(ap); 119232700Sjhb#ifdef KTR 120232700Sjhb sched_clear_tdname(td); 121232700Sjhb#endif 12248391Speter 12348391Speter /* call the processes' main()... */ 124103216Sjulian cpu_set_fork_handler(td, func, arg); 125230984Srstone 126230984Srstone /* Avoid inheriting affinity from a random parent. */ 127230984Srstone cpuset_setthread(td->td_tid, cpuset_root); 128217079Sjhb thread_lock(td); 129103216Sjulian TD_SET_CAN_RUN(td); 130217079Sjhb sched_prio(td, PVM); 131217079Sjhb sched_user_prio(td, PUSER); 13248391Speter 13369657Sjhb /* Delay putting it on the run queue until now. */ 134217079Sjhb if (!(flags & RFSTOPPED)) 135166188Sjeff sched_add(td, SRQ_BORING); 136217079Sjhb thread_unlock(td); 13769657Sjhb 13848391Speter return 0; 13948391Speter} 14048391Speter 14148391Spetervoid 142172836Sjuliankproc_exit(int ecode) 14348391Speter{ 14486293Speter struct thread *td; 14586293Speter struct proc *p; 14670317Sjake 14786293Speter td = curthread; 14886293Speter p = td->td_proc; 149155400Sjhb 150155400Sjhb /* 151155400Sjhb * Reparent curthread from proc0 to init so that the zombie 152155400Sjhb * is harvested. 153155400Sjhb */ 15474927Sjhb sx_xlock(&proctree_lock); 15586292Sdillon PROC_LOCK(p); 15686292Sdillon proc_reparent(p, initproc); 15786292Sdillon PROC_UNLOCK(p); 15874927Sjhb sx_xunlock(&proctree_lock); 159155400Sjhb 160155400Sjhb /* 161155400Sjhb * Wakeup anyone waiting for us to exit. 162155400Sjhb */ 163155400Sjhb wakeup(p); 164155400Sjhb 165155400Sjhb /* Buh-bye! */ 16686293Speter exit1(td, W_EXITCODE(ecode, 0)); 16748391Speter} 16848391Speter 16955539Sluoqi/* 17055539Sluoqi * Advise a kernel process to suspend (or resume) in its main loop. 17155539Sluoqi * Participation is voluntary. 17255539Sluoqi */ 17355539Sluoqiint 174172836Sjuliankproc_suspend(struct proc *p, int timo) 17555539Sluoqi{ 17655539Sluoqi /* 17755539Sluoqi * Make sure this is indeed a system process and we can safely 178104306Sjmallett * use the p_siglist field. 17955539Sluoqi */ 18073911Sjhb PROC_LOCK(p); 18173911Sjhb if ((p->p_flag & P_KTHREAD) == 0) { 18273911Sjhb PROC_UNLOCK(p); 18355539Sluoqi return (EINVAL); 18473911Sjhb } 185104306Sjmallett SIGADDSET(p->p_siglist, SIGSTOP); 18688160Speter wakeup(p); 187173004Sjulian return msleep(&p->p_siglist, &p->p_mtx, PPAUSE | PDROP, "suspkp", timo); 18855539Sluoqi} 18955539Sluoqi 19055539Sluoqiint 191172836Sjuliankproc_resume(struct proc *p) 19255539Sluoqi{ 19355539Sluoqi /* 19455539Sluoqi * Make sure this is indeed a system process and we can safely 19555539Sluoqi * use the p_siglist field. 19655539Sluoqi */ 19773911Sjhb PROC_LOCK(p); 19873911Sjhb if ((p->p_flag & P_KTHREAD) == 0) { 19973911Sjhb PROC_UNLOCK(p); 20055539Sluoqi return (EINVAL); 20173911Sjhb } 202104306Sjmallett SIGDELSET(p->p_siglist, SIGSTOP); 20373911Sjhb PROC_UNLOCK(p); 204104306Sjmallett wakeup(&p->p_siglist); 20555539Sluoqi return (0); 20655539Sluoqi} 20755539Sluoqi 20855539Sluoqivoid 209172836Sjuliankproc_suspend_check(struct proc *p) 21055539Sluoqi{ 21173911Sjhb PROC_LOCK(p); 212104306Sjmallett while (SIGISMEMBER(p->p_siglist, SIGSTOP)) { 213104306Sjmallett wakeup(&p->p_siglist); 214173004Sjulian msleep(&p->p_siglist, &p->p_mtx, PPAUSE, "kpsusp", 0); 21555539Sluoqi } 21673911Sjhb PROC_UNLOCK(p); 21755539Sluoqi} 218173004Sjulian 219173004Sjulian 220173004Sjulian/* 221173004Sjulian * Start a kernel thread. 222173004Sjulian * 223173004Sjulian * This function is used to start "internal" daemons and intended 224173004Sjulian * to be called from SYSINIT(). 225173004Sjulian */ 226173004Sjulian 227173004Sjulianvoid 228173004Sjuliankthread_start(udata) 229173004Sjulian const void *udata; 230173004Sjulian{ 231173004Sjulian const struct kthread_desc *kp = udata; 232173004Sjulian int error; 233173004Sjulian 234173004Sjulian error = kthread_add((void (*)(void *))kp->func, NULL, 235173004Sjulian NULL, kp->global_threadpp, 0, 0, "%s", kp->arg0); 236173004Sjulian if (error) 237173004Sjulian panic("kthread_start: %s: error %d", kp->arg0, error); 238173004Sjulian} 239173004Sjulian 240173004Sjulian/* 241173004Sjulian * Create a kernel thread. It shares its address space 242173004Sjulian * with proc0 - ie: kernel only. 243173004Sjulian * 244173004Sjulian * func is the function to start. 245173004Sjulian * arg is the parameter to pass to function on first startup. 246173004Sjulian * newtdp is the return value pointing to the thread's struct thread. 247173004Sjulian * ** XXX fix this --> flags are flags to fork1 (in unistd.h) 248173004Sjulian * fmt and following will be *printf'd into (*newtd)->td_name (for ps, etc.). 249173004Sjulian */ 250173004Sjulianint 251173004Sjuliankthread_add(void (*func)(void *), void *arg, struct proc *p, 252173004Sjulian struct thread **newtdp, int flags, int pages, const char *fmt, ...) 253173004Sjulian{ 254173004Sjulian va_list ap; 255173004Sjulian struct thread *newtd, *oldtd; 256173004Sjulian 257173004Sjulian if (!proc0.p_stats) 258173004Sjulian panic("kthread_add called too soon"); 259173004Sjulian 260173052Sjulian /* If no process supplied, put it on proc0 */ 261254457Sbryanv if (p == NULL) 262173004Sjulian p = &proc0; 263173004Sjulian 264173052Sjulian /* Initialize our new td */ 265196730Skib newtd = thread_alloc(pages); 266173004Sjulian if (newtd == NULL) 267173004Sjulian return (ENOMEM); 268173004Sjulian 269254457Sbryanv PROC_LOCK(p); 270254457Sbryanv oldtd = FIRST_THREAD_IN_PROC(p); 271254457Sbryanv 272173004Sjulian bzero(&newtd->td_startzero, 273173004Sjulian __rangeof(struct thread, td_startzero, td_endzero)); 274284199Skib newtd->td_su = NULL; 275173004Sjulian bcopy(&oldtd->td_startcopy, &newtd->td_startcopy, 276173004Sjulian __rangeof(struct thread, td_startcopy, td_endcopy)); 277173004Sjulian 278173004Sjulian /* set up arg0 for 'ps', et al */ 279173004Sjulian va_start(ap, fmt); 280173004Sjulian vsnprintf(newtd->td_name, sizeof(newtd->td_name), fmt, ap); 281173004Sjulian va_end(ap); 282173004Sjulian 283173004Sjulian newtd->td_proc = p; /* needed for cpu_set_upcall */ 284173004Sjulian 285173004Sjulian /* XXX optimise this probably? */ 286173004Sjulian /* On x86 (and probably the others too) it is way too full of junk */ 287173004Sjulian /* Needs a better name */ 288173004Sjulian cpu_set_upcall(newtd, oldtd); 289173004Sjulian /* put the designated function(arg) as the resume context */ 290173004Sjulian cpu_set_fork_handler(newtd, func, arg); 291173004Sjulian 292173004Sjulian newtd->td_pflags |= TDP_KTHREAD; 293173004Sjulian newtd->td_ucred = crhold(p->p_ucred); 294173004Sjulian 295173004Sjulian /* this code almost the same as create_thread() in kern_thr.c */ 296173004Sjulian p->p_flag |= P_HADTHREADS; 297173004Sjulian thread_link(newtd, p); 298173004Sjulian thread_lock(oldtd); 299173004Sjulian /* let the scheduler know about these things. */ 300173004Sjulian sched_fork_thread(oldtd, newtd); 301173004Sjulian TD_SET_CAN_RUN(newtd); 302173004Sjulian thread_unlock(oldtd); 303173004Sjulian PROC_UNLOCK(p); 304173004Sjulian 305213642Sdavidxu tidhash_add(newtd); 306173004Sjulian 307230984Srstone /* Avoid inheriting affinity from a random parent. */ 308230984Srstone cpuset_setthread(newtd->td_tid, cpuset_root); 309230984Srstone 310173004Sjulian /* Delay putting it on the run queue until now. */ 311173004Sjulian if (!(flags & RFSTOPPED)) { 312173004Sjulian thread_lock(newtd); 313173004Sjulian sched_add(newtd, SRQ_BORING); 314173004Sjulian thread_unlock(newtd); 315173004Sjulian } 316173004Sjulian if (newtdp) 317173004Sjulian *newtdp = newtd; 318173004Sjulian return 0; 319173004Sjulian} 320173004Sjulian 321173004Sjulianvoid 322173031Sjuliankthread_exit(void) 323173004Sjulian{ 324173658Sjhb struct proc *p; 325173658Sjhb 326204087Sattilio p = curthread->td_proc; 327204087Sattilio 328173658Sjhb /* A module may be waiting for us to exit. */ 329173052Sjulian wakeup(curthread); 330216921Sjhb 331216921Sjhb /* 332216921Sjhb * The last exiting thread in a kernel process must tear down 333216921Sjhb * the whole process. 334216921Sjhb */ 335214238Sdavidxu rw_wlock(&tidhash_lock); 336204087Sattilio PROC_LOCK(p); 337204089Sattilio if (p->p_numthreads == 1) { 338204087Sattilio PROC_UNLOCK(p); 339214238Sdavidxu rw_wunlock(&tidhash_lock); 340204087Sattilio kproc_exit(0); 341204087Sattilio } 342214238Sdavidxu LIST_REMOVE(curthread, td_hash); 343214238Sdavidxu rw_wunlock(&tidhash_lock); 344280309Skib umtx_thread_exit(curthread); 345173658Sjhb PROC_SLOCK(p); 346173004Sjulian thread_exit(); 347173004Sjulian} 348173004Sjulian 349173004Sjulian/* 350173004Sjulian * Advise a kernel process to suspend (or resume) in its main loop. 351173004Sjulian * Participation is voluntary. 352173004Sjulian */ 353173004Sjulianint 354173004Sjuliankthread_suspend(struct thread *td, int timo) 355173004Sjulian{ 356202933Sattilio struct proc *p; 357202933Sattilio 358202933Sattilio p = td->td_proc; 359202933Sattilio 360202933Sattilio /* 361204088Sattilio * td_pflags should not be read by any thread other than 362202933Sattilio * curthread, but as long as this flag is invariant during the 363204088Sattilio * thread's lifetime, it is OK to check its state. 364202933Sattilio */ 365202933Sattilio if ((td->td_pflags & TDP_KTHREAD) == 0) 366173004Sjulian return (EINVAL); 367202933Sattilio 368202933Sattilio /* 369202933Sattilio * The caller of the primitive should have already checked that the 370202933Sattilio * thread is up and running, thus not being blocked by other 371202933Sattilio * conditions. 372202933Sattilio */ 373202933Sattilio PROC_LOCK(p); 374173004Sjulian thread_lock(td); 375173004Sjulian td->td_flags |= TDF_KTH_SUSP; 376173004Sjulian thread_unlock(td); 377202933Sattilio return (msleep(&td->td_flags, &p->p_mtx, PPAUSE | PDROP, "suspkt", 378202933Sattilio timo)); 379173004Sjulian} 380173004Sjulian 381173004Sjulian/* 382202933Sattilio * Resume a thread previously put asleep with kthread_suspend(). 383173004Sjulian */ 384173004Sjulianint 385173004Sjuliankthread_resume(struct thread *td) 386173004Sjulian{ 387202933Sattilio struct proc *p; 388202933Sattilio 389202933Sattilio p = td->td_proc; 390202933Sattilio 391202933Sattilio /* 392204088Sattilio * td_pflags should not be read by any thread other than 393202933Sattilio * curthread, but as long as this flag is invariant during the 394204088Sattilio * thread's lifetime, it is OK to check its state. 395202933Sattilio */ 396202933Sattilio if ((td->td_pflags & TDP_KTHREAD) == 0) 397173004Sjulian return (EINVAL); 398202933Sattilio 399202933Sattilio PROC_LOCK(p); 400173004Sjulian thread_lock(td); 401173004Sjulian td->td_flags &= ~TDF_KTH_SUSP; 402173004Sjulian thread_unlock(td); 403202933Sattilio wakeup(&td->td_flags); 404202933Sattilio PROC_UNLOCK(p); 405173004Sjulian return (0); 406173004Sjulian} 407173004Sjulian 408173004Sjulian/* 409173004Sjulian * Used by the thread to poll as to whether it should yield/sleep 410173004Sjulian * and notify the caller that is has happened. 411173004Sjulian */ 412173004Sjulianvoid 413202933Sattiliokthread_suspend_check() 414173004Sjulian{ 415202933Sattilio struct proc *p; 416202933Sattilio struct thread *td; 417202933Sattilio 418202933Sattilio td = curthread; 419202933Sattilio p = td->td_proc; 420202933Sattilio 421202933Sattilio if ((td->td_pflags & TDP_KTHREAD) == 0) 422202933Sattilio panic("%s: curthread is not a valid kthread", __func__); 423202933Sattilio 424202933Sattilio /* 425202933Sattilio * As long as the double-lock protection is used when accessing the 426202933Sattilio * TDF_KTH_SUSP flag, synchronizing the read operation via proc mutex 427202933Sattilio * is fine. 428202933Sattilio */ 429202933Sattilio PROC_LOCK(p); 430173004Sjulian while (td->td_flags & TDF_KTH_SUSP) { 431173004Sjulian wakeup(&td->td_flags); 432202933Sattilio msleep(&td->td_flags, &p->p_mtx, PPAUSE, "ktsusp", 0); 433173004Sjulian } 434202933Sattilio PROC_UNLOCK(p); 435173004Sjulian} 436173004Sjulian 437173004Sjulianint 438173004Sjuliankproc_kthread_add(void (*func)(void *), void *arg, 439173004Sjulian struct proc **procptr, struct thread **tdptr, 440208390Sjhb int flags, int pages, const char *procname, const char *fmt, ...) 441173004Sjulian{ 442173004Sjulian int error; 443173004Sjulian va_list ap; 444173004Sjulian char buf[100]; 445173004Sjulian struct thread *td; 446173004Sjulian 447173004Sjulian if (*procptr == 0) { 448173004Sjulian error = kproc_create(func, arg, 449173004Sjulian procptr, flags, pages, "%s", procname); 450173004Sjulian if (error) 451173004Sjulian return (error); 452173004Sjulian td = FIRST_THREAD_IN_PROC(*procptr); 453178682Sjulian if (tdptr) 454178682Sjulian *tdptr = td; 455173004Sjulian va_start(ap, fmt); 456173004Sjulian vsnprintf(td->td_name, sizeof(td->td_name), fmt, ap); 457173004Sjulian va_end(ap); 458232700Sjhb#ifdef KTR 459232700Sjhb sched_clear_tdname(td); 460232700Sjhb#endif 461173004Sjulian return (0); 462173004Sjulian } 463173004Sjulian va_start(ap, fmt); 464173004Sjulian vsnprintf(buf, sizeof(buf), fmt, ap); 465173004Sjulian va_end(ap); 466173004Sjulian error = kthread_add(func, arg, *procptr, 467173004Sjulian tdptr, flags, pages, "%s", buf); 468173004Sjulian return (error); 469173004Sjulian} 470