There is a bug in the msleep/endtsleep race workaround.  Please test the patch
at http://www.FreeBSD.org/~jhb/patches/timeout.patch

Index: kern/kern_condvar.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/kern_condvar.c,v
retrieving revision 1.11
diff -u -r1.11 kern_condvar.c
--- kern/kern_condvar.c 2001/07/06 01:16:42     1.11
+++ kern/kern_condvar.c 2001/08/21 17:57:08
@@ -345,8 +345,17 @@
        if (p->p_sflag & PS_TIMEOUT) {
                p->p_sflag &= ~PS_TIMEOUT;
                rval = EWOULDBLOCK;
-       } else
-               callout_stop(&p->p_slpcallout);
+       } else if (p->p_sflag & PS_TIMOFAIL)
+               p->p_sflag &= ~PS_TIMOFAIL;
+       } else if (callout_stop(&p->p_slpcallout) == 0) {
+               /*
+                * Work around race with cv_timedwait_end similar to that
+                * between msleep and endtsleep.
+                */
+               p->p_sflag |= PS_TIMEOUT;
+               p->p_stats->p_ru.ru_nivcsw++;
+               mi_switch();
+       }
 
        mtx_unlock_spin(&sched_lock);
 #ifdef KTRACE
@@ -407,8 +416,17 @@
        if (p->p_sflag & PS_TIMEOUT) {
                p->p_sflag &= ~PS_TIMEOUT;
                rval = EWOULDBLOCK;
-       } else
-               callout_stop(&p->p_slpcallout);
+       } else if (p->p_sflag & PS_TIMOFAIL)
+               p->p_sflag &= ~PS_TIMOFAIL;
+       } else if (callout_stop(&p->p_slpcallout) == 0) {
+               /*
+                * Work around race with cv_timedwait_end similar to that
+                * between msleep and endtsleep.
+                */
+               p->p_sflag |= PS_TIMEOUT;
+               p->p_stats->p_ru.ru_nivcsw++;
+               mi_switch();
+       }
 
        mtx_unlock_spin(&sched_lock);
        PICKUP_GIANT();
@@ -538,12 +556,16 @@
        CTR3(KTR_PROC, "cv_timedwait_end: proc %p (pid %d, %s)", p, p->p_pid,
            p->p_comm);
        mtx_lock_spin(&sched_lock);
-       if (p->p_wchan != NULL) {
+       if (p->p_sflag & PS_TIMEOUT) {
+               p->p_sflag &= ~PS_TIMEOUT;
+               setrunqueue(p);
+       } else if (p->p_wchan != NULL) {
                if (p->p_stat == SSLEEP)
                        setrunnable(p);
                else
                        cv_waitq_remove(p);
                p->p_sflag |= PS_TIMEOUT;
-       }
+       } else
+               p->p_sflag |= PS_TIMOFAIL;
        mtx_unlock_spin(&sched_lock);
 }
Index: kern/kern_synch.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/kern_synch.c,v
retrieving revision 1.155
diff -u -r1.155 kern_synch.c
--- kern/kern_synch.c   2001/08/10 22:53:28     1.155
+++ kern/kern_synch.c   2001/08/21 17:57:08
@@ -451,6 +455,8 @@
                p->p_sflag &= ~PS_TIMEOUT;
                if (sig == 0)
                        rval = EWOULDBLOCK;
+       } else if (p->p_sflag & PS_TIMOFAIL)
+               p->p_sflag &= ~PS_TIMOFAIL;
        } else if (timo && callout_stop(&p->p_slpcallout) == 0) {
                /*
                 * This isn't supposed to be pretty.  If we are here, then
@@ -524,7 +530,8 @@
                else
                        unsleep(p);
                p->p_sflag |= PS_TIMEOUT;
-       }
+       } else
+               p->p_sflag |= PS_TIMOFAIL;
        mtx_unlock_spin(&sched_lock);
 }
 
Index: sys/proc.h
===================================================================
RCS file: /usr/cvs/src/sys/sys/proc.h,v
retrieving revision 1.174
diff -u -r1.174 proc.h
--- sys/proc.h  2001/08/10 22:53:32     1.174
+++ sys/proc.h  2001/08/21 17:57:08
@@ -321,6 +321,7 @@
 #define        PS_SWAPPING     0x00200 /* Process is being swapped. */
 #define        PS_ASTPENDING   0x00400 /* Process has a pending ast. */
 #define        PS_NEEDRESCHED  0x00800 /* Process needs to yield. */
+#define        PS_TIMOFAIL     0x01000 /* Timeout from sleep after we were
awake. */
 
 #define        P_MAGIC         0xbeefface
 


-- 

John Baldwin <[EMAIL PROTECTED]> -- 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 [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to