Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Implement rump_lwproc: the new lwp/proc management routi...



details:   https://anonhg.NetBSD.org/src/rev/7c77d3cd89d6
branches:  trunk
changeset: 757513:7c77d3cd89d6
user:      pooka <pooka%NetBSD.org@localhost>
date:      Wed Sep 01 19:37:58 2010 +0000

description:
Implement rump_lwproc: the new lwp/proc management routines for
rump.  These move the management of the pid/lwpid space from the
application into the kernel, make code more robust, and make it
possible to attach multiple lwp's to non-proc0 processes.

diffstat:

 sys/rump/librump/rumpkern/Makefile.rumpkern |    8 +-
 sys/rump/librump/rumpkern/emul.c            |   23 +-
 sys/rump/librump/rumpkern/lwproc.c          |  339 ++++++++++++++++++++++++++++
 sys/rump/librump/rumpkern/rump.c            |  188 +-------------
 sys/rump/librump/rumpkern/rump_private.h    |    6 +-
 sys/rump/librump/rumpkern/scheduler.c       |  106 +++++---
 sys/rump/librump/rumpkern/sysproxy_socket.c |   10 +-
 sys/rump/librump/rumpkern/threads.c         |    8 +-
 sys/sys/lwp.h                               |    3 +-
 9 files changed, 463 insertions(+), 228 deletions(-)

diffs (truncated from 911 to 300 lines):

diff -r 8b99667471e3 -r 7c77d3cd89d6 sys/rump/librump/rumpkern/Makefile.rumpkern
--- a/sys/rump/librump/rumpkern/Makefile.rumpkern       Wed Sep 01 19:33:04 2010 +0000
+++ b/sys/rump/librump/rumpkern/Makefile.rumpkern       Wed Sep 01 19:37:58 2010 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile.rumpkern,v 1.95 2010/08/30 09:44:40 pooka Exp $
+#      $NetBSD: Makefile.rumpkern,v 1.96 2010/09/01 19:37:58 pooka Exp $
 #
 
 .include "${RUMPTOP}/Makefile.rump"
@@ -15,9 +15,9 @@
 #
 # Source modules, first the ones specifically implemented for librump.
 # 
-SRCS=  rump.c rumpcopy.c emul.c intr.c klock.c kobj_rename.c   \
-       ltsleep.c memalloc.c scheduler.c signals.c sleepq.c     \
-       sysproxy_socket.c threads.c vm.c
+SRCS=  rump.c rumpcopy.c emul.c intr.c lwproc.c klock.c        \
+       kobj_rename.c ltsleep.c memalloc.c scheduler.c          \
+       signals.c sleepq.c sysproxy_socket.c threads.c vm.c
 SRCS+= compat.c
 
 # Multiprocessor or uniprocessor locking.  TODO: select right
