From owner-freebsd-hackers Mon Jul 30 12:46:13 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from mail.wrs.com (unknown-1-11.windriver.com [147.11.1.11]) by hub.freebsd.org (Postfix) with ESMTP id C9AB737B401; Mon, 30 Jul 2001 12:46:06 -0700 (PDT) (envelope-from jhb@FreeBSD.org) Received: from laptop.baldwin.cx (john@[147.11.46.217]) by mail.wrs.com (8.9.3/8.9.1) with ESMTP id MAA27832; Mon, 30 Jul 2001 12:46:05 -0700 (PDT) Message-ID: X-Mailer: XFMail 1.4.0 on FreeBSD X-Priority: 3 (Normal) Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 8bit MIME-Version: 1.0 Date: Mon, 30 Jul 2001 12:46:06 -0700 (PDT) From: John Baldwin To: hackers@FreeBSD.org Subject: PATCH: Make ast's loop Cc: bde@FreeBSD.org Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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 -- 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