Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 30 Jul 2001 12:46:06 -0700 (PDT)
From:      John Baldwin <jhb@FreeBSD.org>
To:        hackers@FreeBSD.org
Cc:        bde@FreeBSD.org
Subject:   PATCH: Make ast's loop
Message-ID:  <XFMail.010730124606.jhb@FreeBSD.org>

next in thread | raw e-mail | index | archive | help
I have a patch to close some races with receiving AST's while handling other
AST's.  Unfortunately due to my office being moved all my test machines are
unavailable at the moment, so I'd like people to test it for me on SMP machines
and alpha.  I'll include it below, but my mailer may mangle it, so here is a
URL as well: http://www.FreeBSD.org/~jhb/patches/ast.patch

Index: kern/subr_trap.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/subr_trap.c,v
retrieving revision 1.196
diff -u -r1.196 subr_trap.c
--- kern/subr_trap.c    2001/07/04 15:36:30     1.196
+++ kern/subr_trap.c    2001/07/17 22:54:42
@@ -72,9 +72,9 @@
        while ((sig = CURSIG(p)) != 0)
                postsig(sig);
        mtx_unlock(&Giant);
+       PROC_UNLOCK(p);
 
        mtx_lock_spin(&sched_lock);
-       PROC_UNLOCK_NOSWITCH(p);
        p->p_pri.pri_level = p->p_pri.pri_user;
        if (resched_wanted(p)) {
                /*
@@ -96,24 +96,22 @@
                while ((sig = CURSIG(p)) != 0)
                        postsig(sig);
                mtx_unlock(&Giant);
-               mtx_lock_spin(&sched_lock);
-               PROC_UNLOCK_NOSWITCH(p);
-       }
+               PROC_UNLOCK(p);
+       } else
+               mtx_unlock_spin(&sched_lock);
 
        /*
         * Charge system time if profiling.
         */
-       if (p->p_sflag & PS_PROFIL) {
-               mtx_unlock_spin(&sched_lock);
+       if (p->p_sflag & PS_PROFIL)
                addupc_task(p, TRAPF_PC(frame),
                            (u_int)(p->p_sticks - oticks) * psratio);
-       } else
-               mtx_unlock_spin(&sched_lock);
 }
 
 /*
  * Process an asynchronous software trap.
  * This is relatively easy.
+ * This function will return with interrupts disabled.
  */
 void
 ast(framep)
@@ -121,67 +119,54 @@
 {
        struct proc *p = CURPROC;
        u_quad_t sticks;
+       critical_t s;
 #if defined(DEV_NPX) && !defined(SMP)
        int ucode;
 #endif
 
        KASSERT(TRAPF_USERMODE(framep), ("ast in kernel mode"));
-
-       /*
-        * We check for a pending AST here rather than in the assembly as
-        * acquiring and releasing mutexes in assembly is not fun.
-        */
-       mtx_lock_spin(&sched_lock);
-       if (!(astpending(p) || resched_wanted(p))) {
-               mtx_unlock_spin(&sched_lock);
-               return;
-       }
-
-       sticks = p->p_sticks;
-       p->p_frame = framep;
-
-       astoff(p);
-       cnt.v_soft++;
-       mtx_intr_enable(&sched_lock);
-       if (p->p_sflag & PS_OWEUPC) {
-               p->p_sflag &= ~PS_OWEUPC;
-               mtx_unlock_spin(&sched_lock);
-               mtx_lock(&Giant);
-               addupc_task(p, p->p_stats->p_prof.pr_addr,
-                           p->p_stats->p_prof.pr_ticks);
+       s = critical_enter();
+       while (astpending(p) || resched_wanted(p)) {
+               critical_exit(s);
+               sticks = p->p_sticks;
+               p->p_frame = framep;
                mtx_lock_spin(&sched_lock);
-       }
-       if (p->p_sflag & PS_ALRMPEND) {
-               p->p_sflag &= ~PS_ALRMPEND;
+               astoff(p);
+               cnt.v_soft++;
                mtx_unlock_spin(&sched_lock);
-               PROC_LOCK(p);
-               psignal(p, SIGVTALRM);
-               PROC_UNLOCK(p);
-               mtx_lock_spin(&sched_lock);
-       }
+               if (p->p_sflag & PS_OWEUPC)
+                       addupc_task(p, p->p_stats->p_prof.pr_addr,
+                                   p->p_stats->p_prof.pr_ticks);
+               if (p->p_sflag & PS_ALRMPEND) {
+                       PROC_LOCK(p);
+                       psignal(p, SIGVTALRM);
+                       PROC_UNLOCK(p);
+               }
 #if defined(DEV_NPX) && !defined(SMP)
-       if (PCPU_GET(curpcb)->pcb_flags & PCB_NPXTRAP) {
-               PCPU_GET(curpcb)->pcb_flags &= ~PCB_NPXTRAP;
-               mtx_unlock_spin(&sched_lock);
-               ucode = npxtrap();
-               if (ucode != -1) {
-                       if (!mtx_owned(&Giant))
-                               mtx_lock(&Giant);
-                       trapsignal(p, SIGFPE, ucode);
+               if (PCPU_GET(curpcb)->pcb_flags & PCB_NPXTRAP) {
+                       ucode = npxtrap();
+                       if (ucode != -1) {
+                               if (!mtx_owned(&Giant))
+                                       mtx_lock(&Giant);
+                               trapsignal(p, SIGFPE, ucode);
+                       }
+               }
+#endif
+               if (p->p_sflag & PS_PROFPEND) {
+                       PROC_LOCK(p);
+                       psignal(p, SIGPROF);
+                       PROC_UNLOCK(p);
                }
                mtx_lock_spin(&sched_lock);
-       }
+               p->p_sflag &= ~(PS_OWEUPC | PS_ALRMPEND | PS_PROFPEND);
+#if defined(DEV_NPX) && !defined(SMP)
+               PCPU_GET(curpcb)->pcb_flags &= ~PCB_NPXTRAP;
 #endif
-       if (p->p_sflag & PS_PROFPEND) {
-               p->p_sflag &= ~PS_PROFPEND;
                mtx_unlock_spin(&sched_lock);
-               PROC_LOCK(p);
-               psignal(p, SIGPROF);
-               PROC_UNLOCK(p);
-       } else
-               mtx_unlock_spin(&sched_lock);
 
-       userret(p, framep, sticks);
+               userret(p, framep, sticks);
+               s = critical_enter();
+       }
 
        if (mtx_owned(&Giant))
                mtx_unlock(&Giant);

-- 

John Baldwin <john@baldwin.cx> -- http://www.FreeBSD.org/~jhb/
PGP Key: http://www.baldwin.cx/~john/pgpkey.asc
"Power Users Use the Power to Serve!"  -  http://www.FreeBSD.org/

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?XFMail.010730124606.jhb>