Source-Changes-HG archive

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

[src/trunk]: src/sys Avoid sneaking past signal delivery in sa_upcall_userret():



details:   https://anonhg.NetBSD.org/src/rev/f83732ee9e00
branches:  trunk
changeset: 554697:f83732ee9e00
user:      cl <cl%NetBSD.org@localhost>
date:      Sat Nov 01 01:38:46 2003 +0000

description:
Avoid sneaking past signal delivery in sa_upcall_userret():
generate unblocked upcalls in sa_unblock_userret(), before signal
delivery/p_userret handling in userret().

Also defer getting state for preempted upcalls because on some ports
preemption can happen between sa_unblock_userret() and sa_upcall_userret().

diffstat:

 sys/arch/pc532/pc532/trap.c     |   8 +++-
 sys/arch/sparc/sparc/trap.c     |   8 +++-
 sys/arch/sparc64/sparc64/trap.c |   8 +++-
 sys/arch/vax/vax/trap.c         |   8 +++-
 sys/kern/kern_sa.c              |  77 ++++++++++++++++++++++++----------------
 sys/sys/savar.h                 |   3 +-
 sys/sys/userret.h               |   8 +++-
 7 files changed, 78 insertions(+), 42 deletions(-)

diffs (truncated from 325 to 300 lines):

diff -r a7c622ae7985 -r f83732ee9e00 sys/arch/pc532/pc532/trap.c
--- a/sys/arch/pc532/pc532/trap.c       Sat Nov 01 01:38:25 2003 +0000
+++ b/sys/arch/pc532/pc532/trap.c       Sat Nov 01 01:38:46 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: trap.c,v 1.58 2003/10/31 03:28:13 simonb Exp $ */
+/*     $NetBSD: trap.c,v 1.59 2003/11/01 01:38:46 cl Exp $     */
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -77,7 +77,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.58 2003/10/31 03:28:13 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.59 2003/11/01 01:38:46 cl Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -147,6 +147,10 @@
        struct proc *p = l->l_proc;
        int sig;
 
+       /* Generate UNBLOCKED upcall. */
+       if (l->l_flag & L_SA_BLOCKING)
+               sa_unblock_userret(l);
+
        /* take pending signals */
        while ((sig = CURSIG(l)) != 0)
                postsig(sig);
diff -r a7c622ae7985 -r f83732ee9e00 sys/arch/sparc/sparc/trap.c
--- a/sys/arch/sparc/sparc/trap.c       Sat Nov 01 01:38:25 2003 +0000
+++ b/sys/arch/sparc/sparc/trap.c       Sat Nov 01 01:38:46 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: trap.c,v 1.148 2003/10/31 03:28:13 simonb Exp $ */
+/*     $NetBSD: trap.c,v 1.149 2003/11/01 01:38:46 cl Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -49,7 +49,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.148 2003/10/31 03:28:13 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.149 2003/11/01 01:38:46 cl Exp $");
 
 #include "opt_ddb.h"
 #include "opt_ktrace.h"
@@ -233,6 +233,10 @@
        struct proc *p = l->l_proc;
        int sig;
 
+       /* Generate UNBLOCKED upcall. */
+       if (l->l_flag & L_SA_BLOCKING)
+               sa_unblock_userret(l);
+
        /* take pending signals */
        while ((sig = CURSIG(l)) != 0)
                postsig(sig);
diff -r a7c622ae7985 -r f83732ee9e00 sys/arch/sparc64/sparc64/trap.c
--- a/sys/arch/sparc64/sparc64/trap.c   Sat Nov 01 01:38:25 2003 +0000
+++ b/sys/arch/sparc64/sparc64/trap.c   Sat Nov 01 01:38:46 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: trap.c,v 1.97 2003/10/27 00:15:24 christos Exp $ */
+/*     $NetBSD: trap.c,v 1.98 2003/11/01 01:38:46 cl Exp $ */
 
 /*
  * Copyright (c) 1996-2002 Eduardo Horvath.  All rights reserved.
@@ -50,7 +50,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.97 2003/10/27 00:15:24 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.98 2003/11/01 01:38:46 cl Exp $");
 
 #define NEW_FPSTATE
 
@@ -443,6 +443,10 @@
        struct proc *p = l->l_proc;
        int sig;
 
+       /* Generate UNBLOCKED upcall. */
+       if (l->l_flag & L_SA_BLOCKING)
+               sa_unblock_userret(l);
+
        /* take pending signals */
        while ((sig = CURSIG(l)) != 0)
                postsig(sig);