diff -r 8b99667471e3 -r 7c77d3cd89d6 sys/rump/librump/rumpkern/emul.c
--- a/sys/rump/librump/rumpkern/emul.c  Wed Sep 01 19:33:04 2010 +0000
+++ b/sys/rump/librump/rumpkern/emul.c  Wed Sep 01 19:37:58 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: emul.c,v 1.144 2010/06/23 08:36:03 pooka Exp $ */
+/*     $NetBSD: emul.c,v 1.145 2010/09/01 19:37:58 pooka Exp $ */
 
 /*
  * Copyright (c) 2007 Antti Kantee.  All Rights Reserved.
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: emul.c,v 1.144 2010/06/23 08:36:03 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: emul.c,v 1.145 2010/09/01 19:37:58 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/null.h>
@@ -158,6 +158,25 @@
        (*l->l_syncobj->sobj_unsleep)(l, cleanup);
 }
 
+void
+lwp_update_creds(struct lwp *l)
+{
+       struct proc *p;
+       kauth_cred_t oldcred;
+
+       p = l->l_proc;
+       oldcred = l->l_cred;
+       l->l_prflag &= ~LPR_CRMOD;
+
+       mutex_enter(p->p_lock);
+       kauth_cred_hold(p->p_cred);
+       l->l_cred = p->p_cred;
+       mutex_exit(p->p_lock);
+
+       if (oldcred != NULL)
+               kauth_cred_free(oldcred);
+}
+
 vaddr_t
 calc_cache_size(struct vm_map *map, int pct, int va_pct)
 {
diff -r 8b99667471e3 -r 7c77d3cd89d6 sys/rump/librump/rumpkern/lwproc.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/rump/librump/rumpkern/lwproc.c        Wed Sep 01 19:37:58 2010 +0000
@@ -0,0 +1,339 @@
+/*      $NetBSD: lwproc.c,v 1.1 2010/09/01 19:37:58 pooka Exp $        */
+
+/*
+ * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: lwproc.c,v 1.1 2010/09/01 19:37:58 pooka Exp $");
+
+#include <sys/param.h>
+#include <sys/atomic.h>
+#include <sys/filedesc.h>
+#include <sys/kauth.h>
+#include <sys/kmem.h>
+#include <sys/lwp.h>
+#include <sys/pool.h>
+#include <sys/proc.h>
+#include <sys/queue.h>
+#include <sys/resourcevar.h>
+#include <sys/uidinfo.h>
+
+#include <rump/rumpuser.h>
+
+#include "rump_private.h"
+
+static void
+lwproc_proc_free(struct proc *p)
+{
+       kauth_cred_t cred;
+
+       mutex_enter(proc_lock);
+
+       KASSERT(p->p_nlwps == 0);
+       KASSERT(LIST_EMPTY(&p->p_lwps));
+       KASSERT(p->p_stat == SIDL || p->p_stat == SDEAD);
+
+       LIST_REMOVE(p, p_list);
+       LIST_REMOVE(p, p_sibling);
+       proc_free_pid(p->p_pid); /* decrements nprocs */
+       proc_leavepgrp(p); /* releases proc_lock */
+
+       cred = p->p_cred;
+       chgproccnt(kauth_cred_getuid(cred), -1);
+       if (rump_proc_vfs_release)
+               rump_proc_vfs_release(p);
+
+       limfree(p->p_limit);
+       pstatsfree(p->p_stats);
+       kauth_cred_free(p->p_cred);
+       proc_finispecific(p);
+
+       mutex_obj_free(p->p_lock);
+       mutex_destroy(&p->p_stmutex);
+       mutex_destroy(&p->p_auxlock);
+       rw_destroy(&p->p_reflock);
+       cv_destroy(&p->p_waitcv);
+       cv_destroy(&p->p_lwpcv);
+
+       proc_free_mem(p);
+}
+
+/*
+ * Allocate a new process.  Mostly mimic fork by
+ * copying the properties of the parent.  However, there are some
+ * differences.  For example, we never share the fd table.
+ *
+ * Switch to the new lwp and return a pointer to it.
+ */
+static struct proc *
+lwproc_newproc(struct proc *parent)
+{
+       uid_t uid = kauth_cred_getuid(parent->p_cred);
+       struct proc *p;
+
+       /* maxproc not enforced */
+       atomic_inc_uint(&nprocs);
+
+       /* allocate process */
+       p = proc_alloc();
+       memset(&p->p_startzero, 0,
+           offsetof(struct proc, p_endzero)
+             - offsetof(struct proc, p_startzero));
+       memcpy(&p->p_startcopy, &parent->p_startcopy,
+           offsetof(struct proc, p_endcopy)
+             - offsetof(struct proc, p_startcopy));
+
+       p->p_stats = pstatscopy(parent->p_stats);
+
+       /* not based on parent */
+       p->p_vmspace = &vmspace0;
+       p->p_emul = &emul_netbsd;
+       p->p_fd = fd_init(NULL);
+       lim_addref(parent->p_limit);
+       p->p_limit = parent->p_limit;
+
+       LIST_INIT(&p->p_lwps);
+       LIST_INIT(&p->p_children);
+
+       p->p_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
+       mutex_init(&p->p_stmutex, MUTEX_DEFAULT, IPL_NONE);
+       mutex_init(&p->p_auxlock, MUTEX_DEFAULT, IPL_NONE);
+       rw_init(&p->p_reflock);
+       cv_init(&p->p_waitcv, "pwait");
+       cv_init(&p->p_lwpcv, "plwp");
+
+       p->p_pptr = parent;
+       p->p_ppid = parent->p_pid;
+
+       kauth_proc_fork(parent, p);
+
+       /* initialize cwd in rump kernels with vfs */
+       if (rump_proc_vfs_init)
+               rump_proc_vfs_init(p);
+
+       chgproccnt(uid, 1); /* not enforced */
+
+       /* publish proc various proc lists */
+       mutex_enter(proc_lock);
+       LIST_INSERT_HEAD(&allproc, p, p_list);
+       LIST_INSERT_HEAD(&parent->p_children, p, p_sibling);
+       LIST_INSERT_AFTER(parent, p, p_pglist);
+       mutex_exit(proc_lock);
+
+       return p;
+}
+
+static void
+lwproc_freelwp(struct lwp *l)
+{
+       struct proc *p;
+       bool freeproc;
+
+       p = l->l_proc;
+       mutex_enter(p->p_lock);
+
+       /* XXX: l_refcnt */
+       KASSERT(l->l_flag & LW_WEXIT);
+       KASSERT(l->l_refcnt == 0);
+
+       /* ok, zero references, continue with nuke */
+       LIST_REMOVE(l, l_sibling);
+       KASSERT(p->p_nlwps >= 1);
+       if (--p->p_nlwps == 0) {
+               KASSERT(p != &proc0);
+               p->p_stat = SDEAD;
+       }
+       freeproc = p->p_nlwps == 0;
+       cv_broadcast(&p->p_lwpcv); /* nobody sleeps on this in rump? */
+       kauth_cred_free(l->l_cred);
+       mutex_exit(p->p_lock);
+
+       mutex_enter(proc_lock);
+       LIST_REMOVE(l, l_list);
+       mutex_exit(proc_lock);
+
+       if (l->l_name)
+               kmem_free(l->l_name, MAXCOMLEN);
+       lwp_finispecific(l);
+
+       kmem_free(l, sizeof(*l));
+
+       if (p->p_stat == SDEAD)
+               lwproc_proc_free(p);    
+}
+
+/*
+ * called with p_lock held, releases lock before return
+ */
+static void
+lwproc_makelwp(struct proc *p, struct lwp *l, bool doswitch, bool procmake)
+{
+
+       p->p_nlwps++;
+       l->l_refcnt = 1;
+       l->l_proc = p;
+
+       l->l_lid = p->p_nlwpid++;
+       LIST_INSERT_HEAD(&p->p_lwps, l, l_sibling);
+       mutex_exit(p->p_lock);
+
+       lwp_update_creds(l);
+
+       l->l_fd = p->p_fd;
+       l->l_cpu = NULL;
+       l->l_target_cpu = rump_cpu; /* Initial target CPU always the same */
+
+       lwp_initspecific(l);
+
+       if (doswitch) {
+               rump_lwproc_switch(l);
+       }
+
+       /* filedesc already has refcount 1 when process is created */
+       if (!procmake) {
+               fd_hold(l);
+       }
+
+       mutex_enter(proc_lock);
+       LIST_INSERT_HEAD(&alllwp, l, l_list);
+       mutex_exit(proc_lock);
+}
+
+struct lwp *
+rump__lwproc_allockernlwp(void)
+{
+       struct proc *p;
+       struct lwp *l;
+
+       l = kmem_zalloc(sizeof(*l), KM_SLEEP);



Home | Main Index | Thread Index | Old Index