Source-Changes-HG archive

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

[src/trunk]: src/sys Prevent sa_newcachelwp() from creating new LWPs when the...



details:   https://anonhg.NetBSD.org/src/rev/c5dbf9cf4d6f
branches:  trunk
changeset: 555261:c5dbf9cf4d6f
user:      cl <cl%NetBSD.org@localhost>
date:      Wed Nov 12 21:27:46 2003 +0000

description:
Prevent sa_newcachelwp() from creating new LWPs when the process is exiting.
This should fix PR 23418 which was also reported by Thomas Klausner and
Ian Fry (who also provided core dumps for analysis - thanks!).

Also g/c sa_yieldcall since it's now safe to put LWPs back into the cache.
Also return stacks in failure case.

diffstat:

 sys/kern/kern_sa.c |  70 +++++++++++++++++------------------------------------
 sys/sys/savar.h    |   3 +-
 2 files changed, 24 insertions(+), 49 deletions(-)

diffs (149 lines):

diff -r b39622662472 -r c5dbf9cf4d6f sys/kern/kern_sa.c
--- a/sys/kern/kern_sa.c        Wed Nov 12 21:07:37 2003 +0000
+++ b/sys/kern/kern_sa.c        Wed Nov 12 21:27:46 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_sa.c,v 1.41 2003/11/07 18:37:41 cl Exp $  */
+/*     $NetBSD: kern_sa.c,v 1.42 2003/11/12 21:27:46 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.41 2003/11/07 18:37:41 cl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sa.c,v 1.42 2003/11/12 21:27:46 cl Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -750,31 +750,34 @@
                        return;
                }
 
+               if (sa->sa_nstacks == 0) {
+#ifdef DIAGNOSTIC
+                       printf("sa_switch(%d.%d flag %x): Not enough stacks.\n",
+                           p->p_pid, l->l_lid, l->l_flag);
+#endif
+                       sa_putcachelwp(p, l2); /* PHOLD from sa_getcachelwp */
+                       mi_switch(l, NULL);
+                       return;
+               }
+
                /*
                 * XXX We need to allocate the sadata_upcall structure here,
                 * XXX since we can't sleep while waiting for memory inside
                 * XXX sa_upcall().  It would be nice if we could safely
                 * XXX allocate the sadata_upcall structure on the stack, here.
                 */
-
-               if (sa->sa_nstacks == 0) {
-#ifdef DIAGNOSTIC
-                       printf("sa_switch(%d.%d flag %x): Not enough stacks.\n",
-                           p->p_pid, l->l_lid, l->l_flag);
-#endif
-                       goto sa_upcall_failed;
-               }
-
                sau = sadata_upcall_alloc(0);
                if (sau == NULL) {
 #ifdef DIAGNOSTIC
                        printf("sa_switch(%d.%d): "
                            "couldn't allocate upcall data.\n",
                            p->p_pid, l->l_lid);
+#endif
+                       sa_putcachelwp(p, l2); /* PHOLD from sa_getcachelwp */
+                       mi_switch(l, NULL);
+                       return;
+               }
 
-#endif
-                       goto sa_upcall_failed;
-               }
                st = sa->sa_stacks[--sa->sa_nstacks];
                DPRINTFN(9,("sa_switch(%d.%d) nstacks--   = %2d\n", 
                    l->l_proc->p_pid, l->l_lid, sa->sa_nstacks));
@@ -787,7 +790,10 @@
                        printf("sa_switch(%d.%d): Error %d from sa_upcall()\n",
                            p->p_pid, l->l_lid, error);
 #endif
-                       goto sa_upcall_failed;
+                       sa->sa_stacks[sa->sa_nstacks++] = st;
+                       sa_putcachelwp(p, l2); /* PHOLD from sa_getcachelwp */
+                       mi_switch(l, NULL);
+                       return;
                }
 
                /* 
@@ -842,13 +848,6 @@
        } else {
                /* NOTREACHED */
                panic("sa_vp empty");
-
-       sa_upcall_failed:
-               cpu_setfunc(l2, sa_yieldcall, l2);
-
-               l2->l_priority = l2->l_usrpri;
-               setrunnable(l2);
-               PRELE(l2); /* Remove the artificial hold-count */
        }
 
        DPRINTFN(4,("sa_switch(%d.%d) switching to LWP %d.\n",
@@ -888,31 +887,6 @@
        upcallret(l);
 }
 
-void
-sa_yieldcall(void *arg)
-{
-       struct lwp *l;
-       struct proc *p;
-       struct sadata *sa;
-
-       l = arg;
-       p = l->l_proc;
-       sa = p->p_sa;
-       sa->sa_vp = l;
-
-       DPRINTFN(6,("sa_yieldcall(%d.%d)\n", p->p_pid, l->l_lid));
-
-       if (LIST_EMPTY(&sa->sa_lwpcache)) {
-               /* Allocate the next cache LWP */
-               DPRINTFN(6,("sa_yieldcall(%d.%d) allocating LWP\n",
-                   p->p_pid, l->l_lid));
-               sa_newcachelwp(l);
-       }
-
-       sa_yield(l);
-       upcallret(l);
-}
-
 static int
 sa_newcachelwp(struct lwp *l)
 {
@@ -923,6 +897,8 @@
        int s;
 
        p = l->l_proc;
+       if (p->p_flag & P_WEXIT)
+               return (0);
 
        inmem = uvm_uarea_alloc(&uaddr);
        if (__predict_false(uaddr == 0)) {
diff -r b39622662472 -r c5dbf9cf4d6f sys/sys/savar.h
--- a/sys/sys/savar.h   Wed Nov 12 21:07:37 2003 +0000
+++ b/sys/sys/savar.h   Wed Nov 12 21:27:46 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: savar.h,v 1.11 2003/11/03 22:34:51 cl Exp $    */
+/*     $NetBSD: savar.h,v 1.12 2003/11/12 21:27:46 cl Exp $    */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -116,7 +116,6 @@
 void   sa_preempt(struct lwp *);
 void   sa_yield(struct lwp *);
 void   sa_switchcall(void *);
-void   sa_yieldcall(void *);
 int    sa_upcall(struct lwp *, int, struct lwp *, struct lwp *, size_t, void *);
 int    sa_upcall0(struct lwp *, int, struct lwp *, struct lwp *,
            size_t, void *, struct sadata_upcall *, stack_t *);



Home | Main Index | Thread Index | Old Index