kern_kthread.c revision 204089
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 204089 2010-02-19 15:10:05Z attilio $");
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>
3755539Sluoqi#include <sys/signalvar.h>
3874927Sjhb#include <sys/sx.h>
3948391Speter#include <sys/unistd.h>
4048391Speter#include <sys/wait.h>
41166188Sjeff#include <sys/sched.h>
42173004Sjulian#include <vm/vm.h>
43173004Sjulian#include <vm/vm_extern.h>
4448391Speter
4548391Speter#include <machine/stdarg.h>
4648391Speter
4748391Speter/*
4848391Speter * Start a kernel process.  This is called after a fork() call in
4948391Speter * mi_startup() in the file kern/init_main.c.
5048391Speter *
5148391Speter * This function is used to start "internal" daemons and intended
5248391Speter * to be called from SYSINIT().
5348391Speter */
5448391Spetervoid
5548391Speterkproc_start(udata)
5648391Speter	const void *udata;
5748391Speter{
5848391Speter	const struct kproc_desc	*kp = udata;
5948391Speter	int error;
6048391Speter
61172836Sjulian	error = kproc_create((void (*)(void *))kp->func, NULL,
62104354Sscottl		    kp->global_procpp, 0, 0, "%s", kp->arg0);
6348391Speter	if (error)
6448391Speter		panic("kproc_start: %s: error %d", kp->arg0, error);
6548391Speter}
6648391Speter
6748391Speter/*
6865557Sjasone * Create a kernel process/thread/whatever.  It shares its address space
6948391Speter * with proc0 - ie: kernel only.
7065557Sjasone *
7165557Sjasone * func is the function to start.
7265557Sjasone * arg is the parameter to pass to function on first startup.
7365557Sjasone * newpp is the return value pointing to the thread's struct proc.
7465557Sjasone * flags are flags to fork1 (in unistd.h)
7565557Sjasone * fmt and following will be *printf'd into (*newpp)->p_comm (for ps, etc.).
7648391Speter */
7748391Speterint
78172836Sjuliankproc_create(void (*func)(void *), void *arg,
79104354Sscottl    struct proc **newpp, int flags, int pages, const char *fmt, ...)
8048391Speter{
8148391Speter	int error;
8248391Speter	va_list ap;
83103216Sjulian	struct thread *td;
8448391Speter	struct proc *p2;
8548391Speter
86114434Sdes	if (!proc0.p_stats)
87172836Sjulian		panic("kproc_create called too soon");
8865557Sjasone
8990375Speter	error = fork1(&thread0, RFMEM | RFFDG | RFPROC | RFSTOPPED | flags,
90104354Sscottl	    pages, &p2);
9148391Speter	if (error)
9248391Speter		return error;
9348391Speter
9448391Speter	/* save a global descriptor, if desired */
9548391Speter	if (newpp != NULL)
9648391Speter		*newpp = p2;
9748391Speter
9848391Speter	/* this is a non-swapped system process */
9971559Sjhb	PROC_LOCK(p2);
100173004Sjulian	td = FIRST_THREAD_IN_PROC(p2);
10171559Sjhb	p2->p_flag |= P_SYSTEM | P_KTHREAD;
102173004Sjulian	td->td_pflags |= TDP_KTHREAD;
103114983Sjhb	mtx_lock(&p2->p_sigacts->ps_mtx);
104114983Sjhb	p2->p_sigacts->ps_flag |= PS_NOCLDWAIT;
105114983Sjhb	mtx_unlock(&p2->p_sigacts->ps_mtx);
10671559Sjhb	PROC_UNLOCK(p2);
10748391Speter
10848391Speter	/* set up arg0 for 'ps', et al */
10948391Speter	va_start(ap, fmt);
11048391Speter	vsnprintf(p2->p_comm, sizeof(p2->p_comm), fmt, ap);
11148391Speter	va_end(ap);
112173004Sjulian	/* set up arg0 for 'ps', et al */
113173004Sjulian	va_start(ap, fmt);
114173004Sjulian	vsnprintf(td->td_name, sizeof(td->td_name), fmt, ap);
115173004Sjulian	va_end(ap);
11648391Speter
11748391Speter	/* call the processes' main()... */
118103216Sjulian	cpu_set_fork_handler(td, func, arg);
119103216Sjulian	TD_SET_CAN_RUN(td);
12048391Speter
12169657Sjhb	/* Delay putting it on the run queue until now. */
12269657Sjhb	if (!(flags & RFSTOPPED)) {
123170307Sjeff		thread_lock(td);
124166188Sjeff		sched_add(td, SRQ_BORING);
125170307Sjeff		thread_unlock(td);
12669657Sjhb	}
12769657Sjhb
12848391Speter	return 0;
12948391Speter}
13048391Speter
13148391Spetervoid
132172836Sjuliankproc_exit(int ecode)
13348391Speter{
13486293Speter	struct thread *td;
13586293Speter	struct proc *p;
13670317Sjake
13786293Speter	td = curthread;
13886293Speter	p = td->td_proc;
139155400Sjhb
140155400Sjhb	/*
141155400Sjhb	 * Reparent curthread from proc0 to init so that the zombie
142155400Sjhb	 * is harvested.
143155400Sjhb	 */
14474927Sjhb	sx_xlock(&proctree_lock);
14586292Sdillon	PROC_LOCK(p);
14686292Sdillon	proc_reparent(p, initproc);
14786292Sdillon	PROC_UNLOCK(p);
14874927Sjhb	sx_xunlock(&proctree_lock);
149155400Sjhb
150155400Sjhb	/*
151155400Sjhb	 * Wakeup anyone waiting for us to exit.
152155400Sjhb	 */
153155400Sjhb	wakeup(p);
154155400Sjhb
155155400Sjhb	/* Buh-bye! */
15686293Speter	exit1(td, W_EXITCODE(ecode, 0));
15748391Speter}
15848391Speter
15955539Sluoqi/*
16055539Sluoqi * Advise a kernel process to suspend (or resume) in its main loop.
16155539Sluoqi * Participation is voluntary.
16255539Sluoqi */
16355539Sluoqiint
164172836Sjuliankproc_suspend(struct proc *p, int timo)
16555539Sluoqi{
16655539Sluoqi	/*
16755539Sluoqi	 * Make sure this is indeed a system process and we can safely
168104306Sjmallett	 * use the p_siglist field.
16955539Sluoqi	 */
17073911Sjhb	PROC_LOCK(p);
17173911Sjhb	if ((p->p_flag & P_KTHREAD) == 0) {
17273911Sjhb		PROC_UNLOCK(p);
17355539Sluoqi		return (EINVAL);
17473911Sjhb	}
175104306Sjmallett	SIGADDSET(p->p_siglist, SIGSTOP);
17688160Speter	wakeup(p);
177173004Sjulian	return msleep(&p->p_siglist, &p->p_mtx, PPAUSE | PDROP, "suspkp", timo);
17855539Sluoqi}
17955539Sluoqi
18055539Sluoqiint
181172836Sjuliankproc_resume(struct proc *p)
18255539Sluoqi{
18355539Sluoqi	/*
18455539Sluoqi	 * Make sure this is indeed a system process and we can safely
18555539Sluoqi	 * use the p_siglist field.
18655539Sluoqi	 */
18773911Sjhb	PROC_LOCK(p);
18873911Sjhb	if ((p->p_flag & P_KTHREAD) == 0) {
18973911Sjhb		PROC_UNLOCK(p);
19055539Sluoqi		return (EINVAL);
19173911Sjhb	}
192104306Sjmallett	SIGDELSET(p->p_siglist, SIGSTOP);
19373911Sjhb	PROC_UNLOCK(p);
194104306Sjmallett	wakeup(&p->p_siglist);
19555539Sluoqi	return (0);
19655539Sluoqi}
19755539Sluoqi
19855539Sluoqivoid
199172836Sjuliankproc_suspend_check(struct proc *p)
20055539Sluoqi{
20173911Sjhb	PROC_LOCK(p);
202104306Sjmallett	while (SIGISMEMBER(p->p_siglist, SIGSTOP)) {
203104306Sjmallett		wakeup(&p->p_siglist);
204173004Sjulian		msleep(&p->p_siglist, &p->p_mtx, PPAUSE, "kpsusp", 0);
20555539Sluoqi	}
20673911Sjhb	PROC_UNLOCK(p);
20755539Sluoqi}
208173004Sjulian
209173004Sjulian
210173004Sjulian/*
211173004Sjulian * Start a kernel thread.
212173004Sjulian *
213173004Sjulian * This function is used to start "internal" daemons and intended
214173004Sjulian * to be called from SYSINIT().
215173004Sjulian */
216173004Sjulian
217173004Sjulianvoid
218173004Sjuliankthread_start(udata)
219173004Sjulian	const void *udata;
220173004Sjulian{
221173004Sjulian	const struct kthread_desc	*kp = udata;
222173004Sjulian	int error;
223173004Sjulian
224173004Sjulian	error = kthread_add((void (*)(void *))kp->func, NULL,
225173004Sjulian		    NULL, kp->global_threadpp, 0, 0, "%s", kp->arg0);
226173004Sjulian	if (error)
227173004Sjulian		panic("kthread_start: %s: error %d", kp->arg0, error);
228173004Sjulian}
229173004Sjulian
230173004Sjulian/*
231173004Sjulian * Create a kernel thread.  It shares its address space
232173004Sjulian * with proc0 - ie: kernel only.
233173004Sjulian *
234173004Sjulian * func is the function to start.
235173004Sjulian * arg is the parameter to pass to function on first startup.
236173004Sjulian * newtdp is the return value pointing to the thread's struct thread.
237173004Sjulian *  ** XXX fix this --> flags are flags to fork1 (in unistd.h)
238173004Sjulian * fmt and following will be *printf'd into (*newtd)->td_name (for ps, etc.).
239173004Sjulian */
240173004Sjulianint
241173004Sjuliankthread_add(void (*func)(void *), void *arg, struct proc *p,
242173004Sjulian    struct thread **newtdp, int flags, int pages, const char *fmt, ...)
243173004Sjulian{
244173004Sjulian	va_list ap;
245173004Sjulian	struct thread *newtd, *oldtd;
246173004Sjulian
247173004Sjulian	if (!proc0.p_stats)
248173004Sjulian		panic("kthread_add called too soon");
249173004Sjulian
250173052Sjulian	/* If no process supplied, put it on proc0 */
251173004Sjulian	if (p == NULL) {
252173004Sjulian		p = &proc0;
253173004Sjulian		oldtd = &thread0;
254173004Sjulian	} else {
255173052Sjulian		oldtd = FIRST_THREAD_IN_PROC(p);
256173004Sjulian	}
257173004Sjulian
258173052Sjulian	/* Initialize our new td  */
259196730Skib	newtd = thread_alloc(pages);
260173004Sjulian	if (newtd == NULL)
261173004Sjulian		return (ENOMEM);
262173004Sjulian
263173004Sjulian	bzero(&newtd->td_startzero,
264173004Sjulian	    __rangeof(struct thread, td_startzero, td_endzero));
265173004Sjulian/* XXX check if we should zero. */
266173004Sjulian	bcopy(&oldtd->td_startcopy, &newtd->td_startcopy,
267173004Sjulian	    __rangeof(struct thread, td_startcopy, td_endcopy));
268173004Sjulian
269173004Sjulian	/* set up arg0 for 'ps', et al */
270173004Sjulian	va_start(ap, fmt);
271173004Sjulian	vsnprintf(newtd->td_name, sizeof(newtd->td_name), fmt, ap);
272173004Sjulian	va_end(ap);
273173004Sjulian
274173004Sjulian	newtd->td_proc = p;  /* needed for cpu_set_upcall */
275173004Sjulian
276173004Sjulian	/* XXX optimise this probably? */
277173004Sjulian	/* On x86 (and probably the others too) it is way too full of junk */
278173004Sjulian	/* Needs a better name */
279173004Sjulian	cpu_set_upcall(newtd, oldtd);
280173004Sjulian	/* put the designated function(arg) as the resume context */
281173004Sjulian	cpu_set_fork_handler(newtd, func, arg);
282173004Sjulian
283173004Sjulian	newtd->td_pflags |= TDP_KTHREAD;
284173004Sjulian	newtd->td_ucred = crhold(p->p_ucred);
285173004Sjulian
286173004Sjulian	/* this code almost the same as create_thread() in kern_thr.c */
287173004Sjulian	PROC_LOCK(p);
288173004Sjulian	p->p_flag |= P_HADTHREADS;
289173004Sjulian	newtd->td_sigmask = oldtd->td_sigmask; /* XXX dubious */
290173004Sjulian	thread_link(newtd, p);
291173004Sjulian	thread_lock(oldtd);
292173004Sjulian	/* let the scheduler know about these things. */
293173004Sjulian	sched_fork_thread(oldtd, newtd);
294173004Sjulian	TD_SET_CAN_RUN(newtd);
295173004Sjulian	thread_unlock(oldtd);
296173004Sjulian	PROC_UNLOCK(p);
297173004Sjulian
298173004Sjulian
299173004Sjulian	/* Delay putting it on the run queue until now. */
300173004Sjulian	if (!(flags & RFSTOPPED)) {
301173004Sjulian		thread_lock(newtd);
302173004Sjulian		sched_add(newtd, SRQ_BORING);
303173004Sjulian		thread_unlock(newtd);
304173004Sjulian	}
305173004Sjulian	if (newtdp)
306173004Sjulian		*newtdp = newtd;
307173004Sjulian	return 0;
308173004Sjulian}
309173004Sjulian
310173004Sjulianvoid
311173031Sjuliankthread_exit(void)
312173004Sjulian{
313173658Sjhb	struct proc *p;
314173658Sjhb
315204087Sattilio	p = curthread->td_proc;
316204087Sattilio
317173658Sjhb	/* A module may be waiting for us to exit. */
318173052Sjulian	wakeup(curthread);
319204087Sattilio	PROC_LOCK(p);
320204089Sattilio	if (p->p_numthreads == 1) {
321204087Sattilio		PROC_UNLOCK(p);
322204087Sattilio		kproc_exit(0);
323173658Sjhb
324204087Sattilio		/* NOTREACHED. */
325204087Sattilio	}
326173658Sjhb	PROC_SLOCK(p);
327173004Sjulian	thread_exit();
328173004Sjulian}
329173004Sjulian
330173004Sjulian/*
331173004Sjulian * Advise a kernel process to suspend (or resume) in its main loop.
332173004Sjulian * Participation is voluntary.
333173004Sjulian */
334173004Sjulianint
335173004Sjuliankthread_suspend(struct thread *td, int timo)
336173004Sjulian{
337202933Sattilio	struct proc *p;
338202933Sattilio
339202933Sattilio	p = td->td_proc;
340202933Sattilio
341202933Sattilio	/*
342204088Sattilio	 * td_pflags should not be read by any thread other than
343202933Sattilio	 * curthread, but as long as this flag is invariant during the
344204088Sattilio	 * thread's lifetime, it is OK to check its state.
345202933Sattilio	 */
346202933Sattilio	if ((td->td_pflags & TDP_KTHREAD) == 0)
347173004Sjulian		return (EINVAL);
348202933Sattilio
349202933Sattilio	/*
350202933Sattilio	 * The caller of the primitive should have already checked that the
351202933Sattilio	 * thread is up and running, thus not being blocked by other
352202933Sattilio	 * conditions.
353202933Sattilio	 */
354202933Sattilio	PROC_LOCK(p);
355173004Sjulian	thread_lock(td);
356173004Sjulian	td->td_flags |= TDF_KTH_SUSP;
357173004Sjulian	thread_unlock(td);
358202933Sattilio	return (msleep(&td->td_flags, &p->p_mtx, PPAUSE | PDROP, "suspkt",
359202933Sattilio	    timo));
360173004Sjulian}
361173004Sjulian
362173004Sjulian/*
363202933Sattilio * Resume a thread previously put asleep with kthread_suspend().
364173004Sjulian */
365173004Sjulianint
366173004Sjuliankthread_resume(struct thread *td)
367173004Sjulian{
368202933Sattilio	struct proc *p;
369202933Sattilio
370202933Sattilio	p = td->td_proc;
371202933Sattilio
372202933Sattilio	/*
373204088Sattilio	 * td_pflags should not be read by any thread other than
374202933Sattilio	 * curthread, but as long as this flag is invariant during the
375204088Sattilio	 * thread's lifetime, it is OK to check its state.
376202933Sattilio	 */
377202933Sattilio	if ((td->td_pflags & TDP_KTHREAD) == 0)
378173004Sjulian		return (EINVAL);
379202933Sattilio
380202933Sattilio	PROC_LOCK(p);
381173004Sjulian	thread_lock(td);
382173004Sjulian	td->td_flags &= ~TDF_KTH_SUSP;
383173004Sjulian	thread_unlock(td);
384202933Sattilio	wakeup(&td->td_flags);
385202933Sattilio	PROC_UNLOCK(p);
386173004Sjulian	return (0);
387173004Sjulian}
388173004Sjulian
389173004Sjulian/*
390173004Sjulian * Used by the thread to poll as to whether it should yield/sleep
391173004Sjulian * and notify the caller that is has happened.
392173004Sjulian */
393173004Sjulianvoid
394202933Sattiliokthread_suspend_check()
395173004Sjulian{
396202933Sattilio	struct proc *p;
397202933Sattilio	struct thread *td;
398202933Sattilio
399202933Sattilio	td = curthread;
400202933Sattilio	p = td->td_proc;
401202933Sattilio
402202933Sattilio	if ((td->td_pflags & TDP_KTHREAD) == 0)
403202933Sattilio		panic("%s: curthread is not a valid kthread", __func__);
404202933Sattilio
405202933Sattilio	/*
406202933Sattilio	 * As long as the double-lock protection is used when accessing the
407202933Sattilio	 * TDF_KTH_SUSP flag, synchronizing the read operation via proc mutex
408202933Sattilio	 * is fine.
409202933Sattilio	 */
410202933Sattilio	PROC_LOCK(p);
411173004Sjulian	while (td->td_flags & TDF_KTH_SUSP) {
412173004Sjulian		wakeup(&td->td_flags);
413202933Sattilio		msleep(&td->td_flags, &p->p_mtx, PPAUSE, "ktsusp", 0);
414173004Sjulian	}
415202933Sattilio	PROC_UNLOCK(p);
416173004Sjulian}
417173004Sjulian
418173004Sjulianint
419173004Sjuliankproc_kthread_add(void (*func)(void *), void *arg,
420173004Sjulian            struct proc **procptr, struct thread **tdptr,
421173004Sjulian            int flags, int pages, char * procname, const char *fmt, ...)
422173004Sjulian{
423173004Sjulian	int error;
424173004Sjulian	va_list ap;
425173004Sjulian	char buf[100];
426173004Sjulian	struct thread *td;
427173004Sjulian
428173004Sjulian	if (*procptr == 0) {
429173004Sjulian		error = kproc_create(func, arg,
430173004Sjulian		    	procptr, flags, pages, "%s", procname);
431173004Sjulian		if (error)
432173004Sjulian			return (error);
433173004Sjulian		td = FIRST_THREAD_IN_PROC(*procptr);
434178682Sjulian		if (tdptr)
435178682Sjulian			*tdptr = td;
436173004Sjulian		va_start(ap, fmt);
437173004Sjulian		vsnprintf(td->td_name, sizeof(td->td_name), fmt, ap);
438173004Sjulian		va_end(ap);
439173004Sjulian		return (0);
440173004Sjulian	}
441173004Sjulian	va_start(ap, fmt);
442173004Sjulian	vsnprintf(buf, sizeof(buf), fmt, ap);
443173004Sjulian	va_end(ap);
444173004Sjulian	error = kthread_add(func, arg, *procptr,
445173004Sjulian		    tdptr, flags, pages, "%s", buf);
446173004Sjulian	return (error);
447173004Sjulian}
448