Source-Changes-HG archive

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

[src/trunk]: src/sys - use list to keep track of free stacks.



details:   https://anonhg.NetBSD.org/src/rev/9e22b1c1aa60
branches:  trunk
changeset: 555447:9e22b1c1aa60
user:      cl <cl%NetBSD.org@localhost>
date:      Mon Nov 17 22:52:09 2003 +0000

description:
- use list to keep track of free stacks.
- use splay tree for the pagefault check if the thread was running on
  an upcall stack.

=> removes the limitation that all upcall stacks need to be
   adjoining and that all upcall stacks have to be loaded with the
   1st sys_sa_stacks call.
=> enables keeping information associated with a stack in the kernel
   which makes it simpler to find out which LWP is using a stack.
=> allows increasing the SA_MAXNUMSTACKS without having to
   allocate an array of that size.

diffstat:

 sys/kern/kern_exec.c |   12 +-
 sys/kern/kern_exit.c |   14 +-
 sys/kern/kern_proc.c |    8 +-
 sys/kern/kern_sa.c   |  235 ++++++++++++++++++++++++++++++--------------------
 sys/sys/lwp.h        |    4 +-
 sys/sys/savar.h      |   21 +++-
 6 files changed, 171 insertions(+), 123 deletions(-)

diffs (truncated from 707 to 300 lines):

diff -r 2ecc9e7331b3 -r 9e22b1c1aa60 sys/kern/kern_exec.c
--- a/sys/kern/kern_exec.c      Mon Nov 17 22:38:11 2003 +0000
+++ b/sys/kern/kern_exec.c      Mon Nov 17 22:52:09 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_exec.c,v 1.175 2003/11/12 21:07:38 dsl Exp $      */
+/*     $NetBSD: kern_exec.c,v 1.176 2003/11/17 22:52:09 cl Exp $       */
 
 /*-
  * Copyright (C) 1993, 1994, 1996 Christopher G. Demetriou
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.175 2003/11/12 21:07:38 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.176 2003/11/17 22:52:09 cl Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_syscall_debug.h"
@@ -545,12 +545,8 @@
        p->p_nlwpid = 1;
 
        /* Release any SA state. */
-       if (p->p_sa) {
-               p->p_flag &= ~P_SA;
-               free(p->p_sa->sa_stacks, M_SA);
-               pool_put(&sadata_pool, p->p_sa);
-               p->p_sa = NULL;
-       }
+       if (p->p_sa)
+               sa_release(p);
 
        /* Remove POSIX timers */
        timers_free(p, TIMERS_POSIX);
diff -r 2ecc9e7331b3 -r 9e22b1c1aa60 sys/kern/kern_exit.c
--- a/sys/kern/kern_exit.c      Mon Nov 17 22:38:11 2003 +0000
+++ b/sys/kern/kern_exit.c      Mon Nov 17 22:52:09 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_exit.c,v 1.128 2003/11/12 21:07:38 dsl Exp $      */
+/*     $NetBSD: kern_exit.c,v 1.129 2003/11/17 22:52:09 cl Exp $       */
 
 /*-
  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -74,7 +74,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.128 2003/11/12 21:07:38 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.129 2003/11/17 22:52:09 cl Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_perfctrs.h"
@@ -858,13 +858,9 @@
        if (p->p_textvp)
                vrele(p->p_textvp);
 
-       /*
-        * Release any SA state
-        */
-       if (p->p_sa) {
-               free(p->p_sa->sa_stacks, M_SA);
-               pool_put(&sadata_pool, p->p_sa);
-       }
+       /* Release any SA state. */
+       if (p->p_sa)
+               sa_release(p);
 
        /* Free proc structure and let pid be reallocated */
        proc_free_mem(p);
diff -r 2ecc9e7331b3 -r 9e22b1c1aa60 sys/kern/kern_proc.c
--- a/sys/kern/kern_proc.c      Mon Nov 17 22:38:11 2003 +0000
+++ b/sys/kern/kern_proc.c      Mon Nov 17 22:52:09 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_proc.c,v 1.68 2003/11/12 21:07:38 dsl Exp $       */
+/*     $NetBSD: kern_proc.c,v 1.69 2003/11/17 22:52:09 cl Exp $        */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -69,7 +69,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.68 2003/11/12 21:07:38 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.69 2003/11/17 22:52:09 cl Exp $");
 
 #include "opt_kstack.h"
 
@@ -190,6 +190,7 @@
 struct pool ras_pool;
 struct pool sadata_pool;
 struct pool saupcall_pool;
+struct pool sastack_pool;
 struct pool ptimer_pool;
 
 MALLOC_DEFINE(M_EMULDATA, "emuldata", "Per-process emulation data");
