Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Apr 2006 22:20:00 GMT
From:      Neel Natu <neelnatu@yahoo.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/95368: Test for race between callout_drain() and softclock() generates false positive
Message-ID:  <200604052220.k35MK0S0046058@www.freebsd.org>
Resent-Message-ID: <200604052220.k35MKH7u055039@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         95368
>Category:       kern
>Synopsis:       Test for race between callout_drain() and softclock() generates false positive
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Apr 05 22:20:17 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Neel Natu
>Release:        6.0-RELEASE
>Organization:
>Environment:
FreeBSD butternut.silverspringnet.com 6.0-RELEASE FreeBSD 6.0-RELEASE #0: Thu Nov  3 09:36:13 UTC 2005     root@x64.samsco.home:/usr/obj/usr/src/sys/GENERIC  i386
>Description:
This bug is applicable only on the 6.0 releng branch.


The check for race condition with softclock() will return positive even in the common case (i.e. when there is no race). This is because of the post-increment
operator on wakeup_ctr.

>From kern_timeout.c:
_callout_stop_safe()
{
                ...
                if (safe) {
                        /* We need to wait until the callout is finished. */
                        wakeup_needed = 1;
                        wakeup_cookie = wakeup_ctr++;
                        mtx_unlock_spin(&callout_lock);
                        mtx_lock(&callout_wait_lock);

                        /*
                         * Check to make sure that softclock() didn't
                         * do the wakeup in between our dropping
                         * callout_lock and picking up callout_wait_lock
                         */
                        if (wakeup_cookie - wakeup_done_ctr > 0)
                                cv_wait(&callout_wait, &callout_wait_lock);

                        mtx_unlock(&callout_wait_lock);
                 ...
}
>How-To-Repeat:

>Fix:
Index: kern_timeout.c
===================================================================
RCS file: /cvsroot/eng/gw/sys/kern/kern_timeout.c,v
retrieving revision 1.1.1.1.30.1
diff -u -r1.1.1.1.30.1 kern_timeout.c
--- kern_timeout.c      17 Feb 2006 04:23:15 -0000      1.1.1.1.30.1
+++ kern_timeout.c      5 Apr 2006 22:16:06 -0000
@@ -523,7 +523,7 @@
                if (safe) {
                        /* We need to wait until the callout is finished. */
                        wakeup_needed = 1;
-                       wakeup_cookie = wakeup_ctr++;
+                       wakeup_cookie = ++wakeup_ctr;
                        mtx_unlock_spin(&callout_lock);
                        mtx_lock(&callout_wait_lock);

>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200604052220.k35MK0S0046058>