Skip site navigation (1)Skip section navigation (2)
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>