@@ -275,7 +276,8 @@
        pool_init(&sadata_pool, sizeof(struct sadata), 0, 0, 0, "sadatapl",
            &pool_allocator_nointr);
        pool_init(&saupcall_pool, sizeof(struct sadata_upcall), 0, 0, 0, 
-           "saupcpl",
+           "saupcpl", &pool_allocator_nointr);
+       pool_init(&sastack_pool, sizeof(struct sastack), 0, 0, 0, "sastackpl",
            &pool_allocator_nointr);
        pool_init(&ptimer_pool, sizeof(struct ptimer), 0, 0, 0, "ptimerpl",
            &pool_allocator_nointr);
diff -r 2ecc9e7331b3 -r 9e22b1c1aa60 sys/kern/kern_sa.c
--- a/sys/kern/kern_sa.c        Mon Nov 17 22:38:11 2003 +0000
+++ b/sys/kern/kern_sa.c        Mon Nov 17 22:52:09 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_sa.c,v 1.42 2003/11/12 21:27:46 cl Exp $  */
+/*     $NetBSD: kern_sa.c,v 1.43 2003/11/17 22:52:09 cl Exp $  */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sa.c,v 1.42 2003/11/12 21:27:46 cl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sa.c,v 1.43 2003/11/17 22:52:09 cl Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -53,11 +53,12 @@
 
 #include <uvm/uvm_extern.h>
 
+static __inline int sast_compare(struct sastack *, struct sastack *);
 static void sa_setwoken(struct lwp *);
 static int sa_newcachelwp(struct lwp *);
 static struct lwp *sa_vp_repossess(struct lwp *l);
 
-static int sa_pagefault(struct lwp *, ucontext_t *);
+static __inline int sa_pagefault(struct lwp *, ucontext_t *);
 
 void sa_upcall_getstate(union sau_state *, struct lwp *);
 
@@ -84,6 +85,9 @@
        (l)->l_flag |= (f) & L_SA;                              \
 } while (/*CONSTCOND*/ 0)
 
+SPLAY_PROTOTYPE(sasttree, sastack, sast_node, sast_compare);
+SPLAY_GENERATE(sasttree, sastack, sast_node, sast_compare);
+
 
 /*
  * sadata_upcall_alloc:
@@ -152,13 +156,11 @@
                sa->sa_vp = NULL;
                sa->sa_wokenq_head = NULL;
                sa->sa_concurrency = 1;
-               sa->sa_stacks = malloc(sizeof(stack_t) * SA_NUMSTACKS,
-                   M_SA, M_WAITOK);
+               SPLAY_INIT(&sa->sa_stackstree);
+               SLIST_INIT(&sa->sa_stackslist);
                sa->sa_nstacks = 0;
                sa->sa_vp_faultaddr = 0;
                sa->sa_vp_ofaultaddr = 0;
-               sa->sa_vp_stacks_low = 0;
-               sa->sa_vp_stacks_high = 0;
                LIST_INIT(&sa->sa_lwpcache);
                SIMPLEQ_INIT(&sa->sa_upcalls);
                p->p_sa = sa;
@@ -177,6 +179,38 @@
        return (0);
 }
 
+void
+sa_release(struct proc *p)
+{
+       struct sadata *sa;
+       struct sastack *sast, *next;
+
+       sa = p->p_sa;
+       KDASSERT(sa != NULL);
+
+       for (sast = SPLAY_MIN(sasttree, &sa->sa_stackstree); sast != NULL;
+            sast = next) {
+               next = SPLAY_NEXT(sasttree, &sa->sa_stackstree, sast);
+               SPLAY_REMOVE(sasttree, &sa->sa_stackstree, sast);
+               pool_put(&sastack_pool, sast);
+       }
+
+       p->p_flag &= ~P_SA;
+       pool_put(&sadata_pool, sa);
+       p->p_sa = NULL;
+}
+
+static __inline int
+sast_compare(struct sastack *a, struct sastack *b)
+{
+       if ((vaddr_t)a->sast_stack.ss_sp + a->sast_stack.ss_size <=
+           (vaddr_t)b->sast_stack.ss_sp)
+               return (-1);
+       if ((vaddr_t)a->sast_stack.ss_sp >=
+           (vaddr_t)b->sast_stack.ss_sp + b->sast_stack.ss_size)
+               return (1);
+       return (0);
+}
 
 int
 sys_sa_stacks(struct lwp *l, void *v, register_t *retval)
@@ -187,6 +221,7 @@
        } */ *uap = v;
        struct sadata *sa = l->l_proc->p_sa;
        struct lwp *l2;
