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>