diff -r a7c622ae7985 -r f83732ee9e00 sys/arch/vax/vax/trap.c
--- a/sys/arch/vax/vax/trap.c   Sat Nov 01 01:38:25 2003 +0000
+++ b/sys/arch/vax/vax/trap.c   Sat Nov 01 01:38:46 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: trap.c,v 1.88 2003/10/31 03:28:14 simonb Exp $     */
+/*     $NetBSD: trap.c,v 1.89 2003/11/01 01:38:47 cl Exp $     */
 
 /*
  * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
@@ -33,7 +33,7 @@
  /* All bugs are subject to removal without further notice */
                
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.88 2003/10/31 03:28:14 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.89 2003/11/01 01:38:47 cl Exp $");
 
 #include "opt_ddb.h"
 #include "opt_ktrace.h"
@@ -127,6 +127,10 @@
        int sig;
        struct proc *p = l->l_proc;
 
+       /* Generate UNBLOCKED upcall. */
+       if (l->l_flag & L_SA_BLOCKING)
+               sa_unblock_userret(l);
+
        /* Take pending signals. */
        while ((sig = CURSIG(l)) != 0)
                postsig(sig);
diff -r a7c622ae7985 -r f83732ee9e00 sys/kern/kern_sa.c
--- a/sys/kern/kern_sa.c        Sat Nov 01 01:38:25 2003 +0000
+++ b/sys/kern/kern_sa.c        Sat Nov 01 01:38:46 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_sa.c,v 1.33 2003/10/31 23:36:50 cl Exp $  */
+/*     $NetBSD: kern_sa.c,v 1.34 2003/11/01 01:38:47 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.33 2003/10/31 23:36:50 cl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sa.c,v 1.34 2003/11/01 01:38:47 cl Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -440,8 +440,14 @@
        struct proc *p = l->l_proc;
        struct sadata *sa = p->p_sa;
 
+       /* 
+        * Defer saving the lwp's state because on some ports
+        * preemption can occur between generating an unblocked upcall
+        * and processing the upcall queue.
+        */
        if (sa->sa_flag & SA_FLAG_PREEMPT)
-               sa_upcall(l, SA_UPCALL_PREEMPTED, l, NULL, 0, NULL);
+               sa_upcall(l, SA_UPCALL_PREEMPTED | SA_UPCALL_DEFER_EVENT,
+                   l, NULL, 0, NULL);
 }
 
 
@@ -1068,18 +1074,14 @@
 
 
 void