+       struct sastack *sast, newsast;
        int count, error, f, i;
 
        /* We have to be using scheduler activations */
@@ -196,59 +231,59 @@
        count = SCARG(uap, num);
        if (count < 0)
                return (EINVAL);
-       count = min(count, SA_NUMSTACKS - sa->sa_nstacks);
 
        SA_LWP_STATE_LOCK(l, f);
-       error = copyin(SCARG(uap, stacks), sa->sa_stacks + sa->sa_nstacks,
-           sizeof(stack_t) * count);
-       SA_LWP_STATE_UNLOCK(l, f);
-       if (error)
-               return (error);
+
+       error = 0;
 
-       for (i = sa->sa_nstacks; i < sa->sa_nstacks + count; i++) {
-               LIST_FOREACH(l2, &l->l_proc->p_lwps, l_sibling) {
-                       if ((l2->l_upcallstack == sa->sa_stacks[i].ss_sp)) {
+       for (i = 0; i < count; i++) {
+               error = copyin(SCARG(uap, stacks) + i, &newsast.sast_stack,
+                   sizeof(stack_t));
+               if (error) {
+                       count = i;
+                       break;
+               }
+               if ((sast = SPLAY_FIND(sasttree, &sa->sa_stackstree, &newsast))) {
+                       DPRINTFN(9, ("sa_stacks(%d.%d) returning stack %p\n",
+                                    l->l_proc->p_pid, l->l_lid,
+                                    newsast.sast_stack.ss_sp));
+                       if ((l2 = sast->sast_blocker)) {
                                l2->l_upcallstack = NULL;
+                               sast->sast_blocker = NULL;
                                wakeup(&l2->l_upcallstack);
                        }
+                       if (SLIST_NEXT(sast, sast_list) != (void *)-1) {
+                               count = i;
+                               error = EEXIST;
+                               break;
+                       }
+               } else if (sa->sa_nstacks >= SA_MAXNUMSTACKS * sa->sa_concurrency) {
+                       DPRINTFN(9, ("sa_stacks(%d.%d) already using %d stacks\n",
+                                    l->l_proc->p_pid, l->l_lid,
+                                    SA_MAXNUMSTACKS * sa->sa_concurrency));
+                       count = i;
+                       error = ENOMEM;
+                       break;
+               } else {
+                       DPRINTFN(9, ("sa_stacks(%d.%d) adding stack %p\n",
+                                    l->l_proc->p_pid, l->l_lid,
+                                    newsast.sast_stack.ss_sp));
+                       sast = pool_get(&sastack_pool, PR_WAITOK);
+                       sast->sast_stack = newsast.sast_stack;
+                       sast->sast_blocker = NULL;
+                       SPLAY_INSERT(sasttree, &sa->sa_stackstree, sast);
+                       sa->sa_nstacks++;
                }
+               SLIST_INSERT_HEAD(&sa->sa_stackslist, sast, sast_list);
        }
 
-       if ((sa->sa_nstacks == 0) && (sa->sa_wokenq_head != NULL))
+       if (SLIST_EMPTY(&sa->sa_stackslist) && (sa->sa_wokenq_head != NULL))
                l->l_flag |= L_SA_UPCALL; 
 
-       /*
-        * Save addresses of the first and last stack on initial load
-        * the pagefault code uses the saved address to detect threads
-        * running on an upcall stack.
-        * XXX assumes all stacks are adjoining
-        * XXX assumes initial load includes all stacks ever used
-        */
-       if (sa->sa_vp_stacks_low == 0) {
-               vaddr_t low = VM_MAXUSER_ADDRESS;
-               vaddr_t high = 0;
-
-               for (i = 0; i < count; i++) {
-                       stack_t *stackp = &sa->sa_stacks[sa->sa_nstacks + i];
-
-                       low = min(low, (vaddr_t)stackp->ss_sp);
-                       high = max(high,
-                           (vaddr_t)stackp->ss_sp + stackp->ss_size);
-               }
-               sa->sa_vp_stacks_low = low;
-               sa->sa_vp_stacks_high = high;
-               DPRINTFN(11,("sys_sa_stacks(%d.%d): low 0x%llx high 0x%llx\n",
-                            l->l_proc->p_pid, l->l_lid,
-                            (unsigned long long)sa->sa_vp_stacks_low,
-                            (unsigned long long)sa->sa_vp_stacks_high));
-       }
-
-       sa->sa_nstacks += count;
-       DPRINTFN(9, ("sa_stacks(%d.%d) nstacks + %d = %2d\n",



Home | Main Index | Thread Index | Old Index