diff options
| author | ad <ad@NetBSD.org> | 2008-04-24 15:35:27 +0000 |
|---|---|---|
| committer | ad <ad@NetBSD.org> | 2008-04-24 15:35:27 +0000 |
| commit | 6d70f903e67437ed96fb6d98a4c9b0b9c08eeed8 (patch) | |
| tree | 5dd579f1fa5f280ae3188efd01fb2172f1db9101 /sys/compat/linux/common/linux_exec.c | |
| parent | ef9411cb09232b55dea056b3e63408fcd3c952f4 (diff) | |
Network protocol interrupts can now block on locks, so merge the globals
proclist_mutex and proclist_lock into a single adaptive mutex (proc_lock).
Implications:
- Inspecting process state requires thread context, so signals can no longer
be sent from a hardware interrupt handler. Signal activity must be
deferred to a soft interrupt or kthread.
- As the proc state locking is simplified, it's now safe to take exit()
and wait() out from under kernel_lock.
- The system spends less time at IPL_SCHED, and there is less lock activity.
Diffstat (limited to 'sys/compat/linux/common/linux_exec.c')
| -rw-r--r-- | sys/compat/linux/common/linux_exec.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/sys/compat/linux/common/linux_exec.c b/sys/compat/linux/common/linux_exec.c index a6b5d0bca33..dbcb990758e 100644 --- a/sys/compat/linux/common/linux_exec.c +++ b/sys/compat/linux/common/linux_exec.c @@ -1,4 +1,4 @@ -/* $NetBSD: linux_exec.c,v 1.103 2008/04/23 12:50:53 ad Exp $ */ +/* $NetBSD: linux_exec.c,v 1.104 2008/04/24 15:35:27 ad Exp $ */ /*- * Copyright (c) 1994, 1995, 1998, 2000, 2007, 2008 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux_exec.c,v 1.103 2008/04/23 12:50:53 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_exec.c,v 1.104 2008/04/24 15:35:27 ad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -148,11 +148,11 @@ linux_e_proc_init(p, parent, forkflags) MALLOC(e, void *, sizeof(struct linux_emuldata), M_EMULDATA, M_WAITOK); } else { - mutex_enter(&proclist_lock); + mutex_enter(proc_lock); e->s->refs--; if (e->s->refs == 0) FREE(e->s, M_EMULDATA); - mutex_exit(&proclist_lock); + mutex_exit(proc_lock); } memset(e, '\0', sizeof(struct linux_emuldata)); @@ -163,15 +163,16 @@ linux_e_proc_init(p, parent, forkflags) ep = parent->p_emuldata; if (forkflags & FORK_SHAREVM) { + mutex_enter(proc_lock); #ifdef DIAGNOSTIC if (ep == NULL) { killproc(p, "FORK_SHAREVM while emuldata is NULL\n"); + mutex_exit(proc_lock); FREE(e, M_EMULDATA); return; } #endif s = ep->s; - mutex_enter(&proclist_lock); s->refs++; } else { struct vmspace *vm; @@ -205,7 +206,7 @@ linux_e_proc_init(p, parent, forkflags) s->xstat = 0; s->flags = 0; - mutex_enter(&proclist_lock); + mutex_enter(proc_lock); } e->s = s; @@ -223,7 +224,7 @@ linux_e_proc_init(p, parent, forkflags) } #endif /* LINUX_NPTL */ - mutex_exit(&proclist_lock); + mutex_exit(proc_lock); p->p_emuldata = e; } @@ -253,7 +254,7 @@ linux_e_proc_exit(struct proc *p) #endif /* Remove the thread for the group thread list */ - mutex_enter(&proclist_lock); + mutex_enter(proc_lock); LIST_REMOVE(e, threads); /* free Linux emuldata and set the pointer to null */ @@ -261,7 +262,7 @@ linux_e_proc_exit(struct proc *p) if (e->s->refs == 0) FREE(e->s, M_EMULDATA); p->p_emuldata = NULL; - mutex_exit(&proclist_lock); + mutex_exit(proc_lock); FREE(e, M_EMULDATA); } @@ -322,7 +323,7 @@ linux_nptl_proc_exit(struct proc *p) { struct linux_emuldata *e = p->p_emuldata; - mutex_enter(&proclist_lock); + mutex_enter(proc_lock); /* * Check if we are a thread group leader victim of another @@ -349,7 +350,7 @@ linux_nptl_proc_exit(struct proc *p) cv_broadcast(&initproc->p_waitcv); } - mutex_exit(&proclist_lock); + mutex_exit(proc_lock); /* Emulate LINUX_CLONE_CHILD_CLEARTID */ if (e->clear_tid != NULL) { |
