xref: /netbsd-src/sys/kern/kern_lwp.c (revision 001c68bd94f75ce9270b69227c4199fbf34ee396)
1 /*	$NetBSD: kern_lwp.c,v 1.8 2003/06/23 11:02:05 martin Exp $	*/
2 
3 /*-
4  * Copyright (c) 2001 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Nathan J. Williams.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 #include "opt_multiprocessor.h"
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/pool.h>
44 #include <sys/lock.h>
45 #include <sys/proc.h>
46 #include <sys/sa.h>
47 #include <sys/savar.h>
48 #include <sys/types.h>
49 #include <sys/ucontext.h>
50 #include <sys/resourcevar.h>
51 #include <sys/mount.h>
52 #include <sys/syscallargs.h>
53 
54 #include <uvm/uvm_extern.h>
55 
56 struct lwplist alllwp;
57 struct lwplist deadlwp;
58 struct lwplist zomblwp;
59 
60 #define LWP_DEBUG
61 
62 #ifdef LWP_DEBUG
63 int lwp_debug = 0;
64 #define DPRINTF(x) if (lwp_debug) printf x
65 #else
66 #define DPRINTF(x)
67 #endif
68 /* ARGSUSED */
69 int
70 sys__lwp_create(struct lwp *l, void *v, register_t *retval)
71 {
72 	struct sys__lwp_create_args /* {
73 		syscallarg(const ucontext_t *) ucp;
74 		syscallarg(u_long) flags;
75 		syscallarg(lwpid_t *) new_lwp;
76 	} */ *uap = v;
77 	struct proc *p = l->l_proc;
78 	struct lwp *l2;
79 	vaddr_t uaddr;
80 	boolean_t inmem;
81 	ucontext_t *newuc;
82 	int s, error;
83 
84 	newuc = pool_get(&lwp_uc_pool, PR_WAITOK);
85 
86 	error = copyin(SCARG(uap, ucp), newuc, sizeof(*newuc));
87 	if (error)
88 		return (error);
89 
90 	/* XXX check against resource limits */
91 
92 	inmem = uvm_uarea_alloc(&uaddr);
93 	if (__predict_false(uaddr == 0)) {
94 		return (ENOMEM);
95 	}
96 
97 	/* XXX flags:
98 	 * __LWP_ASLWP is probably needed for Solaris compat.
99 	 */
100 
101 	newlwp(l, p, uaddr, inmem,
102 	    SCARG(uap, flags) & LWP_DETACHED,
103 	    NULL, 0, startlwp, newuc, &l2);
104 
105 	if ((SCARG(uap, flags) & LWP_SUSPENDED) == 0) {
106 		SCHED_LOCK(s);
107 		l2->l_stat = LSRUN;
108 		setrunqueue(l2);
109 		SCHED_UNLOCK(s);
110 		simple_lock(&p->p_lwplock);
111 		p->p_nrlwps++;
112 		simple_unlock(&p->p_lwplock);
113 	} else {
114 		l2->l_stat = LSSUSPENDED;
115 	}
116 
117 	error = copyout(&l2->l_lid, SCARG(uap, new_lwp),
118 	    sizeof(l2->l_lid));
119 	if (error)
120 		return (error);
121 
122 	return (0);
123 }
124 
125 
126 int
127 sys__lwp_exit(struct lwp *l, void *v, register_t *retval)
128 {
129 
130 	lwp_exit(l);
131 	/* NOTREACHED */
132 	return (0);
133 }
134 
135 
136 int
137 sys__lwp_self(struct lwp *l, void *v, register_t *retval)
138 {
139 
140 	*retval = l->l_lid;
141 
142 	return (0);
143 }
144 
145 
146 int
147 sys__lwp_getprivate(struct lwp *l, void *v, register_t *retval)
148 {
149 
150 	*retval = (uintptr_t) l->l_private;
151 
152 	return (0);
153 }
154 
155 
156 int
157 sys__lwp_setprivate(struct lwp *l, void *v, register_t *retval)
158 {
159 	struct sys__lwp_setprivate_args /* {
160 		syscallarg(void *) ptr;
161 	} */ *uap = v;
162 
163 	l->l_private = SCARG(uap, ptr);
164 
165 	return (0);
166 }
167 
168 
169 int
170 sys__lwp_suspend(struct lwp *l, void *v, register_t *retval)
171 {
172 	struct sys__lwp_suspend_args /* {
173 		syscallarg(lwpid_t) target;
174 	} */ *uap = v;
175 	int target_lid;
176 	struct proc *p = l->l_proc;
177 	struct lwp *t, *t2;
178 	int s;
179 
180 	target_lid = SCARG(uap, target);
181 
182 	LIST_FOREACH(t, &p->p_lwps, l_sibling)
183 		if (t->l_lid == target_lid)
184 			break;
185 
186 	if (t == NULL)
187 		return (ESRCH);
188 
189 	if (t == l) {
190 		/*
191 		 * Check for deadlock, which is only possible
192 		 * when we're suspending ourself.
193 		 */
194 		LIST_FOREACH(t2, &p->p_lwps, l_sibling) {
195 			if ((t2 != l) && (t2->l_stat != LSSUSPENDED))
196 				break;
197 		}
198 
199 		if (t2 == NULL) /* All other LWPs are suspended */
200 			return (EDEADLK);
201 
202 		SCHED_LOCK(s);
203 		l->l_stat = LSSUSPENDED;
204 		/* XXX NJWLWP check if this makes sense here: */
205 		l->l_proc->p_stats->p_ru.ru_nvcsw++;
206 		mi_switch(l, NULL);
207 		SCHED_ASSERT_UNLOCKED();
208 		splx(s);
209 	} else {
210 		switch (t->l_stat) {
211 		case LSSUSPENDED:
212 			return (0); /* _lwp_suspend() is idempotent */
213 		case LSRUN:
214 			SCHED_LOCK(s);
215 			remrunqueue(t);
216 			t->l_stat = LSSUSPENDED;
217 			SCHED_UNLOCK(s);
218 			simple_lock(&p->p_lwplock);
219 			p->p_nrlwps--;
220 			simple_unlock(&p->p_lwplock);
221 			break;
222 		case LSSLEEP:
223 			t->l_stat = LSSUSPENDED;
224 			break;
225 		case LSIDL:
226 		case LSDEAD:
227 		case LSZOMB:
228 			return (EINTR); /* It's what Solaris does..... */
229 		case LSSTOP:
230 			panic("_lwp_suspend: Stopped LWP in running process!");
231 			break;
232 		case LSONPROC:
233 			panic("XXX multiprocessor LWPs? Implement me!");
234 			break;
235 		}
236 	}
237 
238 	return (0);
239 }
240 
241 
242 int
243 sys__lwp_continue(struct lwp *l, void *v, register_t *retval)
244 {
245 	struct sys__lwp_continue_args /* {
246 		syscallarg(lwpid_t) target;
247 	} */ *uap = v;
248 	int target_lid;
249 	struct proc *p = l->l_proc;
250 	struct lwp *t;
251 
252 	target_lid = SCARG(uap, target);
253 
254 	LIST_FOREACH(t, &p->p_lwps, l_sibling)
255 		if (t->l_lid == target_lid)
256 			break;
257 
258 	if (t == NULL)
259 		return (ESRCH);
260 
261 	lwp_continue(t);
262 
263 	return (0);
264 }
265 
266 void
267 lwp_continue(struct lwp *l)
268 {
269 	int s;
270 
271 	DPRINTF(("lwp_continue of %d.%d (%s), state %d, wchan %p\n",
272 	    l->l_proc->p_pid, l->l_lid, l->l_proc->p_comm, l->l_stat,
273 	    l->l_wchan));
274 
275 	if (l->l_stat != LSSUSPENDED)
276 		return;
277 
278 	if (l->l_wchan == 0) {
279 		/* LWP was runnable before being suspended. */
280 		SCHED_LOCK(s);
281 		setrunnable(l);
282 		SCHED_UNLOCK(s);
283 	} else {
284 		/* LWP was sleeping before being suspended. */
285 		l->l_stat = LSSLEEP;
286 	}
287 }
288 
289 int
290 sys__lwp_wakeup(struct lwp *l, void *v, register_t *retval)
291 {
292 	struct sys__lwp_wakeup_args /* {
293 		syscallarg(lwpid_t) wakeup;
294 	} */ *uap = v;
295 	lwpid_t target_lid;
296 	struct lwp *t;
297 	struct proc *p;
298 
299 	p = l->l_proc;
300 	target_lid = SCARG(uap, target);
301 
302 	LIST_FOREACH(t, &p->p_lwps, l_sibling)
303 		if (t->l_lid == target_lid)
304 			break;
305 
306 	if (t == NULL)
307 		return (ESRCH);
308 
309 	if (t->l_stat != LSSLEEP)
310 		return (ENODEV);
311 
312 	if ((t->l_flag & L_SINTR) == 0)
313 		return (EBUSY);
314 
315 	setrunnable(t);
316 
317 	return 0;
318 }
319 
320 int
321 sys__lwp_wait(struct lwp *l, void *v, register_t *retval)
322 {
323 	struct sys__lwp_wait_args /* {
324 		syscallarg(lwpid_t) wait_for;
325 		syscallarg(lwpid_t *) departed;
326 	} */ *uap = v;
327 	int error;
328 	lwpid_t dep;
329 
330 	error = lwp_wait1(l, SCARG(uap, wait_for), &dep, 0);
331 	if (error)
332 		return (error);
333 
334 	if (SCARG(uap, departed)) {
335 		error = copyout(&dep, SCARG(uap, departed),
336 		    sizeof(dep));
337 		if (error)
338 			return (error);
339 	}
340 
341 	return (0);
342 }
343 
344 
345 int
346 lwp_wait1(struct lwp *l, lwpid_t lid, lwpid_t *departed, int flags)
347 {
348 
349 	struct proc *p = l->l_proc;
350 	struct lwp *l2, *l3;
351 	int nfound, error, s, wpri;
352 	static char waitstr1[] = "lwpwait";
353 	static char waitstr2[] = "lwpwait2";
354 
355 	DPRINTF(("lwp_wait1: %d.%d waiting for %d.\n",
356 	    p->p_pid, l->l_lid, lid));
357 
358 	if (lid == l->l_lid)
359 		return (EDEADLK); /* Waiting for ourselves makes no sense. */
360 
361 	wpri = PWAIT |
362 	    ((flags & LWPWAIT_EXITCONTROL) ? PNOEXITERR : PCATCH);
363  loop:
364 	nfound = 0;
365 	LIST_FOREACH(l2, &p->p_lwps, l_sibling) {
366 		if ((l2 == l) || (l2->l_flag & L_DETACHED) ||
367 		    ((lid != 0) && (lid != l2->l_lid)))
368 			continue;
369 
370 		nfound++;
371 		if (l2->l_stat == LSZOMB) {
372 			if (departed)
373 				*departed = l2->l_lid;
374 
375 			s = proclist_lock_write();
376 			LIST_REMOVE(l2, l_zlist); /* off zomblwp */
377 			proclist_unlock_write(s);
378 
379 			simple_lock(&p->p_lwplock);
380 			LIST_REMOVE(l2, l_sibling);
381 			p->p_nlwps--;
382 			p->p_nzlwps--;
383 			simple_unlock(&p->p_lwplock);
384 			/* XXX decrement limits */
385 
386 			pool_put(&lwp_pool, l2);
387 
388 			return (0);
389 		} else if (l2->l_stat == LSSLEEP ||
390 		           l2->l_stat == LSSUSPENDED) {
391 			/* Deadlock checks.
392 			 * 1. If all other LWPs are waiting for exits
393 			 *    or suspended, we would deadlock.
394 			 */
395 
396 			LIST_FOREACH(l3, &p->p_lwps, l_sibling) {
397 				if (l3 != l && (l3->l_stat != LSSUSPENDED) &&
398 				    !(l3->l_stat == LSSLEEP &&
399 					l3->l_wchan == (caddr_t) &p->p_nlwps))
400 					break;
401 			}
402 			if (l3 == NULL) /* Everyone else is waiting. */
403 				return (EDEADLK);
404 
405 			/* XXX we'd like to check for a cycle of waiting
406 			 * LWPs (specific LID waits, not any-LWP waits)
407 			 * and detect that sort of deadlock, but we don't
408 			 * have a good place to store the lwp that is
409 			 * being waited for. wchan is already filled with
410 			 * &p->p_nlwps, and putting the lwp address in
411 			 * there for deadlock tracing would require
412 			 * exiting LWPs to call wakeup on both their
413 			 * own address and &p->p_nlwps, to get threads
414 			 * sleeping on any LWP exiting.
415 			 *
416 			 * Revisit later. Maybe another auxillary
417 			 * storage location associated with sleeping
418 			 * is in order.
419 			 */
420 		}
421 	}
422 
423 	if (nfound == 0)
424 		return (ESRCH);
425 
426 	if ((error = tsleep((caddr_t) &p->p_nlwps, wpri,
427 	    (lid != 0) ? waitstr1 : waitstr2, 0)) != 0)
428 		return (error);
429 
430 	goto loop;
431 }
432 
433 
434 int
435 newlwp(struct lwp *l1, struct proc *p2, vaddr_t uaddr, boolean_t inmem,
436     int flags, void *stack, size_t stacksize,
437     void (*func)(void *), void *arg, struct lwp **rnewlwpp)
438 {
439 	struct lwp *l2;
440 	int s;
441 
442 	l2 = pool_get(&lwp_pool, PR_WAITOK);
443 
444 	l2->l_stat = LSIDL;
445 	l2->l_forw = l2->l_back = NULL;
446 	l2->l_proc = p2;
447 
448 
449 	memset(&l2->l_startzero, 0,
450 	       (unsigned) ((caddr_t)&l2->l_endzero -
451 			   (caddr_t)&l2->l_startzero));
452 	memcpy(&l2->l_startcopy, &l1->l_startcopy,
453 	       (unsigned) ((caddr_t)&l2->l_endcopy -
454 			   (caddr_t)&l2->l_startcopy));
455 
456 #if !defined(MULTIPROCESSOR)
457 	/*
458 	 * In the single-processor case, all processes will always run
459 	 * on the same CPU.  So, initialize the child's CPU to the parent's
460 	 * now.  In the multiprocessor case, the child's CPU will be
461 	 * initialized in the low-level context switch code when the
462 	 * process runs.
463 	 */
464 	KASSERT(l1->l_cpu != NULL);
465 	l2->l_cpu = l1->l_cpu;
466 #else
467 	/*
468 	 * zero child's cpu pointer so we don't get trash.
469 	 */
470 	l2->l_cpu = NULL;
471 #endif /* ! MULTIPROCESSOR */
472 
473 	l2->l_flag = inmem ? L_INMEM : 0;
474 	l2->l_flag |= (flags & LWP_DETACHED) ? L_DETACHED : 0;
475 
476 	callout_init(&l2->l_tsleep_ch);
477 
478 	if (rnewlwpp != NULL)
479 		*rnewlwpp = l2;
480 
481 	l2->l_addr = (struct user *)uaddr;
482 	uvm_lwp_fork(l1, l2, stack, stacksize, func,
483 	    (arg != NULL) ? arg : l2);
484 
485 
486 	simple_lock(&p2->p_lwplock);
487 	l2->l_lid = ++p2->p_nlwpid;
488 	LIST_INSERT_HEAD(&p2->p_lwps, l2, l_sibling);
489 	p2->p_nlwps++;
490 	simple_unlock(&p2->p_lwplock);
491 
492 	/* XXX should be locked differently... */
493 	s = proclist_lock_write();
494 	LIST_INSERT_HEAD(&alllwp, l2, l_list);
495 	proclist_unlock_write(s);
496 
497 	return (0);
498 }
499 
500 
501 /*
502  * Quit the process. This will call cpu_exit, which will call cpu_switch,
503  * so this can only be used meaningfully if you're willing to switch away.
504  * Calling with l!=curlwp would be weird.
505  */
506 void
507 lwp_exit(struct lwp *l)
508 {
509 	struct proc *p = l->l_proc;
510 	int s;
511 
512 	DPRINTF(("lwp_exit: %d.%d exiting.\n", p->p_pid, l->l_lid));
513 	DPRINTF((" nlwps: %d nrlwps %d nzlwps: %d\n",
514 	    p->p_nlwps, p->p_nrlwps, p->p_nzlwps));
515 
516 	/*
517 	 * If we are the last live LWP in a process, we need to exit
518 	 * the entire process (if that's not already going on). We do
519 	 * so with an exit status of zero, because it's a "controlled"
520 	 * exit, and because that's what Solaris does.
521 	 */
522 	if (((p->p_nlwps - p->p_nzlwps) == 1) && ((p->p_flag & P_WEXIT) == 0)) {
523 		DPRINTF(("lwp_exit: %d.%d calling exit1()\n",
524 		    p->p_pid, l->l_lid));
525 		exit1(l, 0);
526 	}
527 
528 	s = proclist_lock_write();
529 	LIST_REMOVE(l, l_list);
530 	if ((l->l_flag & L_DETACHED) == 0) {
531 		DPRINTF(("lwp_exit: %d.%d going on zombie list\n", p->p_pid,
532 		    l->l_lid));
533 		LIST_INSERT_HEAD(&zomblwp, l, l_zlist);
534 	}
535 	proclist_unlock_write(s);
536 
537 	simple_lock(&p->p_lwplock);
538 	p->p_nrlwps--;
539 	simple_unlock(&p->p_lwplock);
540 
541 	l->l_stat = LSDEAD;
542 
543 	/* This LWP no longer needs to hold the kernel lock. */
544 	KERNEL_PROC_UNLOCK(l);
545 
546 	/* cpu_exit() will not return */
547 	cpu_exit(l, 0);
548 
549 }
550 
551 
552 void
553 lwp_exit2(struct lwp *l)
554 {
555 
556 	simple_lock(&deadproc_slock);
557 	LIST_INSERT_HEAD(&deadlwp, l, l_list);
558 	simple_unlock(&deadproc_slock);
559 
560 	wakeup(&deadprocs);
561 }
562 
563 /*
564  * Pick a LWP to represent the process for those operations which
565  * want information about a "process" that is actually associated
566  * with a LWP.
567  */
568 struct lwp *
569 proc_representative_lwp(p)
570 	struct proc *p;
571 {
572 	struct lwp *l, *onproc, *running, *sleeping, *stopped, *suspended;
573 
574 	/* Trivial case: only one LWP */
575 	if (p->p_nlwps == 1)
576 		return (LIST_FIRST(&p->p_lwps));
577 
578 	switch (p->p_stat) {
579 	case SSTOP:
580 	case SACTIVE:
581 		/* Pick the most live LWP */
582 		onproc = running = sleeping = stopped = suspended = NULL;
583 		LIST_FOREACH(l, &p->p_lwps, l_sibling) {
584 			switch (l->l_stat) {
585 			case LSONPROC:
586 				onproc = l;
587 				break;
588 			case LSRUN:
589 				running = l;
590 				break;
591 			case LSSLEEP:
592 				sleeping = l;
593 				break;
594 			case LSSTOP:
595 				stopped = l;
596 				break;
597 			case LSSUSPENDED:
598 				suspended = l;
599 				break;
600 			}
601 		}
602 		if (onproc)
603 			return onproc;
604 		if (running)
605 			return running;
606 		if (sleeping)
607 			return sleeping;
608 		if (stopped)
609 			return stopped;
610 		if (suspended)
611 			return suspended;
612 		break;
613 	case SDEAD:
614 	case SZOMB:
615 		/* Doesn't really matter... */
616 		return (LIST_FIRST(&p->p_lwps));
617 		break;
618 #ifdef DIAGNOSTIC
619 	case SIDL:
620 		/* We have more than one LWP and we're in SIDL?
621 		 * How'd that happen?
622 		 */
623 		panic("Too many LWPs (%d) in SIDL process %d (%s)",
624 		    p->p_nrlwps, p->p_pid, p->p_comm);
625 	default:
626 		panic("Process %d (%s) in unknown state %d",
627 		    p->p_pid, p->p_comm, p->p_stat);
628 #endif
629 	}
630 
631 	panic("proc_representative_lwp: couldn't find a lwp for process"
632 		" %d (%s)", p->p_pid, p->p_comm);
633 	/* NOTREACHED */
634 	return NULL;
635 }
636