Date: Sun, 09 Mar 2008 23:29:08 -0700 From: Julian Elischer <julian@ironport.com> To: FreeBSD Current <current@freebsd.org> Subject: critical_exit() Message-ID: <47D4D534.9050902@ironport.com>
next in thread | raw e-mail | index | archive | help
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--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?47D4D534.9050902>