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$");
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;
275304905Skib	newtd->td_sleeptimo = 0;
276173004Sjulian	bcopy(&oldtd->td_startcopy, &newtd->td_startcopy,
277173004Sjulian	    __rangeof(struct thread, td_startcopy, td_endcopy));
278173004Sjulian
279173004Sjulian	/* set up arg0 for 'ps', et al */
280173004Sjulian	va_start(ap, fmt);
281173004Sjulian	vsnprintf(newtd->td_name, sizeof(newtd->td_name), fmt, ap);
282173004Sjulian	va_end(ap);
283173004Sjulian
284173004Sjulian	newtd->td_proc = p;  /* needed for cpu_set_upcall */
285173004Sjulian
286173004Sjulian	/* XXX optimise this probably? */
287173004Sjulian	/* On x86 (and probably the others too) it is way too full of junk */
288173004Sjulian	/* Needs a better name */
289173004Sjulian	cpu_set_upcall(newtd, oldtd);
290173004Sjulian	/* put the designated function(arg) as the resume context */
291173004Sjulian	cpu_set_fork_handler(newtd, func, arg);
292173004Sjulian
293173004Sjulian	newtd->td_pflags |= TDP_KTHREAD;
294173004Sjulian	newtd->td_ucred = crhold(p->p_ucred);
295173004Sjulian
296173004Sjulian	/* this code almost the same as create_thread() in kern_thr.c */
297173004Sjulian	p->p_flag |= P_HADTHREADS;
298173004Sjulian	thread_link(newtd, p);
299173004Sjulian	thread_lock(oldtd);
300173004Sjulian	/* let the scheduler know about these things. */
301173004Sjulian	sched_fork_thread(oldtd, newtd);
302173004Sjulian	TD_SET_CAN_RUN(newtd);
303173004Sjulian	thread_unlock(oldtd);
304173004Sjulian	PROC_UNLOCK(p);
305173004Sjulian
306213642Sdavidxu	tidhash_add(newtd);
307173004Sjulian
308230984Srstone	/* Avoid inheriting affinity from a random parent. */
309230984Srstone	cpuset_setthread(newtd->td_tid, cpuset_root);
310230984Srstone
311173004Sjulian	/* Delay putting it on the run queue until now. */
312173004Sjulian	if (!(flags & RFSTOPPED)) {
313173004Sjulian		thread_lock(newtd);
314173004Sjulian		sched_add(newtd, SRQ_BORING);
315173004Sjulian		thread_unlock(newtd);
316173004Sjulian	}
317173004Sjulian	if (newtdp)
318173004Sjulian		*newtdp = newtd;
319173004Sjulian	return 0;
320173004Sjulian}
321173004Sjulian
322173004Sjulianvoid
323173031Sjuliankthread_exit(void)
324173004Sjulian{
325173658Sjhb	struct proc *p;
326304264Skib	struct thread *td;
327173658Sjhb
328304264Skib	td = curthread;
329304264Skib	p = td->td_proc;
330204087Sattilio
331173658Sjhb	/* A module may be waiting for us to exit. */
332304264Skib	wakeup(td);
333216921Sjhb
334216921Sjhb	/*
335216921Sjhb	 * The last exiting thread in a kernel process must tear down
336216921Sjhb	 * the whole process.
337216921Sjhb	 */
338214238Sdavidxu	rw_wlock(&tidhash_lock);
339204087Sattilio	PROC_LOCK(p);
340204089Sattilio	if (p->p_numthreads == 1) {
341204087Sattilio		PROC_UNLOCK(p);
342214238Sdavidxu		rw_wunlock(&tidhash_lock);
343204087Sattilio		kproc_exit(0);
344204087Sattilio	}
345304264Skib	LIST_REMOVE(td, td_hash);
346214238Sdavidxu	rw_wunlock(&tidhash_lock);
347304264Skib	umtx_thread_exit(td);
348304264Skib	tdsigcleanup(td);
349173658Sjhb	PROC_SLOCK(p);
350173004Sjulian	thread_exit();
351173004Sjulian}
352173004Sjulian
353173004Sjulian/*
354173004Sjulian * Advise a kernel process to suspend (or resume) in its main loop.
355173004Sjulian * Participation is voluntary.
356173004Sjulian */
357173004Sjulianint
358173004Sjuliankthread_suspend(struct thread *td, int timo)
359173004Sjulian{
360202933Sattilio	struct proc *p;
361202933Sattilio
362202933Sattilio	p = td->td_proc;
363202933Sattilio
364202933Sattilio	/*
365204088Sattilio	 * td_pflags should not be read by any thread other than
366202933Sattilio	 * curthread, but as long as this flag is invariant during the
367204088Sattilio	 * thread's lifetime, it is OK to check its state.
368202933Sattilio	 */
369202933Sattilio	if ((td->td_pflags & TDP_KTHREAD) == 0)
370173004Sjulian		return (EINVAL);
371202933Sattilio
372202933Sattilio	/*
373202933Sattilio	 * The caller of the primitive should have already checked that the
374202933Sattilio	 * thread is up and running, thus not being blocked by other
375202933Sattilio	 * conditions.
376202933Sattilio	 */
377202933Sattilio	PROC_LOCK(p);
378173004Sjulian	thread_lock(td);
379173004Sjulian	td->td_flags |= TDF_KTH_SUSP;
380173004Sjulian	thread_unlock(td);
381202933Sattilio	return (msleep(&td->td_flags, &p->p_mtx, PPAUSE | PDROP, "suspkt",
382202933Sattilio	    timo));
383173004Sjulian}
384173004Sjulian
385173004Sjulian/*
386202933Sattilio * Resume a thread previously put asleep with kthread_suspend().
387173004Sjulian */
388173004Sjulianint
389173004Sjuliankthread_resume(struct thread *td)
390173004Sjulian{
391202933Sattilio	struct proc *p;
392202933Sattilio
393202933Sattilio	p = td->td_proc;
394202933Sattilio
395202933Sattilio	/*
396204088Sattilio	 * td_pflags should not be read by any thread other than
397202933Sattilio	 * curthread, but as long as this flag is invariant during the
398204088Sattilio	 * thread's lifetime, it is OK to check its state.
399202933Sattilio	 */
400202933Sattilio	if ((td->td_pflags & TDP_KTHREAD) == 0)
401173004Sjulian		return (EINVAL);
402202933Sattilio
403202933Sattilio	PROC_LOCK(p);
404173004Sjulian	thread_lock(td);
405173004Sjulian	td->td_flags &= ~TDF_KTH_SUSP;
406173004Sjulian	thread_unlock(td);
407202933Sattilio	wakeup(&td->td_flags);
408202933Sattilio	PROC_UNLOCK(p);
409173004Sjulian	return (0);
410173004Sjulian}
411173004Sjulian
412173004Sjulian/*
413173004Sjulian * Used by the thread to poll as to whether it should yield/sleep
414173004Sjulian * and notify the caller that is has happened.
415173004Sjulian */
416173004Sjulianvoid
417202933Sattiliokthread_suspend_check()
418173004Sjulian{
419202933Sattilio	struct proc *p;
420202933Sattilio	struct thread *td;
421202933Sattilio
422202933Sattilio	td = curthread;
423202933Sattilio	p = td->td_proc;
424202933Sattilio
425202933Sattilio	if ((td->td_pflags & TDP_KTHREAD) == 0)
426202933Sattilio		panic("%s: curthread is not a valid kthread", __func__);
427202933Sattilio
428202933Sattilio	/*
429202933Sattilio	 * As long as the double-lock protection is used when accessing the
430202933Sattilio	 * TDF_KTH_SUSP flag, synchronizing the read operation via proc mutex
431202933Sattilio	 * is fine.
432202933Sattilio	 */
433202933Sattilio	PROC_LOCK(p);
434173004Sjulian	while (td->td_flags & TDF_KTH_SUSP) {
435173004Sjulian		wakeup(&td->td_flags);
436202933Sattilio		msleep(&td->td_flags, &p->p_mtx, PPAUSE, "ktsusp", 0);
437173004Sjulian	}
438202933Sattilio	PROC_UNLOCK(p);
439173004Sjulian}
440173004Sjulian
441173004Sjulianint
442173004Sjuliankproc_kthread_add(void (*func)(void *), void *arg,
443173004Sjulian            struct proc **procptr, struct thread **tdptr,
444208390Sjhb            int flags, int pages, const char *procname, const char *fmt, ...)
445173004Sjulian{
446173004Sjulian	int error;
447173004Sjulian	va_list ap;
448173004Sjulian	char buf[100];
449173004Sjulian	struct thread *td;
450173004Sjulian
451173004Sjulian	if (*procptr == 0) {
452173004Sjulian		error = kproc_create(func, arg,
453173004Sjulian		    	procptr, flags, pages, "%s", procname);
454173004Sjulian		if (error)
455173004Sjulian			return (error);
456173004Sjulian		td = FIRST_THREAD_IN_PROC(*procptr);
457178682Sjulian		if (tdptr)
458178682Sjulian			*tdptr = td;
459173004Sjulian		va_start(ap, fmt);
460173004Sjulian		vsnprintf(td->td_name, sizeof(td->td_name), fmt, ap);
461173004Sjulian		va_end(ap);
462232700Sjhb#ifdef KTR
463232700Sjhb		sched_clear_tdname(td);
464232700Sjhb#endif
465173004Sjulian		return (0);
466173004Sjulian	}
467173004Sjulian	va_start(ap, fmt);
468173004Sjulian	vsnprintf(buf, sizeof(buf), fmt, ap);
469173004Sjulian	va_end(ap);
470173004Sjulian	error = kthread_add(func, arg, *procptr,
471173004Sjulian		    tdptr, flags, pages, "%s", buf);
472173004Sjulian	return (error);
473173004Sjulian}
474