1 /*-
2 * Copyright (c) 1999 Peter Wemm <peter@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD: releng/8.3/sys/kern/kern_kthread.c 218355 2011-02-05 22:57:14Z kib $");
29
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kthread.h>
33 #include <sys/lock.h>
34 #include <sys/mutex.h>
35 #include <sys/proc.h>
36 #include <sys/resourcevar.h>
37 #include <sys/signalvar.h>
38 #include <sys/sx.h>
39 #include <sys/unistd.h>
40 #include <sys/wait.h>
41 #include <sys/sched.h>
42 #include <vm/vm.h>
43 #include <vm/vm_extern.h>
44
45 #include <machine/stdarg.h>
46
47 /*
48 * Start a kernel process. This is called after a fork() call in
49 * mi_startup() in the file kern/init_main.c.
50 *
51 * This function is used to start "internal" daemons and intended
52 * to be called from SYSINIT().
53 */
54 void
55 kproc_start(udata)
56 const void *udata;
57 {
58 const struct kproc_desc *kp = udata;
59 int error;
60
61 error = kproc_create((void (*)(void *))kp->func, NULL,
62 kp->global_procpp, 0, 0, "%s", kp->arg0);
63 if (error)
64 panic("kproc_start: %s: error %d", kp->arg0, error);
65 }
66
67 /*
68 * Create a kernel process/thread/whatever. It shares its address space
69 * with proc0 - ie: kernel only.
70 *
71 * func is the function to start.
72 * arg is the parameter to pass to function on first startup.
73 * newpp is the return value pointing to the thread's struct proc.
74 * flags are flags to fork1 (in unistd.h)
75 * fmt and following will be *printf'd into (*newpp)->p_comm (for ps, etc.).
76 */
77 int
78 kproc_create(void (*func)(void *), void *arg,
79 struct proc **newpp, int flags, int pages, const char *fmt, ...)
80 {
81 int error;
82 va_list ap;
83 struct thread *td;
84 struct proc *p2;
85
86 if (!proc0.p_stats)
87 panic("kproc_create called too soon");
88
89 error = fork1(&thread0, RFMEM | RFFDG | RFPROC | RFSTOPPED | flags,
90 pages, &p2);
91 if (error)
92 return error;
93
94 /* save a global descriptor, if desired */
95 if (newpp != NULL)
96 *newpp = p2;
97
98 /* this is a non-swapped system process */
99 PROC_LOCK(p2);
100 td = FIRST_THREAD_IN_PROC(p2);
101 p2->p_flag |= P_SYSTEM | P_KTHREAD;
102 td->td_pflags |= TDP_KTHREAD;
103 mtx_lock(&p2->p_sigacts->ps_mtx);
104 p2->p_sigacts->ps_flag |= PS_NOCLDWAIT;
105 mtx_unlock(&p2->p_sigacts->ps_mtx);
106 PROC_UNLOCK(p2);
107
108 /* set up arg0 for 'ps', et al */
109 va_start(ap, fmt);
110 vsnprintf(p2->p_comm, sizeof(p2->p_comm), fmt, ap);
111 va_end(ap);
112 /* set up arg0 for 'ps', et al */
113 va_start(ap, fmt);
114 vsnprintf(td->td_name, sizeof(td->td_name), fmt, ap);
115 va_end(ap);
116
117 /* call the processes' main()... */
118 cpu_set_fork_handler(td, func, arg);
119 thread_lock(td);
120 TD_SET_CAN_RUN(td);
121 sched_prio(td, PVM);
122 sched_user_prio(td, PUSER);
123
124 /* Delay putting it on the run queue until now. */
125 if (!(flags & RFSTOPPED))
126 sched_add(td, SRQ_BORING);
127 thread_unlock(td);
128
129 return 0;
130 }
131
132 void
133 kproc_exit(int ecode)
134 {
135 struct thread *td;
136 struct proc *p;
137
138 td = curthread;
139 p = td->td_proc;
140
141 /*
142 * Reparent curthread from proc0 to init so that the zombie
143 * is harvested.
144 */
145 sx_xlock(&proctree_lock);
146 PROC_LOCK(p);
147 proc_reparent(p, initproc);
148 PROC_UNLOCK(p);
149 sx_xunlock(&proctree_lock);
150
151 /*
152 * Wakeup anyone waiting for us to exit.
153 */
154 wakeup(p);
155
156 /* Buh-bye! */
157 exit1(td, W_EXITCODE(ecode, 0));
158 }
159
160 /*
161 * Advise a kernel process to suspend (or resume) in its main loop.
162 * Participation is voluntary.
163 */
164 int
165 kproc_suspend(struct proc *p, int timo)
166 {
167 /*
168 * Make sure this is indeed a system process and we can safely
169 * use the p_siglist field.
170 */
171 PROC_LOCK(p);
172 if ((p->p_flag & P_KTHREAD) == 0) {
173 PROC_UNLOCK(p);
174 return (EINVAL);
175 }
176 SIGADDSET(p->p_siglist, SIGSTOP);
177 wakeup(p);
178 return msleep(&p->p_siglist, &p->p_mtx, PPAUSE | PDROP, "suspkp", timo);
179 }
180
181 int
182 kproc_resume(struct proc *p)
183 {
184 /*
185 * Make sure this is indeed a system process and we can safely
186 * use the p_siglist field.
187 */
188 PROC_LOCK(p);
189 if ((p->p_flag & P_KTHREAD) == 0) {
190 PROC_UNLOCK(p);
191 return (EINVAL);
192 }
193 SIGDELSET(p->p_siglist, SIGSTOP);
194 PROC_UNLOCK(p);
195 wakeup(&p->p_siglist);
196 return (0);
197 }
198
199 void
200 kproc_suspend_check(struct proc *p)
201 {
202 PROC_LOCK(p);
203 while (SIGISMEMBER(p->p_siglist, SIGSTOP)) {
204 wakeup(&p->p_siglist);
205 msleep(&p->p_siglist, &p->p_mtx, PPAUSE, "kpsusp", 0);
206 }
207 PROC_UNLOCK(p);
208 }
209
210
211 /*
212 * Start a kernel thread.
213 *
214 * This function is used to start "internal" daemons and intended
215 * to be called from SYSINIT().
216 */
217
218 void
219 kthread_start(udata)
220 const void *udata;
221 {
222 const struct kthread_desc *kp = udata;
223 int error;
224
225 error = kthread_add((void (*)(void *))kp->func, NULL,
226 NULL, kp->global_threadpp, 0, 0, "%s", kp->arg0);
227 if (error)
228 panic("kthread_start: %s: error %d", kp->arg0, error);
229 }
230
231 /*
232 * Create a kernel thread. It shares its address space
233 * with proc0 - ie: kernel only.
234 *
235 * func is the function to start.
236 * arg is the parameter to pass to function on first startup.
237 * newtdp is the return value pointing to the thread's struct thread.
238 * ** XXX fix this --> flags are flags to fork1 (in unistd.h)
239 * fmt and following will be *printf'd into (*newtd)->td_name (for ps, etc.).
240 */
241 int
242 kthread_add(void (*func)(void *), void *arg, struct proc *p,
243 struct thread **newtdp, int flags, int pages, const char *fmt, ...)
244 {
245 va_list ap;
246 struct thread *newtd, *oldtd;
247
248 if (!proc0.p_stats)
249 panic("kthread_add called too soon");
250
251 /* If no process supplied, put it on proc0 */
252 if (p == NULL) {
253 p = &proc0;
254 oldtd = &thread0;
255 } else {
256 oldtd = FIRST_THREAD_IN_PROC(p);
257 }
258
259 /* Initialize our new td */
260 newtd = thread_alloc(pages);
261 if (newtd == NULL)
262 return (ENOMEM);
263
264 bzero(&newtd->td_startzero,
265 __rangeof(struct thread, td_startzero, td_endzero));
266 bzero(&newtd->td_rux, sizeof(newtd->td_rux));
267 newtd->td_map_def_user = NULL;
268 newtd->td_dbg_forked = 0;
269 /* XXX check if we should zero. */
270 bcopy(&oldtd->td_startcopy, &newtd->td_startcopy,
271 __rangeof(struct thread, td_startcopy, td_endcopy));
272
273 /* set up arg0 for 'ps', et al */
274 va_start(ap, fmt);
275 vsnprintf(newtd->td_name, sizeof(newtd->td_name), fmt, ap);
276 va_end(ap);
277
278 newtd->td_proc = p; /* needed for cpu_set_upcall */
279
280 /* XXX optimise this probably? */
281 /* On x86 (and probably the others too) it is way too full of junk */
282 /* Needs a better name */
283 cpu_set_upcall(newtd, oldtd);
284 /* put the designated function(arg) as the resume context */
285 cpu_set_fork_handler(newtd, func, arg);
286
287 newtd->td_pflags |= TDP_KTHREAD;
288 newtd->td_ucred = crhold(p->p_ucred);
289
290 /* this code almost the same as create_thread() in kern_thr.c */
291 PROC_LOCK(p);
292 p->p_flag |= P_HADTHREADS;
293 newtd->td_sigmask = oldtd->td_sigmask; /* XXX dubious */
294 thread_link(newtd, p);
295 thread_lock(oldtd);
296 /* let the scheduler know about these things. */
297 sched_fork_thread(oldtd, newtd);
298 TD_SET_CAN_RUN(newtd);
299 thread_unlock(oldtd);
300 PROC_UNLOCK(p);
301
302
303 /* Delay putting it on the run queue until now. */
304 if (!(flags & RFSTOPPED)) {
305 thread_lock(newtd);
306 sched_add(newtd, SRQ_BORING);
307 thread_unlock(newtd);
308 }
309 if (newtdp)
310 *newtdp = newtd;
311 return 0;
312 }
313
314 void
315 kthread_exit(void)
316 {
317 struct proc *p;
318
319 /* A module may be waiting for us to exit. */
320 wakeup(curthread);
321
322 /*
323 * We could rely on thread_exit to call exit1() but
324 * there is extra work that needs to be done
325 */
326 if (curthread->td_proc->p_numthreads == 1)
327 kproc_exit(0); /* never returns */
328
329 p = curthread->td_proc;
330 PROC_LOCK(p);
331 PROC_SLOCK(p);
332 thread_exit();
333 }
334
335 /*
336 * Advise a kernel process to suspend (or resume) in its main loop.
337 * Participation is voluntary.
338 */
339 int
340 kthread_suspend(struct thread *td, int timo)
341 {
342 if ((td->td_pflags & TDP_KTHREAD) == 0) {
343 return (EINVAL);
344 }
345 thread_lock(td);
346 td->td_flags |= TDF_KTH_SUSP;
347 thread_unlock(td);
348 /*
349 * If it's stopped for some other reason,
350 * kick it to notice our request
351 * or we'll end up timing out
352 */
353 wakeup(td); /* traditional place for kernel threads to sleep on */ /* XXX ?? */
354 return (tsleep(&td->td_flags, PPAUSE | PDROP, "suspkt", timo));
355 }
356
357 /*
358 * let the kthread it can keep going again.
359 */
360 int
361 kthread_resume(struct thread *td)
362 {
363 if ((td->td_pflags & TDP_KTHREAD) == 0) {
364 return (EINVAL);
365 }
366 thread_lock(td);
367 td->td_flags &= ~TDF_KTH_SUSP;
368 thread_unlock(td);
369 wakeup(&td->td_name);
370 return (0);
371 }
372
373 /*
374 * Used by the thread to poll as to whether it should yield/sleep
375 * and notify the caller that is has happened.
376 */
377 void
378 kthread_suspend_check(struct thread *td)
379 {
380 while (td->td_flags & TDF_KTH_SUSP) {
381 /*
382 * let the caller know we got the message then sleep
383 */
384 wakeup(&td->td_flags);
385 tsleep(&td->td_name, PPAUSE, "ktsusp", 0);
386 }
387 }
388
389 int
390 kproc_kthread_add(void (*func)(void *), void *arg,
391 struct proc **procptr, struct thread **tdptr,
392 int flags, int pages, const char *procname, const char *fmt, ...)
393 {
394 int error;
395 va_list ap;
396 char buf[100];
397 struct thread *td;
398
399 if (*procptr == 0) {
400 error = kproc_create(func, arg,
401 procptr, flags, pages, "%s", procname);
402 if (error)
403 return (error);
404 td = FIRST_THREAD_IN_PROC(*procptr);
405 if (tdptr)
406 *tdptr = td;
407 va_start(ap, fmt);
408 vsnprintf(td->td_name, sizeof(td->td_name), fmt, ap);
409 va_end(ap);
410 return (0);
411 }
412 va_start(ap, fmt);
413 vsnprintf(buf, sizeof(buf), fmt, ap);
414 va_end(ap);
415 error = kthread_add(func, arg, *procptr,
416 tdptr, flags, pages, "%s", buf);
417 return (error);
418 }
Cache object: f8490fbdb5beab6b8f07c9dbca243b37
|