summaryrefslogtreecommitdiff
path: root/sys/compat/linux/common/linux_exec.c
diff options
context:
space:
mode:
authorad <ad@NetBSD.org>2008-04-24 15:35:27 +0000
committerad <ad@NetBSD.org>2008-04-24 15:35:27 +0000
commit6d70f903e67437ed96fb6d98a4c9b0b9c08eeed8 (patch)
tree5dd579f1fa5f280ae3188efd01fb2172f1db9101 /sys/compat/linux/common/linux_exec.c
parentef9411cb09232b55dea056b3e63408fcd3c952f4 (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.c23
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) {