Move from struct proc to process the reference-count-holding pointers
authorguenther <guenther@openbsd.org>
Thu, 15 May 2014 03:52:25 +0000 (03:52 +0000)
committerguenther <guenther@openbsd.org>
Thu, 15 May 2014 03:52:25 +0000 (03:52 +0000)
to the process's vmspace and filedescs.  struct proc continues to
keep copies of the pointers, copying them on fork, clearing them
on exit, and (for vmspace) refreshing on exec.
Also, make uvm_swapout_threads() thread aware, eliminating p_swtime
in kernel.

particular testing by ajacoutot@ and sebastia@

14 files changed:
sys/arch/vax/vax/pmap.c
sys/kern/init_main.c
sys/kern/kern_descrip.c
sys/kern/kern_exec.c
sys/kern/kern_exit.c
sys/kern/kern_fork.c
sys/kern/kern_proc.c
sys/kern/sched_bsd.c
sys/sys/filedesc.h
sys/sys/proc.h
sys/sys/sysctl.h
sys/uvm/uvm_extern.h
sys/uvm/uvm_glue.c
sys/uvm/uvm_map.c

index c97421f..2ce070f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pmap.c,v 1.64 2014/05/08 19:06:07 miod Exp $ */
+/*     $OpenBSD: pmap.c,v 1.65 2014/05/15 03:52:25 guenther Exp $ */
 /*     $NetBSD: pmap.c,v 1.74 1999/11/13 21:32:25 matt Exp $      */
 /*
  * Copyright (c) 1994, 1998, 1999, 2003 Ludd, University of Lule}, Sweden.
@@ -605,71 +605,61 @@ rmspace(struct pmap *pm)
  * Avoid to remove ourselves. Logic is designed after uvm_swapout_threads().
  */
 
