sys_lwp.c revision 1.15 1 /* $NetBSD: sys_lwp.c,v 1.15 2007/03/14 23:58:24 ad Exp $ */
2
3 /*-
4 * Copyright (c) 2001, 2006, 2007 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, and Andrew Doran.
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 /*
40 * Lightweight process (LWP) system calls. See kern_lwp.c for a description
41 * of LWPs.
42 */
43
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: sys_lwp.c,v 1.15 2007/03/14 23:58:24 ad Exp $");
46
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/pool.h>
50 #include <sys/proc.h>
51 #include <sys/types.h>
52 #include <sys/syscallargs.h>
53 #include <sys/kauth.h>
54 #include <sys/kmem.h>
55 #include <sys/sleepq.h>
56
57 #include <uvm/uvm_extern.h>
58
59 #define LWP_UNPARK_MAX 1024
60
61 syncobj_t lwp_park_sobj = {
62 SOBJ_SLEEPQ_SORTED,
63 sleepq_unsleep,
64 sleepq_changepri,
65 sleepq_lendpri,
66 syncobj_noowner,
67 };
68
69 sleeptab_t lwp_park_tab;
70
71 void
72 lwp_sys_init(void)
73 {
74 sleeptab_init(&lwp_park_tab);
75 }
76
77 /* ARGSUSED */
78 int
79 sys__lwp_create(struct lwp *l, void *v, register_t *retval)
80 {
81 struct sys__lwp_create_args /* {
82 syscallarg(const ucontext_t *) ucp;
83 syscallarg(u_long) flags;
84 syscallarg(lwpid_t *) new_lwp;
85 } */ *uap = v;
86 struct proc *p = l->l_proc;
87 struct lwp *l2;
88 vaddr_t uaddr;
89 bool inmem;
90 ucontext_t *newuc;
91 int error, lid;
92
93 newuc = pool_get(&lwp_uc_pool, PR_WAITOK);
94
95 error = copyin(SCARG(uap, ucp), newuc, p->p_emul->e_ucsize);
96 if (error) {
97 pool_put(&lwp_uc_pool, newuc);
98 return error;
99 }
100
101 /* XXX check against resource limits */
102
103 inmem = uvm_uarea_alloc(&uaddr);
104 if (__predict_false(uaddr == 0)) {
105 pool_put(&lwp_uc_pool, newuc);
106 return ENOMEM;
107 }
108
109 newlwp(l, p, uaddr, inmem,
110 SCARG(uap, flags) & LWP_DETACHED,
111 NULL, 0, p->p_emul->e_startlwp, newuc, &l2);
112
113 /*
114 * Set the new LWP running, unless the caller has requested that
115 * it be created in suspended state. If the process is stopping,
116 * then the LWP is created stopped.
117 */
118 mutex_enter(&p->p_smutex);
119 lwp_lock(l2);
120 lid = l2->l_lid;
121 if ((SCARG(uap, flags) & LWP_SUSPENDED) == 0 &&
122 (l->l_flag & (LW_WREBOOT | LW_WSUSPEND | LW_WEXIT)) == 0) {
123 if (p->p_stat == SSTOP || (p->p_sflag & PS_STOPPING) != 0)
124 l2->l_stat = LSSTOP;
125 else {
126 KASSERT(lwp_locked(l2, &sched_mutex));
127 p->p_nrlwps++;
128 l2->l_stat = LSRUN;
129 setrunqueue(l2);
130 }
131 } else
132 l2->l_stat = LSSUSPENDED;
133 lwp_unlock(l2);
134 mutex_exit(&p->p_smutex);
135
136 error = copyout(&lid, SCARG(uap, new_lwp), sizeof(lid));
137 if (error)
138 return error;
139
140 return 0;
141 }
142
143 int
144 sys__lwp_exit(struct lwp *l, void *v, register_t *retval)
145 {
146
147 lwp_exit(l);
148 return 0;
149 }
150
151 int
152 sys__lwp_self(struct lwp *l, void *v, register_t *retval)
153 {
154
155 *retval = l->l_lid;
156 return 0;
157 }
158
159 int
160 sys__lwp_getprivate(struct lwp *l, void *v, register_t *retval)
161 {
162
163 *retval = (uintptr_t)l->l_private;
164 return 0;
165 }
166
167 int
168 sys__lwp_setprivate(struct lwp *l, void *v, register_t *retval)
169 {
170 struct sys__lwp_setprivate_args /* {
171 syscallarg(void *) ptr;
172 } */ *uap = v;
173
174 l->l_private = SCARG(uap, ptr);
175 return 0;
176 }
177
178 int
179 sys__lwp_suspend(struct lwp *l, void *v, register_t *retval)
180 {
181 struct sys__lwp_suspend_args /* {
182 syscallarg(lwpid_t) target;
183 } */ *uap = v;
184 struct proc *p = l->l_proc;
185 struct lwp *t;
186 int error;
187
188 mutex_enter(&p->p_smutex);
189 if ((t = lwp_find(p, SCARG(uap, target))) == NULL) {
190 mutex_exit(&p->p_smutex);
191 return ESRCH;
192 }
193
194 /*
195 * Check for deadlock, which is only possible when we're suspending
196 * ourself. XXX There is a short race here, as p_nrlwps is only
197 * incremented when an LWP suspends itself on the kernel/user
198 * boundary. It's still possible to kill -9 the process so we
199 * don't bother checking further.
200 */
201 lwp_lock(t);
202 if ((t == l && p->p_nrlwps == 1) ||
203 (l->l_flag & (LW_WCORE | LW_WEXIT)) != 0) {
204 lwp_unlock(t);
205 mutex_exit(&p->p_smutex);
206 return EDEADLK;
207 }
208
209 /*
210 * Suspend the LWP. XXX If it's on a different CPU, we should wait
211 * for it to be preempted, where it will put itself to sleep.
212 *
213 * Suspension of the current LWP will happen on return to userspace.
214 */
215 error = lwp_suspend(l, t);
216 mutex_exit(&p->p_smutex);
217
218 return error;
219 }
220
221 int
222 sys__lwp_continue(struct lwp *l, void *v, register_t *retval)
223 {
224 struct sys__lwp_continue_args /* {
225 syscallarg(lwpid_t) target;
226 } */ *uap = v;
227 int error;
228 struct proc *p = l->l_proc;
229 struct lwp *t;
230
231 error = 0;
232
233 mutex_enter(&p->p_smutex);
234 if ((t = lwp_find(p, SCARG(uap, target))) == NULL) {
235 mutex_exit(&p->p_smutex);
236 return ESRCH;
237 }
238
239 lwp_lock(t);
240 lwp_continue(t);
241 mutex_exit(&p->p_smutex);
242
243 return error;
244 }
245
246 int
247 sys__lwp_wakeup(struct lwp *l, void *v, register_t *retval)
248 {
249 struct sys__lwp_wakeup_args /* {
250 syscallarg(lwpid_t) target;
251 } */ *uap = v;
252 struct lwp *t;
253 struct proc *p;
254 int error;
255
256 p = l->l_proc;
257 mutex_enter(&p->p_smutex);
258
259 if ((t = lwp_find(p, SCARG(uap, target))) == NULL) {
260 mutex_exit(&p->p_smutex);
261 return ESRCH;
262 }
263
264 lwp_lock(t);
265 t->l_flag |= (LW_CANCELLED | LW_UNPARKED);
266
267 if (t->l_stat != LSSLEEP) {
268 error = ENODEV;
269 goto bad;
270 }
271
272 if ((t->l_flag & LW_SINTR) == 0) {
273 error = EBUSY;
274 goto bad;
275 }
276
277 /* Wake it up. setrunnable() will release the LWP lock. */
278 setrunnable(t);
279 mutex_exit(&p->p_smutex);
280 return 0;
281
282 bad:
283 lwp_unlock(t);
284 mutex_exit(&p->p_smutex);
285 return error;
286 }
287
288 int
289 sys__lwp_wait(struct lwp *l, void *v, register_t *retval)
290 {
291 struct sys__lwp_wait_args /* {
292 syscallarg(lwpid_t) wait_for;
293 syscallarg(lwpid_t *) departed;
294 } */ *uap = v;
295 struct proc *p = l->l_proc;
296 int error;
297 lwpid_t dep;
298
299 mutex_enter(&p->p_smutex);
300 error = lwp_wait1(l, SCARG(uap, wait_for), &dep, 0);
301 mutex_exit(&p->p_smutex);
302
303 if (error)
304 return error;
305
306 if (SCARG(uap, departed)) {
307 error = copyout(&dep, SCARG(uap, departed), sizeof(dep));
308 if (error)
309 return error;
310 }
311
312 return 0;
313 }
314
315 /* ARGSUSED */
316 int
317 sys__lwp_kill(struct lwp *l, void *v, register_t *retval)
318 {
319 struct sys__lwp_kill_args /* {
320 syscallarg(lwpid_t) target;
321 syscallarg(int) signo;
322 } */ *uap = v;
323 struct proc *p = l->l_proc;
324 struct lwp *t;
325 ksiginfo_t ksi;
326 int signo = SCARG(uap, signo);
327 int error = 0;
328
329 if ((u_int)signo >= NSIG)
330 return EINVAL;
331
332 KSI_INIT(&ksi);
333 ksi.ksi_signo = signo;
334 ksi.ksi_code = SI_USER;
335 ksi.ksi_pid = p->p_pid;
336 ksi.ksi_uid = kauth_cred_geteuid(l->l_cred);
337 ksi.ksi_lid = SCARG(uap, target);
338
339 mutex_enter(&proclist_mutex);
340 mutex_enter(&p->p_smutex);
341 if ((t = lwp_find(p, ksi.ksi_lid)) == NULL)
342 error = ESRCH;
343 else if (signo != 0)
344 kpsignal2(p, &ksi);
345 mutex_exit(&p->p_smutex);
346 mutex_exit(&proclist_mutex);
347
348 return error;
349 }
350
351 int
352 sys__lwp_detach(struct lwp *l, void *v, register_t *retval)
353 {
354 struct sys__lwp_detach_args /* {
355 syscallarg(lwpid_t) target;
356 } */ *uap = v;
357 struct proc *p;
358 struct lwp *t;
359 lwpid_t target;
360 int error;
361
362 target = SCARG(uap, target);
363 p = l->l_proc;
364
365 mutex_enter(&p->p_smutex);
366
367 if (l->l_lid == target)
368 t = l;
369 else {
370 /*
371 * We can't use lwp_find() here because the target might
372 * be a zombie.
373 */
374 LIST_FOREACH(t, &p->p_lwps, l_sibling)
375 if (t->l_lid == target)
376 break;
377 }
378
379 /*
380 * If the LWP is already detached, there's nothing to do.
381 * If it's a zombie, we need to clean up after it. LSZOMB
382 * is visible with the proc mutex held.
383 *
384 * After we have detached or released the LWP, kick any
385 * other LWPs that may be sitting in _lwp_wait(), waiting
386 * for the target LWP to exit.
387 */
388 if (t != NULL && t->l_stat != LSIDL) {
389 if ((t->l_prflag & LPR_DETACHED) == 0) {
390 p->p_ndlwps++;
391 t->l_prflag |= LPR_DETACHED;
392 if (t->l_stat == LSZOMB) {
393 cv_broadcast(&p->p_lwpcv);
394 lwp_free(t, 0, 0); /* releases proc mutex */
395 return 0;
396 }
397 error = 0;
398 } else
399 error = EINVAL;
400 } else
401 error = ESRCH;
402
403 cv_broadcast(&p->p_lwpcv);
404 mutex_exit(&p->p_smutex);
405
406 return error;
407 }
408
409 static inline wchan_t
410 lwp_park_wchan(struct proc *p, const void *hint)
411 {
412 return (wchan_t)((uintptr_t)p ^ (uintptr_t)hint);
413 }
414
415 /*
416 * 'park' an LWP waiting on a user-level synchronisation object. The LWP
417 * will remain parked until another LWP in the same process calls in and
418 * requests that it be unparked.
419 */
420 int
421 sys__lwp_park(struct lwp *l, void *v, register_t *retval)
422 {
423 struct sys__lwp_park_args /* {
424 syscallarg(const struct timespec *) ts;
425 syscallarg(ucontext_t *) uc;
426 syscallarg(const void *) hint;
427 } */ *uap = v;
428 const struct timespec *tsp;
429 struct timespec ts, tsx;
430 struct timeval tv;
431 sleepq_t *sq;
432 wchan_t wchan;
433 int timo, error;
434
435 /* Fix up the given timeout value. */
436 if ((tsp = SCARG(uap, ts)) != NULL) {
437 if ((error = copyin(tsp, &ts, sizeof(ts))) != 0)
438 return error;
439 getnanotime(&tsx);
440 timespecsub(&ts, &tsx, &ts);
441 tv.tv_sec = ts.tv_sec;
442 tv.tv_usec = ts.tv_nsec / 1000;
443 if (tv.tv_sec < 0 || (tv.tv_sec == 0 && tv.tv_usec < 0))
444 return ETIMEDOUT;
445 if ((error = itimerfix(&tv)) != 0)
446 return error;
447 timo = tvtohz(&tv);
448 } else
449 timo = 0;
450
451 /* Find and lock the sleep queue. */
452 wchan = lwp_park_wchan(l->l_proc, SCARG(uap, hint));
453 sq = sleeptab_lookup(&lwp_park_tab, wchan);
454
455 /*
456 * Before going the full route and blocking, check to see if an
457 * unpark op is pending.
458 */
459 sleepq_lwp_lock(l);
460 if ((l->l_flag & (LW_CANCELLED | LW_UNPARKED)) != 0) {
461 l->l_flag &= ~(LW_CANCELLED | LW_UNPARKED);
462 sleepq_lwp_unlock(l);
463 sleepq_unlock(sq);
464 return EALREADY;
465 }
466 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
467 lwp_unlock_to(l, sq->sq_mutex);
468 #endif
469
470 /*
471 * For now we ignore the ucontext argument. In the future, we may
472 * put our stack up to be recycled. If it's binned, a trampoline
473 * function could call sleepq_unblock() on our behalf.
474 */
475 KERNEL_UNLOCK_ALL(l, &l->l_biglocks); /* XXX for compat32 */
476 sleepq_block(sq, sched_kpri(l), wchan, "parked", timo, 1,
477 &lwp_park_sobj);
478 error = sleepq_unblock(timo, 1);
479 switch (error) {
480 case EWOULDBLOCK:
481 error = ETIMEDOUT;
482 break;
483 case ERESTART:
484 error = EINTR;
485 break;
486 default:
487 /* nothing */
488 break;
489 }
490 return error;
491 }
492
493 int
494 sys__lwp_unpark(struct lwp *l, void *v, register_t *retval)
495 {
496 struct sys__lwp_unpark_args /* {
497 syscallarg(lwpid_t) target;
498 syscallarg(const void *) hint;
499 } */ *uap = v;
500 struct proc *p;
501 struct lwp *t;
502 sleepq_t *sq;
503 lwpid_t target;
504 wchan_t wchan;
505 int swapin;
506
507 p = l->l_proc;
508 target = SCARG(uap, target);
509
510 /*
511 * Easy case: search for the LWP on the sleep queue. If
512 * it's parked, remove it from the queue and set running.
513 */
514 wchan = lwp_park_wchan(p, SCARG(uap, hint));
515 sq = sleeptab_lookup(&lwp_park_tab, wchan);
516
517 TAILQ_FOREACH(t, &sq->sq_queue, l_sleepchain)
518 if (t->l_proc == p && t->l_lid == target)
519 break;
520
521 if (__predict_true(t != NULL)) {
522 swapin = sleepq_remove(sq, t);
523 sleepq_unlock(sq);
524 if (swapin)
525 uvm_kick_scheduler();
526 return 0;
527 }
528
529 /*
530 * The LWP hasn't parked yet. Take the hit and mark the
531 * operation as pending.
532 */
533 sleepq_unlock(sq);
534 mutex_enter(&p->p_smutex);
535 if ((t = lwp_find(p, target)) == NULL) {
536 mutex_exit(&p->p_smutex);
537 return ESRCH;
538 }
539 lwp_lock(t);
540
541 /*
542 * It may not have parked yet, we may have raced, or it
543 * is parked on a different user sync object.
544 */
545 if (t->l_syncobj == &lwp_park_sobj) {
546 /* Releases the LWP lock. */
547 setrunnable(t);
548 } else {
549 /*
550 * Set the operation pending. The next call to _lwp_park
551 * will return early.
552 */
553 t->l_flag |= LW_UNPARKED;
554 lwp_unlock(t);
555 }
556
557 mutex_exit(&p->p_smutex);
558 return 0;
559 }
560
561 int
562 sys__lwp_unpark_all(struct lwp *l, void *v, register_t *retval)
563 {
564 struct sys__lwp_unpark_all_args /* {
565 syscallarg(const lwpid_t *) targets;
566 syscallarg(size_t) ntargets;
567 syscallarg(const void *) hint;
568 } */ *uap = v;
569 struct proc *p;
570 struct lwp *t;
571 sleepq_t *sq;
572 wchan_t wchan;
573 lwpid_t targets[32], *tp, *tpp, *tmax, target;
574 int swapin, error;
575 u_int ntargets;
576 size_t sz;
577
578 p = l->l_proc;
579 ntargets = SCARG(uap, ntargets);
580
581 if (SCARG(uap, targets) == NULL) {
582 /*
583 * Let the caller know how much we are willing to do, and
584 * let it unpark the LWPs in blocks.
585 */
586 *retval = LWP_UNPARK_MAX;
587 return 0;
588 }
589 if (ntargets > LWP_UNPARK_MAX || ntargets == 0)
590 return EINVAL;
591
592 /*
593 * Copy in the target array. If it's a small number of LWPs, then
594 * place the numbers on the stack.
595 */
596 sz = sizeof(target) * ntargets;
597 if (sz <= sizeof(targets))
598 tp = targets;
599 else {
600 KERNEL_LOCK(1, l); /* XXXSMP */
601 tp = kmem_alloc(sz, KM_SLEEP);
602 KERNEL_UNLOCK_ONE(l); /* XXXSMP */
603 if (tp == NULL)
604 return ENOMEM;
605 }
606 error = copyin(SCARG(uap, targets), tp, sz);
607 if (error != 0) {
608 if (tp != targets) {
609 KERNEL_LOCK(1, l); /* XXXSMP */
610 kmem_free(tp, sz);
611 KERNEL_UNLOCK_ONE(l); /* XXXSMP */
612 }
613 return error;
614 }
615
616 swapin = 0;
617 wchan = lwp_park_wchan(p, SCARG(uap, hint));
618 sq = sleeptab_lookup(&lwp_park_tab, wchan);
619
620 for (tmax = tp + ntargets, tpp = tp; tpp < tmax; tpp++) {
621 target = *tpp;
622
623 /*
624 * Easy case: search for the LWP on the sleep queue. If
625 * it's parked, remove it from the queue and set running.
626 */
627 TAILQ_FOREACH(t, &sq->sq_queue, l_sleepchain)
628 if (t->l_proc == p && t->l_lid == target)
629 break;
630
631 if (t != NULL) {
632 swapin |= sleepq_remove(sq, t);
633 continue;
634 }
635
636 /*
637 * The LWP hasn't parked yet. Take the hit and
638 * mark the operation as pending.
639 */
640 sleepq_unlock(sq);
641 mutex_enter(&p->p_smutex);
642 if ((t = lwp_find(p, target)) == NULL) {
643 mutex_exit(&p->p_smutex);
644 sleepq_lock(sq);
645 continue;
646 }
647 lwp_lock(t);
648
649 /*
650 * It may not have parked yet, we may have raced, or
651 * it is parked on a different user sync object.
652 */
653 if (t->l_syncobj == &lwp_park_sobj) {
654 /* Releases the LWP lock. */
655 setrunnable(t);
656 } else {
657 /*
658 * Set the operation pending. The next call to
659 * _lwp_park will return early.
660 */
661 t->l_flag |= LW_UNPARKED;
662 lwp_unlock(t);
663 }
664
665 mutex_exit(&p->p_smutex);
666 sleepq_lock(sq);
667 }
668
669 sleepq_unlock(sq);
670 if (tp != targets) {
671 KERNEL_LOCK(1, l); /* XXXSMP */
672 kmem_free(tp, sz);
673 KERNEL_UNLOCK_ONE(l); /* XXXSMP */
674 }
675 if (swapin)
676 uvm_kick_scheduler();
677
678 return 0;
679 }
680