From owner-freebsd-current@FreeBSD.ORG Mon Mar 10 06:57:35 2008 Return-Path: Delivered-To: current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 85865106566B for ; Mon, 10 Mar 2008 06:57:35 +0000 (UTC) (envelope-from prvs=julian=9481976d6@ironport.com) Received: from smtp2-outbound.ironport.com (smtp2-outbound.ironport.com [63.251.108.116]) by mx1.freebsd.org (Postfix) with ESMTP id 82C138FC16 for ; Mon, 10 Mar 2008 06:57:35 +0000 (UTC) (envelope-from prvs=julian=9481976d6@ironport.com) DomainKey-Signature: s=key512; d=ironport.com; c=nofws; q=dns; h=Received:Message-ID:Date:From:User-Agent:MIME-Version:To: Subject:Content-Type; b=XkSkz+aV4qI9VWQaj+IVddRZ1KOwSNaH0/rSzIOk9q4GRnr1WZ8F6JvS uGnUhCzEj69fqPIiVMKX6qnOwTut6g==; Received: from unknown (HELO julian-mac.elischer.org) ([10.251.60.86]) by smtp2-outbound.ironport.com with ESMTP; 09 Mar 2008 23:29:01 -0700 Message-ID: <47D4D534.9050902@ironport.com> Date: Sun, 09 Mar 2008 23:29:08 -0700 From: Julian Elischer User-Agent: Thunderbird 2.0.0.12 (Macintosh/20080213) MIME-Version: 1.0 To: FreeBSD Current Content-Type: multipart/mixed; boundary="------------080604020403090608060201" X-Mailman-Approved-At: Mon, 10 Mar 2008 11:25:28 +0000 X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Cc: Subject: critical_exit() X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Mar 2008 06:57:35 -0000 This is a multi-part message in MIME format. --------------080604020403090608060201 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Why would the following: void critical_exit(void) { struct thread *td; td = curthread; KASSERT(td->td_critnest != 0, ("critical_exit: td_critnest == 0")); if (td->td_critnest == 1) { td->td_critnest = 0; if (td->td_owepreempt) { td->td_critnest = 1; thread_lock(td); td->td_critnest--; SCHED_STAT_INC(switch_owepreempt); mi_switch(SW_INVOL|SW_PREEMPT, NULL); thread_unlock(td); } } else td->td_critnest--; CTR4(KTR_CRITICAL, "critical_exit by thread %p (%ld, %s) to %d", td, (long)td->td_proc->p_pid, td->td_name, td->td_critnest); } not be expressed: void critical_exit(void) { struct thread *td; td = curthread; KASSERT(td->td_critnest != 0, ("critical_exit: td_critnest == 0")); if (td->td_critnest == 1) { if (td->td_owepreempt) { thread_lock(td); td->td_critnest = 0; SCHED_STAT_INC(switch_owepreempt); mi_switch(SW_INVOL|SW_PREEMPT, NULL); thread_unlock(td); } else { td_critnest = 0; } } else td->td_critnest--; CTR4(KTR_CRITICAL, "critical_exit by thread %p (%ld, %s) to %d", td, (long)td->td_proc->p_pid, td->td_name, td->td_critnest); } It seems to me there is a race in the current version, where the critical count is temporarily 0, where the thread could be pre-empted when it shouldn't be.. (prompted by a comment by jeffr that made me go look at this code).. --------------080604020403090608060201--