-static inline boolean_t
-pmap_vax_swappable(struct proc *p, struct pmap *pm)
-{
-       if (p->p_flag & (P_SYSTEM | P_WEXIT))   /* !swappable(p) */
-               return FALSE;
-       if (p->p_vmspace->vm_map.pmap == pm)
-               return FALSE;
-       switch (p->p_stat) {
-       case SRUN:
-       case SSLEEP:
-       case SSTOP:
-               return TRUE;
-       default:
-               return FALSE;
-       }
-}
-
 int
 pmap_rmproc(struct pmap *pm)
 {
+       struct process *pr, *outpr;
        struct pmap *ppm;
-       struct proc *p;
-       struct proc *outp, *outp2;
-       int outpri, outpri2;
+       struct proc *p, *slpp;
+       int outpri;
        int didswap = 0;
        extern int maxslp;
 
-       outp = outp2 = NULL;
-       outpri = outpri2 = 0;
-       LIST_FOREACH(p, &allproc, p_list) {
-               if (!pmap_vax_swappable(p, pm))
+       outpr = NULL;
+       outpri = 0;
+       LIST_FOREACH(pr, &allprocess, ps_list) {
+               if (pr->ps_flags & (PS_SYSTEM | PS_EXITING))
                        continue;
                ppm = p->p_vmspace->vm_map.pmap;
+               if (ppm == pm)          /* Don't swap ourself */
+                       continue;
                if (ppm->pm_p0lr == 0 && ppm->pm_p1lr == NPTEPERREG)
-                       continue; /* Already swapped */
-               switch (p->p_stat) {
-               case SRUN:
-#if 0 /* won't pass pmap_vax_swappable() */
-               case SONPROC:
-#endif
-                       if (p->p_swtime > outpri2) {
-                               outp2 = p;
-                               outpri2 = p->p_swtime;
+                       continue;       /* Already swapped */
+
+               /*
+                * slpp: the sleeping or stopped thread in pr with
+                * the smallest p_slptime
+                */
+               slpp = NULL;
+               TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) {
+                       switch (p->p_stat) {
+                       case SRUN:
+                       case SONPROC:
+                               goto next_process;
+
+                       case SSLEEP:
+                       case SSTOP:
+                               if (slpp == NULL ||
+                                   slpp->p_slptime < p->p_slptime)
+                               slpp = p;
+                               continue;
                        }
-                       continue;
-               case SSLEEP:
-               case SSTOP:
-                       if (p->p_slptime >= maxslp) {
+               }
+               if (slpp != NULL) {
+                       if (slpp->p_slptime >= maxslp) {
                                rmspace(ppm);
                                didswap++;
-                       } else if (p->p_slptime > outpri) {
-                               outp = p;
+                       } else if (slpp->p_slptime > outpri) {
+                               outpr = pr;
                                outpri = p->p_slptime;
                        }
-                       continue;
                }
+next_process:  ;
        }
 
-       if (didswap == 0) {
-               if ((p = outp) == NULL)
-                       p = outp2;
-               if (p) {
-                       rmspace(p->p_vmspace->vm_map.pmap);
-                       didswap++;
-               }
+       if (didswap == 0 && outpr != NULL) {
+               rmspace(outpr->ps_vmspace->vm_map.pmap);
+               didswap++;
        }
        return didswap;
 }
index 92481c3..fba6902 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: init_main.c,v 1.212 2014/05/04 05:03:26 guenther Exp $        */
+/*     $OpenBSD: init_main.c,v 1.213 2014/05/15 03:52:25 guenther Exp $        */
 /*     $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $   */
 
 /*
@@ -305,7 +305,7 @@ main(void *framep)
        siginit(pr);
 
        /* Create the file descriptor table. */
-       p->p_fd = fdinit(NULL);
+       p->p_fd = pr->ps_fd = fdinit();
 
        /* Create the limits structures. */
        pr->ps_limit = &limit0;
@@ -325,7 +325,7 @@ main(void *framep)
        /* Allocate a prototype map so we have something to fork. */
        uvmspace_init(&vmspace0, pmap_kernel(), round_page(VM_MIN_ADDRESS),
            trunc_page(VM_MAX_ADDRESS), TRUE, TRUE);
-       p->p_vmspace = &vmspace0;
+       p->p_vmspace = pr->ps_vmspace = &vmspace0;
 
        p->p_addr = proc0paddr;                         /* XXX */
 
index ab36785..484d3c7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_descrip.c,v 1.107 2014/04/12 14:18:11 espie Exp $        */
+/*     $OpenBSD: kern_descrip.c,v 1.108 2014/05/15 03:52:25 guenther Exp $     */
 /*     $NetBSD: kern_descrip.c,v 1.42 1996/03/30 22:24:38 christos Exp $       */
 
 /*
@@ -867,21 +867,12 @@ restart:
  * Build a new filedesc structure.
  */
 struct filedesc *
-fdinit(struct proc *p)
+fdinit(void)
 {
        struct filedesc0 *newfdp;
        extern int cmask;
 
        newfdp = pool_get(&fdesc_pool, PR_WAITOK|PR_ZERO);
-       if (p != NULL) {
-               struct filedesc *fdp = p->p_fd;
-
-               newfdp->fd_fd.fd_cdir = fdp->fd_cdir;
-               vref(newfdp->fd_fd.fd_cdir);
-               newfdp->fd_fd.fd_rdir = fdp->fd_rdir;
-               if (newfdp->fd_fd.fd_rdir)
-                       vref(newfdp->fd_fd.fd_rdir);
-       }
        rw_init(&newfdp->fd_fd.fd_lock, "fdlock");
 
        /* Create the file descriptor table. */
@@ -904,19 +895,19 @@ fdinit(struct proc *p)
  * Share a filedesc structure.
  */
 struct filedesc *
-fdshare(struct proc *p)
+fdshare(struct process *pr)
 {
-       p->p_fd->fd_refcnt++;
-       return (p->p_fd);
+       pr->ps_fd->fd_refcnt++;
+       return (pr->ps_fd);
 }
 
 /*
  * Copy a filedesc structure.
  */
 struct filedesc *
-fdcopy(struct proc *p)
+fdcopy(struct process *pr)
 {
-       struct filedesc *newfdp, *fdp = p->p_fd;
+       struct filedesc *newfdp, *fdp = pr->ps_fd;
        struct file **fpp;
        int i;
 
index 969ac15..91bbc2e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_exec.c,v 1.141 2014/04/18 11:51:17 guenther Exp $        */
+/*     $OpenBSD: kern_exec.c,v 1.142 2014/05/15 03:52:25 guenther Exp $        */
 /*     $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $  */
 
 /*-
@@ -78,7 +78,7 @@
 /*
  * Map the shared signal code.
  */
-int exec_sigcode_map(struct proc *, struct emul *);
+int exec_sigcode_map(struct process *, struct emul *);
 
 /*
  * If non-zero, stackgap_random specifies the upper limit of the random gap size
@@ -256,7 +256,7 @@ sys_execve(struct proc *p, void *v, register_t *retval)
 #endif
        char *stack;
        struct ps_strings arginfo;
-       struct vmspace *vm = p->p_vmspace;
+       struct vmspace *vm = pr->ps_vmspace;
        char **tmpfap;
        extern struct emul emul_native;
 #if NSYSTRACE > 0
@@ -415,17 +415,16 @@ sys_execve(struct proc *p, void *v, register_t *retval)
        /*
         * we're committed: any further errors will kill the process, so
         * kill the other threads now.
-        * XXX wait until threads are reaped to make uvmspace_exec() cheaper?
         */
        single_thread_set(p, SINGLE_EXIT, 0);
 
        /*
         * Prepare vmspace for remapping. Note that uvmspace_exec can replace
-        * p_vmspace!
+        * pr_vmspace!
         */
        uvmspace_exec(p, VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS);
 
-       vm = p->p_vmspace;
+       vm = pr->ps_vmspace;
        /* Now map address space */
        vm->vm_taddr = (char *)pack.ep_taddr;
        vm->vm_tsize = atop(round_page(pack.ep_tsize));
@@ -653,7 +652,7 @@ sys_execve(struct proc *p, void *v, register_t *retval)
 #endif
 
        /* map the process's signal trampoline code */
-       if (exec_sigcode_map(p, pack.ep_emul))
+       if (exec_sigcode_map(pr, pack.ep_emul))
                goto free_pack_abort;
 
 #ifdef __HAVE_EXEC_MD_MAP
@@ -817,7 +816,7 @@ copyargs(struct exec_package *pack, struct ps_strings *arginfo, void *stack,
 }
 
 int
-exec_sigcode_map(struct proc *p, struct emul *e)
+exec_sigcode_map(struct process *pr, struct emul *e)
 {
        vsize_t sz;
 
@@ -851,9 +850,9 @@ exec_sigcode_map(struct proc *p, struct emul *e)
                uvm_unmap(kernel_map, va, va + round_page(sz));
        }
 
-       p->p_p->ps_sigcode = 0; /* no hint */
+       pr->ps_sigcode = 0; /* no hint */
        uao_reference(e->e_sigobject);
-       if (uvm_map(&p->p_vmspace->vm_map, &p->p_p->ps_sigcode, round_page(sz),
+       if (uvm_map(&pr->ps_vmspace->vm_map, &pr->ps_sigcode, round_page(sz),
            e->e_sigobject, 0, 0, UVM_MAPFLAG(UVM_PROT_RX, UVM_PROT_RX,
            UVM_INH_SHARE, UVM_ADV_RANDOM, 0))) {
                uao_detach(e->e_sigobject);
index 37e7c39..1fbaa86 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_exit.c,v 1.140 2014/04/18 11:51:17 guenther Exp $        */
+/*     $OpenBSD: kern_exit.c,v 1.141 2014/05/15 03:52:25 guenther Exp $        */
 /*     $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $  */
 
 /*
@@ -176,12 +176,10 @@ exit1(struct proc *p, int rv, int flags)
        }
        p->p_siglist = 0;
 
-       /*
-        * Close open files and release open-file table.
-        */
-       fdfree(p);
-
        if ((p->p_flag & P_THREAD) == 0) {
+               /* close open files and release open-file table */
+               fdfree(p);
+
                timeout_del(&pr->ps_realit_to);
 #ifdef SYSVSEM
                semexit(pr);
@@ -242,6 +240,8 @@ exit1(struct proc *p, int rv, int flags)
                        atomic_setbits_int(&pr->ps_flags, PS_NOZOMBIE);
        }
 
+       p->p_fd = NULL;         /* zap the thread's copy */
+
 #if NSYSTRACE > 0
        if (ISSET(p->p_flag, P_SYSTRACE))
                systrace_exit(p);
@@ -446,7 +446,8 @@ reaper(void)
                 * We must do this from a valid thread because doing
                 * so may block.
                 */
-               uvm_exit(p);
+               uvm_uarea_free(p);
+               p->p_vmspace = NULL;            /* zap the thread's copy */
 
                if (p->p_flag & P_THREAD) {
                        /* Just a thread */
@@ -454,6 +455,9 @@ reaper(void)
                } else {
                        struct process *pr = p->p_p;
 
+                       /* Release the rest of the process's vmspace */
+                       uvm_exit(pr);
+
                        if ((pr->ps_flags & PS_NOZOMBIE) == 0) {
                                /* Process is now a true zombie. */
                                p->p_stat = SZOMB;
index adbabb3..30e29bc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_fork.c,v 1.166 2014/05/06 11:50:14 mpi Exp $     */
+/*     $OpenBSD: kern_fork.c,v 1.167 2014/05/15 03:52:25 guenther Exp $        */
 /*     $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $  */
 
 /*
@@ -196,12 +196,21 @@ process_new(struct proc *p, struct process *parent, int flags)
        p->p_p = pr;
 
        /*
-        * Create signal actions for the child process.
+        * Duplicate sub-structures as needed.
+        * Increase reference counts on shared objects.
         */
+       if (flags & FORK_SHAREFILES)
+               pr->ps_fd = fdshare(parent);
+       else
+               pr->ps_fd = fdcopy(parent);
        if (flags & FORK_SIGHAND)
                pr->ps_sigacts = sigactsshare(parent);
        else
                pr->ps_sigacts = sigactsinit(parent);
+       if (flags & FORK_SHAREVM)
+               pr->ps_vmspace = uvmspace_share(parent);
+       else
+               pr->ps_vmspace = uvmspace_fork(parent);
 
        if (parent->ps_flags & PS_PROFIL)
                startprofclock(pr);
@@ -334,18 +343,11 @@ fork1(struct proc *curp, int flags, void *stack, pid_t *tidptr,
                process_new(p, curpr, flags);
                pr = p->p_p;
        }
+       p->p_fd         = pr->ps_fd;
+       p->p_vmspace    = pr->ps_vmspace;
        if (pr->ps_flags & PS_SYSTEM)
                atomic_setbits_int(&p->p_flag, P_SYSTEM);
 
-       /*
-        * Duplicate sub-structures as needed.
-        * Increase reference counts on shared objects.
-        */
-       if (flags & FORK_SHAREFILES)
-               p->p_fd = fdshare(curp);
-       else
-               p->p_fd = fdcopy(curp);
-
        if (flags & FORK_PPWAIT) {
                atomic_setbits_int(&pr->ps_flags, PS_PPWAIT);
                atomic_setbits_int(&curpr->ps_flags, PS_ISPWAIT);
@@ -380,13 +382,16 @@ fork1(struct proc *curp, int flags, void *stack, pid_t *tidptr,
        p->p_addr = (struct user *)uaddr;
 
        /*
-        * Finish creating the child process.  It will return through a
-        * different path later.
+        * Finish creating the child thread.  cpu_fork() will copy
+        * and update the pcb and make the child ready to run.  If
+        * this is a normal user fork, the child will exit directly
+        * to user mode via child_return() on its first time slice
+        * and will not return here.  If this is a kernel thread,
+        * the specified entry point will be executed.
         */
-       uvm_fork(curp, p, ((flags & FORK_SHAREVM) ? TRUE : FALSE), stack,
-           0, func ? func : child_return, arg ? arg : p);
+       cpu_fork(curp, p, stack, 0, func ? func : child_return, arg ? arg : p);
 
-       vm = p->p_vmspace;
+       vm = pr->ps_vmspace;
 
        if (flags & FORK_FORK) {
                forkstat.cntfork++;
index c749d53..757878a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_proc.c,v 1.57 2014/03/30 21:54:48 guenther Exp $ */
+/*     $OpenBSD: kern_proc.c,v 1.58 2014/05/15 03:52:25 guenther Exp $ */
 /*     $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $  */
 
 /*
@@ -403,9 +403,8 @@ proc_printit(struct proc *p, const char *modif,
            TAILQ_NEXT(p, p_runq), p->p_list.le_next, p->p_list.le_prev);
        (*pr)("    process=%p user=%p, vmspace=%p\n",
            p->p_p, p->p_addr, p->p_vmspace);
-       (*pr)("    estcpu=%u, cpticks=%d, pctcpu=%u.%u, swtime=%u\n",
-           p->p_estcpu, p->p_cpticks, p->p_pctcpu / 100, p->p_pctcpu % 100,
-           p->p_swtime);
+       (*pr)("    estcpu=%u, cpticks=%d, pctcpu=%u.%u\n",
+           p->p_estcpu, p->p_cpticks, p->p_pctcpu / 100, p->p_pctcpu % 100);
        (*pr)("    user=%u, sys=%u, intr=%u\n",
            p->p_uticks, p->p_sticks, p->p_iticks);
 }
index ed512c2..1a73afc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sched_bsd.c,v 1.33 2013/06/03 16:55:22 guenther Exp $ */
+/*     $OpenBSD: sched_bsd.c,v 1.34 2014/05/15 03:52:25 guenther Exp $ */
 /*     $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
 
 /*-
@@ -222,7 +222,6 @@ schedcpu(void *arg)
                 * (if sleeping).  We ignore overflow; with 16-bit int's
                 * (remember them?) overflow takes 45 days.
                 */
-               p->p_swtime++;
                if (p->p_stat == SSLEEP || p->p_stat == SSTOP)
                        p->p_slptime++;
                p->p_pctcpu = (p->p_pctcpu * ccpu) >> FSHIFT;
index 452c7a4..b383a38 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: filedesc.h,v 1.27 2014/04/12 14:18:11 espie Exp $     */
+/*     $OpenBSD: filedesc.h,v 1.28 2014/05/15 03:52:25 guenther Exp $  */
 /*     $NetBSD: filedesc.h,v 1.14 1996/04/09 20:55:28 cgd Exp $        */
 
 /*
@@ -125,9 +125,9 @@ int dupfdopen(struct filedesc *, int, int, int);
 int    fdalloc(struct proc *p, int want, int *result);
 void   fdexpand(struct proc *);
 int    falloc(struct proc *p, struct file **resultfp, int *resultfd);
-struct filedesc *fdinit(struct proc *p);
-struct filedesc *fdshare(struct proc *p);
-struct filedesc *fdcopy(struct proc *p);
+struct filedesc *fdinit(void);
+struct filedesc *fdshare(struct process *);
+struct filedesc *fdcopy(struct process *);
 void   fdfree(struct proc *p);
 int    fdrelease(struct proc *p, int);
 void   fdremove(struct filedesc *, int);
index cf4170a..dffe712 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: proc.h,v 1.185 2014/05/04 05:03:26 guenther Exp $     */
+/*     $OpenBSD: proc.h,v 1.186 2014/05/15 03:52:25 guenther Exp $     */
 /*     $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $       */
 
 /*-
@@ -166,6 +166,8 @@ struct process {
 
        struct  sigacts *ps_sigacts;    /* Signal actions, state */
        struct  vnode *ps_textvp;       /* Vnode of executable. */
+       struct  filedesc *ps_fd;        /* Ptr to open files structure */
+       struct  vmspace *ps_vmspace;    /* Address space */
 
 /* The following fields are all zeroed upon creation in process_new. */
 #define        ps_startzero    ps_klist
@@ -259,8 +261,8 @@ struct proc {
        TAILQ_ENTRY(proc) p_thr_link;/* Threads in a process linkage. */
 
        /* substructures: */
-       struct  filedesc *p_fd;         /* Ptr to open files structure. */
-       struct  vmspace *p_vmspace;     /* Address space. */
+       struct  filedesc *p_fd;         /* copy of p_p->ps_fd */
+       struct  vmspace *p_vmspace;     /* copy of p_p->ps_vmspace */
 #define        p_rlimit        p_p->ps_limit->pl_rlimit
 
        int     p_flag;                 /* P_* flags. */
@@ -285,8 +287,7 @@ struct proc {
        const volatile void *p_wchan;/* Sleep address. */
        struct  timeout p_sleep_to;/* timeout for tsleep() */
        const char *p_wmesg;     /* Reason for sleep. */
-       fixpt_t p_pctcpu;        /* %cpu for this thread during p_swtime */
-       u_int   p_swtime;        /* Time swapped in or out. */
+       fixpt_t p_pctcpu;        /* %cpu for this thread */
        u_int   p_slptime;       /* Time since last blocked. */
        u_int   p_uticks;               /* Statclock hits in user mode. */
        u_int   p_sticks;               /* Statclock hits in system mode. */
index 2e43d2e..97d355e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sysctl.h,v 1.144 2014/03/30 21:54:48 guenther Exp $   */
+/*     $OpenBSD: sysctl.h,v 1.145 2014/05/15 03:52:25 guenther Exp $   */
 /*     $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $  */
 
 /*
@@ -357,8 +357,8 @@ struct kinfo_proc {
        u_int32_t p_rtime_sec;          /* STRUCT TIMEVAL: Real time. */
        u_int32_t p_rtime_usec;         /* STRUCT TIMEVAL: Real time. */
        int32_t p_cpticks;              /* INT: Ticks of cpu time. */
-       u_int32_t p_pctcpu;             /* FIXPT_T: %cpu for this process during p_swtime */
-       u_int32_t p_swtime;             /* U_INT: Time swapped in or out. */
+       u_int32_t p_pctcpu;             /* FIXPT_T: %cpu for this process */
+       u_int32_t p_swtime;             /* unused, always zero */
        u_int32_t p_slptime;            /* U_INT: Time since last blocked. */
        int32_t p_schedflags;           /* INT: PSCHED_* flags */
 
@@ -469,9 +469,9 @@ do {                                                                        \
                                                                        \
        if (show_addresses) {                                           \
                (kp)->p_paddr = PTRTOINT64(paddr);                      \
-               (kp)->p_fd = PTRTOINT64((p)->p_fd);                     \
+               (kp)->p_fd = PTRTOINT64((pr)->ps_fd);                   \
                (kp)->p_limit = PTRTOINT64((pr)->ps_limit);             \
-               (kp)->p_vmspace = PTRTOINT64((p)->p_vmspace);           \
+               (kp)->p_vmspace = PTRTOINT64((pr)->ps_vmspace);         \
                (kp)->p_sigacts = PTRTOINT64((pr)->ps_sigacts);         \
                (kp)->p_sess = PTRTOINT64((pg)->pg_session);            \
                (kp)->p_ru = PTRTOINT64((pr)->ps_ru);                   \
@@ -551,7 +551,6 @@ do {                                                                        \
                }                                                       \
                (kp)->p_addr = PTRTOINT64((p)->p_addr);                 \
                (kp)->p_stat = (p)->p_stat;                             \
-               (kp)->p_swtime = (p)->p_swtime;                         \
                (kp)->p_slptime = (p)->p_slptime;                       \
                (kp)->p_holdcnt = 1;                                    \
                (kp)->p_priority = (p)->p_priority;                     \
index 4dd4ee8..76b5946 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_extern.h,v 1.114 2014/05/06 11:50:14 mpi Exp $    */
+/*     $OpenBSD: uvm_extern.h,v 1.115 2014/05/15 03:52:25 guenther Exp $       */
 /*     $NetBSD: uvm_extern.h,v 1.57 2001/03/09 01:02:12 chs Exp $      */
 
 /*
@@ -513,9 +513,8 @@ int                 uvm_fault(vm_map_t, vaddr_t,
 void                   uvm_chgkprot(caddr_t, size_t, int);
 #endif
 vaddr_t                        uvm_uarea_alloc(void);
-void                   uvm_fork(struct proc *, struct proc *, boolean_t,
-                           void *, size_t, void (*)(void *), void *);
-void                   uvm_exit(struct proc *);
+void                   uvm_uarea_free(struct proc *);
+void                   uvm_exit(struct process *);
 void                   uvm_init_limits(struct proc *);
 boolean_t              uvm_kernacc(caddr_t, size_t, int);
 
@@ -668,9 +667,9 @@ struct vmspace              *uvmspace_alloc(vaddr_t, vaddr_t,
 void                   uvmspace_init(struct vmspace *, struct pmap *,
                                vaddr_t, vaddr_t, boolean_t, boolean_t);
 void                   uvmspace_exec(struct proc *, vaddr_t, vaddr_t);
-struct vmspace         *uvmspace_fork(struct vmspace *);
+struct vmspace         *uvmspace_fork(struct process *);
 void                   uvmspace_free(struct vmspace *);
-void                   uvmspace_share(struct proc *, struct proc *);
+struct vmspace         *uvmspace_share(struct process *);
 
 
 /* uvm_meter.c */
index 5865c46..88eb3c3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_glue.c,v 1.64 2014/05/03 22:49:43 guenther Exp $  */
+/*     $OpenBSD: uvm_glue.c,v 1.65 2014/05/15 03:52:25 guenther Exp $  */
 /*     $NetBSD: uvm_glue.c,v 1.44 2001/02/06 19:54:44 eeh Exp $        */
 
 /* 
@@ -316,53 +316,26 @@ uvm_uarea_alloc(void)
 }
 
 /*
- * uvm_fork: fork a virtual address space
+ * uvm_uarea_free: free a dead thread's stack
  *
- * - the address space is copied as per parent map's inherit values
- * - if specified, the child gets a new user stack described by
- *     stack and stacksize
- * - NOTE: the kernel stack may be at a different location in the child
- *     process, and thus addresses of automatic variables may be invalid
- *     after cpu_fork returns in the child process.  We do nothing here
- *     after cpu_fork returns.
- * - XXXCDC: we need a way for this to return a failure value rather
- *   than just hang
+ * - the thread passed to us is a dead thread; we
+ *   are running on a different context now (the reaper).
  */
 void
-uvm_fork(struct proc *p1, struct proc *p2, boolean_t shared, void *stack,
-    size_t stacksize, void (*func)(void *), void * arg)
+uvm_uarea_free(struct proc *p)
 {
-       if (shared == TRUE) {
-               p2->p_vmspace = NULL;
-               uvmspace_share(p1, p2);                 /* share vmspace */
-       } else
-               p2->p_vmspace = uvmspace_fork(p1->p_vmspace); /* fork vmspace */
-
-       /*
-        * cpu_fork() copy and update the pcb, and make the child ready
-        * to run.  If this is a normal user fork, the child will exit
-        * directly to user mode via child_return() on its first time
-        * slice and will not return here.  If this is a kernel thread,
-        * the specified entry point will be executed.
-        */
-       cpu_fork(p1, p2, stack, stacksize, func, arg);
+       uvm_km_free(kernel_map, (vaddr_t)p->p_addr, USPACE);
+       p->p_addr = NULL;
 }
 
 /*
  * uvm_exit: exit a virtual address space
- *
- * - the process passed to us is a dead (pre-zombie) process; we
- *   are running on a different context now (the reaper).
- * - we must run in a separate thread because freeing the vmspace
- *   of the dead process may block.
  */
 void
-uvm_exit(struct proc *p)
+uvm_exit(struct process *pr)
 {
-       uvmspace_free(p->p_vmspace);
-       p->p_vmspace = NULL;
-       uvm_km_free(kernel_map, (vaddr_t)p->p_addr, USPACE);
-       p->p_addr = NULL;
+       uvmspace_free(pr->ps_vmspace);
+       pr->ps_vmspace = NULL;
 }
 
 /*
@@ -395,11 +368,6 @@ int        swapdebug = 0;
 #define SDB_SWAPOUT    4
 #endif
 
-/*
- * swappable: is process "p" swappable?
- */
-
-#define        swappable(p) (((p)->p_flag & (P_SYSTEM | P_WEXIT)) == 0)
 
 /*
  * swapout_threads: find threads that can be swapped
@@ -413,9 +381,10 @@ int        swapdebug = 0;
 void
 uvm_swapout_threads(void)
 {
-       struct proc *p;
-       struct proc *outp, *outp2;
-       int outpri, outpri2;
+       struct process *pr;
+       struct proc *p, *slpp;
+       struct process *outpr;
+       int outpri;
        int didswap = 0;
        extern int maxslp; 
        /* XXXCDC: should move off to uvmexp. or uvm., also in uvm_meter */
@@ -426,33 +395,45 @@ uvm_swapout_threads(void)
 #endif
 
        /*
-        * outp/outpri  : stop/sleep process with largest sleeptime < maxslp
-        * outp2/outpri2: the longest resident process (its swap time)
+        * outpr/outpri  : stop/sleep process whose most active thread has
+        *      the largest sleeptime < maxslp
         */
-       outp = outp2 = NULL;
-       outpri = outpri2 = 0;
-       LIST_FOREACH(p, &allproc, p_list) {
-               if (!swappable(p))
+       outpr = NULL;
+       outpri = 0;
+       LIST_FOREACH(pr, &allprocess, ps_list) {
+               if (pr->ps_flags & (PS_SYSTEM | PS_EXITING))
                        continue;
-               switch (p->p_stat) {
-               case SRUN:
-                       if (p->p_swtime > outpri2) {
-                               outp2 = p;
-                               outpri2 = p->p_swtime;
+
+               /*
+                * slpp: the sleeping or stopped thread in pr with
+                * the smallest p_slptime
+                */
+               slpp = NULL;
+               TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) {
+                       switch (p->p_stat) {
+                       case SRUN:
+                       case SONPROC:
+                               goto next_process;
+
+                       case SSLEEP:
+                       case SSTOP:
+                               if (slpp == NULL ||
+                                   slpp->p_slptime < p->p_slptime)
+                                       slpp = p;
+                               continue;
                        }
-                       continue;
-                       
-               case SSLEEP:
-               case SSTOP:
-                       if (p->p_slptime >= maxslp) {
-                               pmap_collect(p->p_vmspace->vm_map.pmap);
+               }
+
+               if (slpp != NULL) {
+                       if (slpp->p_slptime >= maxslp) {
+                               pmap_collect(pr->ps_vmspace->vm_map.pmap);
                                didswap++;
-                       } else if (p->p_slptime > outpri) {
-                               outp = p;
-                               outpri = p->p_slptime;
+                       } else if (slpp->p_slptime > outpri) {
+                               outpr = pr;
+                               outpri = slpp->p_slptime;
                        }
-                       continue;
                }
+next_process:  ;
        }
 
        /*
@@ -461,15 +442,14 @@ uvm_swapout_threads(void)
         * if we are real low on memory since we don't gain much by doing
         * it.
         */
-       if (didswap == 0 && uvmexp.free <= atop(round_page(USPACE))) {
-               if ((p = outp) == NULL)
-                       p = outp2;
+       if (didswap == 0 && uvmexp.free <= atop(round_page(USPACE)) &&
+           outpr != NULL) {
 #ifdef DEBUG
                if (swapdebug & SDB_SWAPOUT)
-                       printf("swapout_threads: no duds, try procp %p\n", p);
+                       printf("swapout_threads: no duds, try procpr %p\n",
+                           outpr);
 #endif
-               if (p)
-                       pmap_collect(p->p_vmspace->vm_map.pmap);
+               pmap_collect(outpr->ps_vmspace->vm_map.pmap);
        }
 }
 
index 5d668e1..1648d40 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_map.c,v 1.167 2014/04/13 23:14:15 tedu Exp $      */
+/*     $OpenBSD: uvm_map.c,v 1.168 2014/05/15 03:52:25 guenther Exp $  */
 /*     $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
 
 /*
@@ -3015,15 +3015,16 @@ uvmspace_init(struct vmspace *vm, struct pmap *pmap, vaddr_t min, vaddr_t max,
  * uvmspace_share: share a vmspace between two processes
  *
  * - XXX: no locking on vmspace
- * - used for vfork and threads
+ * - used for vfork
  */
 
-void
-uvmspace_share(p1, p2)
-       struct proc *p1, *p2;
+struct vmspace *
+uvmspace_share(struct process *pr)
 {
-       p2->p_vmspace = p1->p_vmspace;
-       p1->p_vmspace->vm_refcnt++;
+       struct vmspace *vm = pr->ps_vmspace;
+
+       vm->vm_refcnt++;
+       return vm;
 }
 
 /*
@@ -3035,7 +3036,8 @@ uvmspace_share(p1, p2)
 void
 uvmspace_exec(struct proc *p, vaddr_t start, vaddr_t end)
 {
-       struct vmspace *nvm, *ovm = p->p_vmspace;
+       struct process *pr = p->p_p;
+       struct vmspace *nvm, *ovm = pr->ps_vmspace;
        struct vm_map *map = &ovm->vm_map;
        struct uvm_map_deadq dead_entries;
 
@@ -3049,8 +3051,9 @@ uvmspace_exec(struct proc *p, vaddr_t start, vaddr_t end)
        /* see if more than one process is using this vmspace...  */
        if (ovm->vm_refcnt == 1) {
                /*
-                * if p is the only process using its vmspace then we can safely
-                * recycle that vmspace for the program that is being exec'd.
+                * If pr is the only process using its vmspace then
+                * we can safely recycle that vmspace for the program
+                * that is being exec'd.
                 */
 
 #ifdef SYSVSHM
@@ -3104,16 +3107,16 @@ uvmspace_exec(struct proc *p, vaddr_t start, vaddr_t end)
                pmap_remove_holes(map);
        } else {
                /*
-                * p's vmspace is being shared, so we can't reuse it for p since
-                * it is still being used for others.   allocate a new vmspace
-                * for p
+                * pr's vmspace is being shared, so we can't reuse
+                * it for pr since it is still being used for others.
+                * allocate a new vmspace for pr
                 */
                nvm = uvmspace_alloc(start, end,
                    (map->flags & VM_MAP_PAGEABLE) ? TRUE : FALSE, TRUE);
 
                /* install new vmspace and drop our ref to the old one. */
                pmap_deactivate(p);
-               p->p_vmspace = nvm;
+               p->p_vmspace = pr->ps_vmspace = nvm;
                pmap_activate(p);
 
                uvmspace_free(ovm);
@@ -3409,8 +3412,9 @@ uvm_mapent_forkcopy(struct vmspace *new_vm, struct vm_map *new_map,
  * => parent's map must not be locked.
  */
 struct vmspace *
-uvmspace_fork(struct vmspace *vm1)
+uvmspace_fork(struct process *pr)
 {
+       struct vmspace *vm1 = pr->ps_vmspace;
        struct vmspace *vm2;
        struct vm_map *old_map = &vm1->vm_map;
        struct vm_map *new_map;