-sa_upcall_userret(struct lwp *l)
+sa_unblock_userret(struct lwp *l)
 {
        struct proc *p;
+       struct lwp *l2;
        struct sadata *sa;
-       struct sa_t **sapp, *sap;
        struct sadata_upcall *sau;
-       struct sa_t self_sa;
-       struct sa_t *sas[3];
        stack_t st;
-       void *stack, *ap;
-       ucontext_t u, *up;
-       int f, i, nsas, nint, nevents, sig, s, type;
+       int f, s;
 
        p = l->l_proc;
        sa = p->p_sa;
@@ -1089,7 +1091,7 @@
        KERNEL_PROC_LOCK(l);
        SA_LWP_STATE_LOCK(l, f);
 
-       DPRINTFN(7,("sa_upcall_userret(%d.%d %x) \n", p->p_pid, l->l_lid,
+       DPRINTFN(7,("sa_unblock_userret(%d.%d %x) \n", p->p_pid, l->l_lid,
            l->l_flag));
 
        while (l->l_upcallstack != NULL) {
@@ -1122,11 +1124,9 @@
 
        if (l->l_flag & L_SA_BLOCKING) {
                /* Invoke an "unblocked" upcall */
-               struct lwp *l2;
-               DPRINTFN(8,("sa_upcall_userret(%d.%d) unblocking\n",
+               DPRINTFN(8,("sa_unblock_userret(%d.%d) unblocking\n",
                    p->p_pid, l->l_lid));
 
-
                sau = sadata_upcall_alloc(1);
                sau->sau_arg = NULL;
 
@@ -1134,7 +1134,6 @@
                        sadata_upcall_free(sau);
                        lwp_exit(l);
                }
-
        
                SCHED_ASSERT_UNLOCKED();
 
@@ -1142,7 +1141,8 @@
 
                KDASSERT(sa->sa_nstacks > 0);
                st = sa->sa_stacks[--sa->sa_nstacks];
-
+               DPRINTFN(9,("sa_unblock_userret(%d.%d) nstacks--   = %2d\n",
+                   l->l_proc->p_pid, l->l_lid, sa->sa_nstacks));
                
                SCHED_ASSERT_UNLOCKED();
                        
@@ -1152,8 +1152,10 @@
                        lwp_exit(l);
                }
 
-               DPRINTFN(9,("sa_upcall_userret(%d.%d) nstacks--   = %2d\n",
-                   l->l_proc->p_pid, l->l_lid, sa->sa_nstacks));
+               /*
+                * Defer saving the event lwp's state because a
+                * PREEMPT upcall could be on the queue already.
+                */
                if (sa_upcall0(l, SA_UPCALL_UNBLOCKED | SA_UPCALL_DEFER_EVENT,
                        l, l2, 0, NULL, sau, &st) != 0) {
                        /*
@@ -1161,7 +1163,7 @@
                         * upcall, but don't have resources to do so.
                         */
 #ifdef DIAGNOSTIC
-                       printf("sa_upcall_userret: out of upcall resources"
+                       printf("sa_unblock_userret: out of upcall resources"
                            " for %d.%d\n", p->p_pid, l->l_lid);
 #endif
                        sigexit(l, SIGABRT);
@@ -1173,22 +1175,35 @@
                SCHED_LOCK(s);
                sa_putcachelwp(p, l2); /* PHOLD from sa_vp_repossess */
                SCHED_UNLOCK(s);
+       }
+       SA_LWP_STATE_UNLOCK(l, f);
+       KERNEL_PROC_UNLOCK(l);
+}
 
-               /* We migth have sneaked past signal handling and userret */
-               SA_LWP_STATE_UNLOCK(l, f);
-               KERNEL_PROC_UNLOCK(l);
 
-               /* take pending signals */
-               while ((sig = CURSIG(l)) != 0)
-                       postsig(sig);
+void
+sa_upcall_userret(struct lwp *l)
+{
+       struct proc *p;
+       struct sadata *sa;
+       struct sa_t **sapp, *sap;
+       struct sadata_upcall *sau;
+       struct sa_t self_sa;
+       struct sa_t *sas[3];
+       void *stack, *ap;
+       ucontext_t u, *up;
+       int f, i, nsas, nint, nevents, type;
 
-               /* Invoke per-process kernel-exit handling, if any */
-               if (p->p_userret)
-                       (p->p_userret)(l, p->p_userret_arg);
+       p = l->l_proc;
+       sa = p->p_sa;
+       
+       SCHED_ASSERT_UNLOCKED();
 
-               KERNEL_PROC_LOCK(l);
-               SA_LWP_STATE_LOCK(l, f);
-       }
+       KERNEL_PROC_LOCK(l);
+       SA_LWP_STATE_LOCK(l, f);
+
+       DPRINTFN(7,("sa_upcall_userret(%d.%d %x) \n", p->p_pid, l->l_lid,
+           l->l_flag));
 
        KDASSERT(sa->sa_vp == l);
 
diff -r a7c622ae7985 -r f83732ee9e00 sys/sys/savar.h
--- a/sys/sys/savar.h   Sat Nov 01 01:38:25 2003 +0000
+++ b/sys/sys/savar.h   Sat Nov 01 01:38:46 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: savar.h,v 1.8 2003/10/31 22:47:44 cl Exp $     */
+/*     $NetBSD: savar.h,v 1.9 2003/11/01 01:38:47 cl Exp $     */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -128,6 +128,7 @@
 struct lwp *sa_getcachelwp(struct proc *);
 
 
+void   sa_unblock_userret(struct lwp *);
 void   sa_upcall_userret(struct lwp *);
 void   cpu_upcall(struct lwp *, int, int, int, void *, void *, void *, sa_upcall_t);
 
diff -r a7c622ae7985 -r f83732ee9e00 sys/sys/userret.h



Home | Main Index | Thread Index | Old Index