On Mon, 16 Aug 1999, Linus Torvalds wrote:

>So about half of your patch is unnecessary, but the latter half looks
>valid.

I checked the 2.3.13 kernel sources wrt the wait_event SMP race.
Here it is a fix against 2.3.13:

While checking all the scheduler-related code, I noticed that some driver
still mess with the scheduler setting counter to zero. I fixed them as
well (removed the line that zero the sched-counter).

diff -urN 2.3.13/arch/i386/kernel/apm.c 2.3.13-wait_event/arch/i386/kernel/apm.c
--- 2.3.13/arch/i386/kernel/apm.c       Thu Aug 12 02:53:17 1999
+++ 2.3.13-wait_event/arch/i386/kernel/apm.c    Tue Aug 17 19:49:59 1999
@@ -1078,6 +1078,7 @@
                add_wait_queue(&apm_waitqueue, &wait);
 repeat:
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (queue_empty(as) && !signal_pending(current)) {
                        schedule();
                        goto repeat;
diff -urN 2.3.13/arch/m68k/mac/adb-bus.c 2.3.13-wait_event/arch/m68k/mac/adb-bus.c
--- 2.3.13/arch/m68k/mac/adb-bus.c      Thu Aug 12 02:53:18 1999
+++ 2.3.13-wait_event/arch/m68k/mac/adb-bus.c   Tue Aug 17 21:01:33 1999
@@ -2336,6 +2336,7 @@
 
        add_wait_queue(&adb_wait, &wait);
        current->state = TASK_INTERRUPTIBLE;
+       mb();
 
        while (!state->req.got_reply) {
                if (file->f_flags & O_NONBLOCK) {
@@ -2564,6 +2565,7 @@
 
        add_wait_queue(&adb_wait, &wait);
        current->state = TASK_INTERRUPTIBLE;
+       mb();
 
        while (!state->req.got_reply) {
                if (file->f_flags & O_NONBLOCK) {
diff -urN 2.3.13/arch/mips/baget/vacserial.c 
2.3.13-wait_event/arch/mips/baget/vacserial.c
--- 2.3.13/arch/mips/baget/vacserial.c  Tue Jul 13 02:02:03 1999
+++ 2.3.13-wait_event/arch/mips/baget/vacserial.c       Tue Aug 17 19:53:20 1999
@@ -1778,7 +1778,6 @@
                baget_printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
 #endif
                current->state = TASK_INTERRUPTIBLE;
-               current->counter = 0;   /* make us low-priority */
                schedule_timeout(char_time);
                if (signal_pending(current))
                        break;
@@ -1904,6 +1903,7 @@
        info->blocked_open++;
        while (1) {
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) ||
                    !(info->flags & ASYNC_INITIALIZED)) {
 #ifdef SERIAL_DO_RESTART
diff -urN 2.3.13/arch/ppc/8xx_io/uart.c 2.3.13-wait_event/arch/ppc/8xx_io/uart.c
--- 2.3.13/arch/ppc/8xx_io/uart.c       Tue Jul 13 02:00:55 1999
+++ 2.3.13-wait_event/arch/ppc/8xx_io/uart.c    Tue Aug 17 19:54:56 1999
@@ -1688,7 +1688,6 @@
                printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
 #endif
                current->state = TASK_INTERRUPTIBLE;
-/*             current->counter = 0;    make us low-priority */
                schedule_timeout(char_time);
                if (signal_pending(current))
                        break;
@@ -1827,6 +1826,7 @@
                                   (UART_MCR_DTR | UART_MCR_RTS));
                sti();
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) ||
                    !(info->flags & ASYNC_INITIALIZED)) {
 #ifdef SERIAL_DO_RESTART
diff -urN 2.3.13/arch/sparc64/solaris/timod.c 
2.3.13-wait_event/arch/sparc64/solaris/timod.c
--- 2.3.13/arch/sparc64/solaris/timod.c Thu Aug 12 02:53:19 1999
+++ 2.3.13-wait_event/arch/sparc64/solaris/timod.c      Tue Aug 17 19:55:43 1999
@@ -678,6 +678,7 @@
                for(;;) {
                        SOLD("loop");
                        current->state = TASK_INTERRUPTIBLE;
+                       mb();
                        /* ! ( l<0 || ( l>=0 && ( ! pfirst || (flags == HIPRI && pri 
!= HIPRI) ) ) ) */ 
                        /* ( ! l<0 && ! ( l>=0 && ( ! pfirst || (flags == HIPRI && pri 
!= HIPRI) ) ) ) */ 
                        /* ( l>=0 && ( ! l>=0 || ! ( ! pfirst || (flags == HIPRI && 
pri != HIPRI) ) ) ) */ 
diff -urN 2.3.13/drivers/block/raid5.c 2.3.13-wait_event/drivers/block/raid5.c
--- 2.3.13/drivers/block/raid5.c        Tue Jul 13 02:02:07 1999
+++ 2.3.13-wait_event/drivers/block/raid5.c     Tue Aug 17 19:56:54 1999
@@ -98,6 +98,7 @@
        add_wait_queue(&sh->wait, &wait);
 repeat:
        current->state = TASK_UNINTERRUPTIBLE;
+       mb();
        if (stripe_locked(sh)) {
                schedule();
                goto repeat;
diff -urN 2.3.13/drivers/char/busmouse.c 2.3.13-wait_event/drivers/char/busmouse.c
--- 2.3.13/drivers/char/busmouse.c      Thu Aug 12 02:53:19 1999
+++ 2.3.13-wait_event/drivers/char/busmouse.c   Tue Aug 17 19:57:34 1999
@@ -274,6 +274,7 @@
                add_wait_queue(&mse->wait, &wait);
 repeat:
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (!mse->ready && !signal_pending(current)) {
                        spin_unlock_irqrestore(&mse->lock, flags);
                        schedule();
diff -urN 2.3.13/drivers/char/cyclades.c 2.3.13-wait_event/drivers/char/cyclades.c
--- 2.3.13/drivers/char/cyclades.c      Thu Aug 12 02:53:19 1999
+++ 2.3.13-wait_event/drivers/char/cyclades.c   Tue Aug 17 19:59:05 1999
@@ -2555,6 +2555,7 @@
            CY_UNLOCK(info, flags);
 
            current->state = TASK_INTERRUPTIBLE;
+           mb();
            if (tty_hung_up_p(filp)
            || !(info->flags & ASYNC_INITIALIZED) ){
                return ((info->flags & ASYNC_HUP_NOTIFY) ? 
@@ -2616,6 +2617,7 @@
 #endif
 
            current->state = TASK_INTERRUPTIBLE;
+           mb();
            if (tty_hung_up_p(filp)
            || !(info->flags & ASYNC_INITIALIZED) ){
                return ((info->flags & ASYNC_HUP_NOTIFY) ?
@@ -2851,7 +2853,6 @@
            printk("Not clean (jiff=%lu)...", jiffies);
 #endif
            current->state = TASK_INTERRUPTIBLE;
-           current->counter = 0;       /* make us low-priority */
            schedule_timeout(char_time);
            if (signal_pending(current))
                break;
@@ -2864,7 +2865,6 @@
     }
     /* Run one more char cycle */
     current->state = TASK_INTERRUPTIBLE;
-    current->counter = 0;      /* make us low-priority */
     schedule_timeout(char_time * 5);
     current->state = TASK_RUNNING;
 #ifdef CY_DEBUG_WAIT_UNTIL_SENT
diff -urN 2.3.13/drivers/char/dz.c 2.3.13-wait_event/drivers/char/dz.c
--- 2.3.13/drivers/char/dz.c    Tue Jul 13 02:02:25 1999
+++ 2.3.13-wait_event/drivers/char/dz.c Tue Aug 17 19:59:36 1999
@@ -1195,6 +1195,7 @@
   info->blocked_open++;
   while (1) {
     current->state = TASK_INTERRUPTIBLE;
+    mb();
     if (tty_hung_up_p (filp) || !(info->is_initialized)) {
       retval = -EAGAIN;
       break;
diff -urN 2.3.13/drivers/char/epca.c 2.3.13-wait_event/drivers/char/epca.c
--- 2.3.13/drivers/char/epca.c  Thu Aug 12 02:53:20 1999
+++ 2.3.13-wait_event/drivers/char/epca.c       Tue Aug 17 19:59:53 1999
@@ -1368,6 +1368,7 @@
        { /* Begin forever while  */
 
                current->state = TASK_INTERRUPTIBLE;
+               mb();
 
                if (tty_hung_up_p(filp) ||
                    !(ch->asyncflags & ASYNC_INITIALIZED)) 
diff -urN 2.3.13/drivers/char/esp.c 2.3.13-wait_event/drivers/char/esp.c
--- 2.3.13/drivers/char/esp.c   Tue Jul 13 02:02:25 1999
+++ 2.3.13-wait_event/drivers/char/esp.c        Tue Aug 17 20:00:18 1999
@@ -2318,6 +2318,7 @@
                }
                sti();
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) ||
                    !(info->flags & ASYNC_INITIALIZED)) {
 #ifdef SERIAL_DO_RESTART
diff -urN 2.3.13/drivers/char/ftape/lowlevel/ftape-io.c 
2.3.13-wait_event/drivers/char/ftape/lowlevel/ftape-io.c
--- 2.3.13/drivers/char/ftape/lowlevel/ftape-io.c       Mon Jan 18 02:28:22 1999
+++ 2.3.13-wait_event/drivers/char/ftape/lowlevel/ftape-io.c    Tue Aug 17 21:46:13 
+1999
@@ -96,18 +96,19 @@
                TRACE(ft_t_any, "%d msec, %d ticks", time/1000, ticks);
                timeout = ticks;
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                save_flags(flags);
                sti();
                do {
-                       while (current->state != TASK_RUNNING) {
-                               timeout = schedule_timeout(timeout);
-                       }
                        /*  Mmm. Isn't current->blocked == 0xffffffff ?
                         */
                        if (signal_pending(current)) {
                                TRACE(ft_t_err,
                                      "awoken by non-blocked signal :-(");
                                break;  /* exit on signal */
+                       }
+                       while (current->state != TASK_RUNNING) {
+                               timeout = schedule_timeout(timeout);
                        }
                } while (timeout);
                restore_flags(flags);
diff -urN 2.3.13/drivers/char/generic_serial.c 
2.3.13-wait_event/drivers/char/generic_serial.c
--- 2.3.13/drivers/char/generic_serial.c        Thu Aug 12 02:53:20 1999
+++ 2.3.13-wait_event/drivers/char/generic_serial.c     Tue Aug 17 20:00:27 1999
@@ -699,6 +699,7 @@
                CD = port->rd->get_CD (port);
                gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD);
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) ||
                    !(port->flags & ASYNC_INITIALIZED)) {
                        if (port->flags & ASYNC_HUP_NOTIFY)
diff -urN 2.3.13/drivers/char/isicom.c 2.3.13-wait_event/drivers/char/isicom.c
--- 2.3.13/drivers/char/isicom.c        Thu Aug 12 02:53:20 1999
+++ 2.3.13-wait_event/drivers/char/isicom.c     Tue Aug 17 20:00:51 1999
@@ -996,6 +996,7 @@
                
                sti();
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {       
 
                        if (port->flags & ASYNC_HUP_NOTIFY)
                                retval = -EAGAIN;
diff -urN 2.3.13/drivers/char/joystick/joystick.c 
2.3.13-wait_event/drivers/char/joystick/joystick.c
--- 2.3.13/drivers/char/joystick/joystick.c     Tue Jul 13 02:00:33 1999
+++ 2.3.13-wait_event/drivers/char/joystick/joystick.c  Tue Aug 17 21:33:08 1999
@@ -527,6 +527,7 @@
 
                        add_wait_queue(&jd->wait, &wait);
                        current->state = TASK_INTERRUPTIBLE;
+                       mb();
 
                        while (GOF(curl->tail) == jd->bhead) {
 
diff -urN 2.3.13/drivers/char/msp3400.c 2.3.13-wait_event/drivers/char/msp3400.c
--- 2.3.13/drivers/char/msp3400.c       Tue Jul 13 02:00:33 1999
+++ 2.3.13-wait_event/drivers/char/msp3400.c    Tue Aug 17 20:01:32 1999
@@ -796,8 +796,7 @@
 
                /* wait 1 sec */
                current->state = TASK_INTERRUPTIBLE;
-               current->timeout = jiffies + HZ;
-               schedule();
+               schedule_timeout(HZ);
                if (signal_pending(current))
                        goto done;
                if (msp->restart) {
diff -urN 2.3.13/drivers/char/n_tty.c 2.3.13-wait_event/drivers/char/n_tty.c
--- 2.3.13/drivers/char/n_tty.c Tue Jul 13 02:00:33 1999
+++ 2.3.13-wait_event/drivers/char/n_tty.c      Tue Aug 17 20:03:56 1999
@@ -953,6 +953,7 @@
                if (((minimum - (b - buf)) < tty->minimum_to_wake) &&
                    ((minimum - (b - buf)) >= 1))
                        tty->minimum_to_wake = (minimum - (b - buf));
+               mb();
                
                if (!input_available_p(tty, 0)) {
                        if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
@@ -1074,6 +1075,7 @@
        add_wait_queue(&tty->write_wait, &wait);
        while (1) {
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (signal_pending(current)) {
                        retval = -ERESTARTSYS;
                        break;
diff -urN 2.3.13/drivers/char/pc_keyb.c 2.3.13-wait_event/drivers/char/pc_keyb.c
--- 2.3.13/drivers/char/pc_keyb.c       Thu Aug 12 02:53:20 1999
+++ 2.3.13-wait_event/drivers/char/pc_keyb.c    Tue Aug 17 20:04:30 1999
@@ -873,6 +873,7 @@
                add_wait_queue(&queue->proc_list, &wait);
 repeat:
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (queue_empty() && !signal_pending(current)) {
                        schedule();
                        goto repeat;
diff -urN 2.3.13/drivers/char/pcxx.c 2.3.13-wait_event/drivers/char/pcxx.c
--- 2.3.13/drivers/char/pcxx.c  Thu Aug 12 02:53:20 1999
+++ 2.3.13-wait_event/drivers/char/pcxx.c       Tue Aug 17 20:04:38 1999
@@ -357,6 +357,7 @@
                }
                sti();
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if(tty_hung_up_p(filp) || (info->asyncflags & ASYNC_INITIALIZED) == 0) 
{
                        if(info->asyncflags & ASYNC_HUP_NOTIFY)
                                retval = -EAGAIN;
diff -urN 2.3.13/drivers/char/planb.c 2.3.13-wait_event/drivers/char/planb.c
--- 2.3.13/drivers/char/planb.c Thu Aug 12 02:53:20 1999
+++ 2.3.13-wait_event/drivers/char/planb.c      Tue Aug 17 20:05:00 1999
@@ -384,6 +384,7 @@
        add_wait_queue(&pb->lockq, &wait);
 repeat:
        current->state = TASK_UNINTERRUPTIBLE;
+       mb();
        if (pb->lock) {
                schedule();
                goto repeat;
diff -urN 2.3.13/drivers/char/qpmouse.c 2.3.13-wait_event/drivers/char/qpmouse.c
--- 2.3.13/drivers/char/qpmouse.c       Tue Jul 13 02:00:33 1999
+++ 2.3.13-wait_event/drivers/char/qpmouse.c    Tue Aug 17 20:05:08 1999
@@ -268,6 +268,7 @@
                add_wait_queue(&queue->proc_list, &wait);
 repeat:
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (queue_empty() && !signal_pending(current)) {
                        schedule();
                        goto repeat;
diff -urN 2.3.13/drivers/char/random.c 2.3.13-wait_event/drivers/char/random.c
--- 2.3.13/drivers/char/random.c        Tue Jul 13 02:00:33 1999
+++ 2.3.13-wait_event/drivers/char/random.c     Tue Aug 17 20:05:46 1999
@@ -1310,6 +1310,7 @@
        add_wait_queue(&random_read_wait, &wait);
        while (nbytes > 0) {
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                
                n = nbytes;
                if (n > random_state.entropy_count / 8)
diff -urN 2.3.13/drivers/char/riscom8.c 2.3.13-wait_event/drivers/char/riscom8.c
--- 2.3.13/drivers/char/riscom8.c       Thu Aug 12 02:53:20 1999
+++ 2.3.13-wait_event/drivers/char/riscom8.c    Tue Aug 17 20:06:18 1999
@@ -1028,6 +1028,7 @@
                }
                sti();
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) ||
                    !(port->flags & ASYNC_INITIALIZED)) {
                        if (port->flags & ASYNC_HUP_NOTIFY)
diff -urN 2.3.13/drivers/char/rocket.c 2.3.13-wait_event/drivers/char/rocket.c
--- 2.3.13/drivers/char/rocket.c        Thu Aug 12 02:53:20 1999
+++ 2.3.13-wait_event/drivers/char/rocket.c     Tue Aug 17 20:06:34 1999
@@ -891,6 +891,7 @@
                        sSetRTS(&info->channel);
                }
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) ||
                    !(info->flags & ROCKET_INITIALIZED)) {
                        if (info->flags & ROCKET_HUP_NOTIFY)
diff -urN 2.3.13/drivers/char/selection.c 2.3.13-wait_event/drivers/char/selection.c
--- 2.3.13/drivers/char/selection.c     Tue Jul 13 02:00:33 1999
+++ 2.3.13-wait_event/drivers/char/selection.c  Tue Aug 17 20:08:50 1999
@@ -302,6 +302,7 @@
        add_wait_queue(&vt->paste_wait, &wait);
        while (sel_buffer && sel_buffer_lth > pasted) {
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (test_bit(TTY_THROTTLED, &tty->flags)) {
                        schedule();
                        continue;
diff -urN 2.3.13/drivers/char/serial.c 2.3.13-wait_event/drivers/char/serial.c
--- 2.3.13/drivers/char/serial.c        Tue Jul 13 02:02:25 1999
+++ 2.3.13-wait_event/drivers/char/serial.c     Tue Aug 17 20:09:42 1999
@@ -2512,6 +2512,7 @@
                                   (UART_MCR_DTR | UART_MCR_RTS));
                restore_flags(flags);
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) ||
                    !(info->flags & ASYNC_INITIALIZED)) {
 #ifdef SERIAL_DO_RESTART
diff -urN 2.3.13/drivers/char/serial167.c 2.3.13-wait_event/drivers/char/serial167.c
--- 2.3.13/drivers/char/serial167.c     Tue Jul 13 02:00:56 1999
+++ 2.3.13-wait_event/drivers/char/serial167.c  Tue Aug 17 20:09:24 1999
@@ -2095,6 +2095,7 @@
            }
        restore_flags(flags);
        current->state = TASK_INTERRUPTIBLE;
+       mb();
        if (tty_hung_up_p(filp)
        || !(info->flags & ASYNC_INITIALIZED) ){
            if (info->flags & ASYNC_HUP_NOTIFY) {
diff -urN 2.3.13/drivers/char/specialix.c 2.3.13-wait_event/drivers/char/specialix.c
--- 2.3.13/drivers/char/specialix.c     Tue Jul 13 02:00:34 1999
+++ 2.3.13-wait_event/drivers/char/specialix.c  Tue Aug 17 20:09:52 1999
@@ -1399,6 +1399,7 @@
                }
                sti();
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) ||
                    !(port->flags & ASYNC_INITIALIZED)) {
                        if (port->flags & ASYNC_HUP_NOTIFY)
diff -urN 2.3.13/drivers/char/synclink.c 2.3.13-wait_event/drivers/char/synclink.c
--- 2.3.13/drivers/char/synclink.c      Tue Jul 13 02:01:52 1999
+++ 2.3.13-wait_event/drivers/char/synclink.c   Tue Aug 17 20:11:20 1999
@@ -3413,7 +3413,6 @@
        if ( info->params.mode == MGSL_MODE_HDLC ) {
                while (info->tx_active) {
                        current->state = TASK_INTERRUPTIBLE;
-                       current->counter = 0;   /* make us low-priority */
                        schedule_timeout(char_time);
                        if (signal_pending(current))
                                break;
@@ -3424,7 +3423,6 @@
                while (!(usc_InReg(info,TCSR) & TXSTATUS_ALL_SENT) &&
                        info->tx_enabled) {
                        current->state = TASK_INTERRUPTIBLE;
-                       current->counter = 0;   /* make us low-priority */
                        schedule_timeout(char_time);
                        if (signal_pending(current))
                                break;
@@ -3562,6 +3560,7 @@
                }
                
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                
                if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)){
                        retval = (info->flags & ASYNC_HUP_NOTIFY) ?
diff -urN 2.3.13/drivers/char/tty_io.c 2.3.13-wait_event/drivers/char/tty_io.c
--- 2.3.13/drivers/char/tty_io.c        Thu Aug 12 02:53:20 1999
+++ 2.3.13-wait_event/drivers/char/tty_io.c     Tue Aug 17 20:13:16 1999
@@ -1632,6 +1632,7 @@
 static int send_break(struct tty_struct *tty, int duration)
 {
        current->state = TASK_INTERRUPTIBLE;
+       mb(); /* don't miss the signal wakeup */
 
        tty->driver.break_ctl(tty, -1);
        if (!signal_pending(current))
diff -urN 2.3.13/drivers/char/tty_ioctl.c 2.3.13-wait_event/drivers/char/tty_ioctl.c
--- 2.3.13/drivers/char/tty_ioctl.c     Tue Jul 13 02:00:34 1999
+++ 2.3.13-wait_event/drivers/char/tty_ioctl.c  Tue Aug 17 20:13:49 1999
@@ -60,6 +60,7 @@
                       tty->driver.chars_in_buffer(tty));
 #endif
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (signal_pending(current))
                        goto stop_waiting;
                if (!tty->driver.chars_in_buffer(tty))
diff -urN 2.3.13/drivers/char/vt.c 2.3.13-wait_event/drivers/char/vt.c
--- 2.3.13/drivers/char/vt.c    Thu Jul 22 01:07:25 1999
+++ 2.3.13-wait_event/drivers/char/vt.c Tue Aug 17 20:14:09 1999
@@ -1114,6 +1114,7 @@
        add_wait_queue(&vt_activate_queue, &wait);
        for (;;) {
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                retval = 0;
                if (vt == fg_console)
                        break;
diff -urN 2.3.13/drivers/isdn/isdn_tty.c 2.3.13-wait_event/drivers/isdn/isdn_tty.c
--- 2.3.13/drivers/isdn/isdn_tty.c      Tue Jul 13 02:01:19 1999
+++ 2.3.13-wait_event/drivers/isdn/isdn_tty.c   Tue Aug 17 20:14:18 1999
@@ -1947,6 +1947,7 @@
        info->blocked_open++;
        while (1) {
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) ||
                    !(info->flags & ISDN_ASYNC_INITIALIZED)) {
 #ifdef MODEM_DO_RESTART
diff -urN 2.3.13/drivers/macintosh/macserial.c 
2.3.13-wait_event/drivers/macintosh/macserial.c
--- 2.3.13/drivers/macintosh/macserial.c        Thu Aug 12 02:53:20 1999
+++ 2.3.13-wait_event/drivers/macintosh/macserial.c     Tue Aug 17 20:17:16 1999
@@ -1676,6 +1676,7 @@
                        zs_rtsdtr(info, 1);
                sti();
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) ||
                    !(info->flags & ZILOG_INITIALIZED)) {
 #ifdef SERIAL_DO_RESTART
diff -urN 2.3.13/drivers/net/cosa.c 2.3.13-wait_event/drivers/net/cosa.c
--- 2.3.13/drivers/net/cosa.c   Tue Jul 13 02:02:31 1999
+++ 2.3.13-wait_event/drivers/net/cosa.c        Tue Aug 17 20:17:55 1999
@@ -1558,7 +1558,6 @@
                /* sleep if not ready to read */
                current->state = TASK_INTERRUPTIBLE;
                schedule_timeout(1);
-               current->state = TASK_RUNNING;
        }
        printk(KERN_INFO "cosa: timeout in get_wait_data (status 0x%x)\n",
                cosa_getstatus(cosa));
@@ -1586,7 +1585,6 @@
                /* sleep if not ready to read */
                current->state = TASK_INTERRUPTIBLE;
                schedule_timeout(1);
-               current->state = TASK_RUNNING;
 #endif
        }
        printk(KERN_INFO "cosa%d: timeout in put_wait_data (status 0x%x)\n",
diff -urN 2.3.13/drivers/net/cycx_drv.c 2.3.13-wait_event/drivers/net/cycx_drv.c
--- 2.3.13/drivers/net/cycx_drv.c       Tue Jul 13 02:02:09 1999
+++ 2.3.13-wait_event/drivers/net/cycx_drv.c    Tue Aug 17 20:18:05 1999
@@ -639,7 +639,6 @@
    know it all the contexts where this routine is used are interruptible... */
 
        current->state = TASK_INTERRUPTIBLE;
-       current->counter = 0;       /* make us low-priority */
        schedule_timeout(sec*HZ);
 }
 
diff -urN 2.3.13/drivers/sbus/char/aurora.c 
2.3.13-wait_event/drivers/sbus/char/aurora.c
--- 2.3.13/drivers/sbus/char/aurora.c   Tue Jul 13 02:02:09 1999
+++ 2.3.13-wait_event/drivers/sbus/char/aurora.c        Tue Aug 17 21:35:23 1999
@@ -1328,6 +1328,7 @@
                }
                sti();
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) ||
                    !(port->flags & ASYNC_INITIALIZED)) {
                        if (port->flags & ASYNC_HUP_NOTIFY)
diff -urN 2.3.13/drivers/sbus/char/pcikbd.c 
2.3.13-wait_event/drivers/sbus/char/pcikbd.c
--- 2.3.13/drivers/sbus/char/pcikbd.c   Tue Jul 13 02:01:38 1999
+++ 2.3.13-wait_event/drivers/sbus/char/pcikbd.c        Tue Aug 17 21:35:35 1999
@@ -894,6 +894,7 @@
                add_wait_queue(&queue->proc_list, &wait);
 repeat:
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (queue_empty() && !signal_pending(current)) {
                        schedule();
                        goto repeat;
diff -urN 2.3.13/drivers/sbus/char/sab82532.c 
2.3.13-wait_event/drivers/sbus/char/sab82532.c
--- 2.3.13/drivers/sbus/char/sab82532.c Tue Jul 13 02:02:34 1999
+++ 2.3.13-wait_event/drivers/sbus/char/sab82532.c      Tue Aug 17 21:35:50 1999
@@ -1803,6 +1803,7 @@
                }
                sti();
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) ||
                    !(info->flags & ASYNC_INITIALIZED)) {
 #ifdef SERIAL_DO_RESTART
diff -urN 2.3.13/drivers/sbus/char/su.c 2.3.13-wait_event/drivers/sbus/char/su.c
--- 2.3.13/drivers/sbus/char/su.c       Tue Jul 13 02:02:34 1999
+++ 2.3.13-wait_event/drivers/sbus/char/su.c    Tue Aug 17 21:36:04 1999
@@ -1966,6 +1966,7 @@
                                   (UART_MCR_DTR | UART_MCR_RTS));
                restore_flags(flags);
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) ||
                    !(info->flags & ASYNC_INITIALIZED)) {
 #ifdef SERIAL_DO_RESTART
diff -urN 2.3.13/drivers/sbus/char/zs.c 2.3.13-wait_event/drivers/sbus/char/zs.c
--- 2.3.13/drivers/sbus/char/zs.c       Thu Aug 12 02:53:21 1999
+++ 2.3.13-wait_event/drivers/sbus/char/zs.c    Tue Aug 17 21:36:20 1999
@@ -1712,6 +1712,7 @@
                        zs_rtsdtr(info, 1);
                sti();
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) ||
                    !(info->flags & ZILOG_INITIALIZED)) {
 #ifdef SERIAL_DEBUG_OPEN
diff -urN 2.3.13/drivers/scsi/scsi.h 2.3.13-wait_event/drivers/scsi/scsi.h
--- 2.3.13/drivers/scsi/scsi.h  Tue Aug 17 16:14:50 1999
+++ 2.3.13-wait_event/drivers/scsi/scsi.h       Tue Aug 17 21:52:33 1999
@@ -716,6 +716,7 @@
        add_wait_queue(QUEUE, &wait);               \
        for(;;) {                                   \
        current->state = TASK_UNINTERRUPTIBLE;      \
+       mb();                                       \
        if (CONDITION) {                            \
             if (in_interrupt())                            \
                panic("scsi: trying to call schedule() in interrupt" \
diff -urN 2.3.13/drivers/sgi/char/sgiserial.c 
2.3.13-wait_event/drivers/sgi/char/sgiserial.c
--- 2.3.13/drivers/sgi/char/sgiserial.c Tue Jul 13 02:02:09 1999
+++ 2.3.13-wait_event/drivers/sgi/char/sgiserial.c      Tue Aug 17 21:36:42 1999
@@ -1592,6 +1592,7 @@
                        zs_rtsdtr(info, 1);
                sti();
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) ||
                    !(info->flags & ZILOG_INITIALIZED)) {
 #ifdef SERIAL_DO_RESTART
diff -urN 2.3.13/drivers/tc/zs.c 2.3.13-wait_event/drivers/tc/zs.c
--- 2.3.13/drivers/tc/zs.c      Tue Jul 13 02:02:09 1999
+++ 2.3.13-wait_event/drivers/tc/zs.c   Tue Aug 17 20:21:17 1999
@@ -1315,7 +1315,6 @@
                char_time = MIN(char_time, timeout);
        while ((read_zsreg(info->zs_channel, 1) & ALL_SNT) == 0) {
                current->state = TASK_INTERRUPTIBLE;
-               current->counter = 0;   /* make us low-priority */
                schedule_timeout(char_time);
                if (signal_pending(current))
                        break;
@@ -1434,6 +1433,7 @@
                        zs_rtsdtr(info, 1);
                sti();
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (tty_hung_up_p(filp) ||
                    !(info->flags & ZILOG_INITIALIZED)) {
 #ifdef SERIAL_DO_RESTART
diff -urN 2.3.13/fs/buffer.c 2.3.13-wait_event/fs/buffer.c
--- 2.3.13/fs/buffer.c  Thu Aug 12 02:53:23 1999
+++ 2.3.13-wait_event/fs/buffer.c       Tue Aug 17 18:37:46 1999
@@ -146,8 +146,9 @@
        atomic_inc(&bh->b_count);
        add_wait_queue(&bh->b_wait, &wait);
 repeat:
-       tsk->state = TASK_UNINTERRUPTIBLE;
        run_task_queue(&tq_disk);
+       tsk->state = TASK_UNINTERRUPTIBLE;
+       mb();
        if (buffer_locked(bh)) {
                schedule();
                goto repeat;
@@ -1108,7 +1109,6 @@
  */
 static struct buffer_head * create_buffers(unsigned long page, unsigned long size, 
int async)
 {
-       DECLARE_WAITQUEUE(wait, current);
        struct buffer_head *bh, *head;
        long offset;
 
@@ -1174,14 +1174,7 @@
         * Set our state for sleeping, then check again for buffer heads.
         * This ensures we won't miss a wake_up from an interrupt.
         */
-       add_wait_queue(&buffer_wait, &wait);
-       current->state = TASK_UNINTERRUPTIBLE;
-       if (nr_unused_buffer_heads < MAX_BUF_PER_PAGE) {
-               current->policy |= SCHED_YIELD;
-               schedule();
-       }
-       remove_wait_queue(&buffer_wait, &wait);
-       current->state = TASK_RUNNING;
+       wait_event(buffer_wait, nr_unused_buffer_heads >= MAX_BUF_PER_PAGE);
        goto try_again;
 }
 
diff -urN 2.3.13/fs/coda/upcall.c 2.3.13-wait_event/fs/coda/upcall.c
--- 2.3.13/fs/coda/upcall.c     Tue Jul 13 02:02:40 1999
+++ 2.3.13-wait_event/fs/coda/upcall.c  Tue Aug 17 19:05:50 1999
@@ -628,6 +628,7 @@
                        current->state = TASK_INTERRUPTIBLE;
                else
                        current->state = TASK_UNINTERRUPTIBLE;
+               mb();
 
                /* got a reply */
                if ( vmp->uc_flags & REQ_WRITE )
diff -urN 2.3.13/fs/dquot.c 2.3.13-wait_event/fs/dquot.c
--- 2.3.13/fs/dquot.c   Tue Jul 13 02:02:40 1999
+++ 2.3.13-wait_event/fs/dquot.c        Tue Aug 17 18:38:49 1999
@@ -200,6 +200,7 @@
        add_wait_queue(&dquot->dq_wait, &wait);
 repeat:
        current->state = TASK_UNINTERRUPTIBLE;
+       mb();
        if (dquot->dq_flags & DQ_LOCKED) {
                schedule();
                goto repeat;
diff -urN 2.3.13/fs/inode.c 2.3.13-wait_event/fs/inode.c
--- 2.3.13/fs/inode.c   Tue Jul 13 02:02:40 1999
+++ 2.3.13-wait_event/fs/inode.c        Tue Aug 17 18:38:56 1999
@@ -104,6 +104,7 @@
        add_wait_queue(&inode->i_wait, &wait);
 repeat:
        current->state = TASK_UNINTERRUPTIBLE;
+       mb();
        if (inode->i_state & I_LOCK) {
                schedule();
                goto repeat;
diff -urN 2.3.13/fs/iobuf.c 2.3.13-wait_event/fs/iobuf.c
--- 2.3.13/fs/iobuf.c   Sun Aug  1 18:11:17 1999
+++ 2.3.13-wait_event/fs/iobuf.c        Tue Aug 17 18:39:14 1999
@@ -122,8 +122,9 @@
 
        add_wait_queue(&kiobuf->wait_queue, &wait);
 repeat:
-       tsk->state = TASK_UNINTERRUPTIBLE;
        run_task_queue(&tq_disk);
+       tsk->state = TASK_UNINTERRUPTIBLE;
+       mb();
        if (atomic_read(&kiobuf->io_count) != 0) {
                schedule();
                goto repeat;
diff -urN 2.3.13/fs/ncpfs/sock.c 2.3.13-wait_event/fs/ncpfs/sock.c
--- 2.3.13/fs/ncpfs/sock.c      Tue Jul 13 02:00:52 1999
+++ 2.3.13-wait_event/fs/ncpfs/sock.c   Tue Aug 17 19:24:46 1999
@@ -173,6 +173,9 @@
                wait_table.nr = 0;
                wait_table.entry = &entry;
                current->state = TASK_INTERRUPTIBLE;
+               /* mb() is not necessary because ->poll() will serialize
+                  instructions adding the wait_table waitqueues in the
+                  waitqueue-head before going to calculate the mask-retval. */
                if (!(file->f_op->poll(file, &wait_table) & POLLIN)) {
                        int timed_out;
                        if (timeout > max_timeout) {
diff -urN 2.3.13/fs/nfs/write.c 2.3.13-wait_event/fs/nfs/write.c
--- 2.3.13/fs/nfs/write.c       Tue Jul 13 02:02:40 1999
+++ 2.3.13-wait_event/fs/nfs/write.c    Tue Aug 17 19:25:15 1999
@@ -393,6 +393,7 @@
        add_wait_queue(&req->wb_wait, &wait);
        for (;;) {
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                retval = 0;
                if (req->wb_flags & NFS_WRITE_COMPLETE)
                        break;
diff -urN 2.3.13/fs/select.c 2.3.13-wait_event/fs/select.c
--- 2.3.13/fs/select.c  Sun Aug  1 18:11:17 1999
+++ 2.3.13-wait_event/fs/select.c       Tue Aug 17 19:22:30 1999
@@ -175,6 +175,7 @@
        retval = 0;
        for (;;) {
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                for (i = 0 ; i < n; i++) {
                        unsigned long bit = BIT(i);
                        unsigned long mask;
@@ -338,6 +339,7 @@
                struct pollfd * fdpnt;
 
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                for (fdpnt = fds, j = 0; j < nfds; j++, fdpnt++) {
                        int fd;
                        unsigned int mask;
diff -urN 2.3.13/fs/super.c 2.3.13-wait_event/fs/super.c
--- 2.3.13/fs/super.c   Thu Aug 12 02:53:24 1999
+++ 2.3.13-wait_event/fs/super.c        Tue Aug 17 18:41:33 1999
@@ -418,6 +418,7 @@
        add_wait_queue(&sb->s_wait, &wait);
 repeat:
        current->state = TASK_UNINTERRUPTIBLE;
+       mb();
        if (sb->s_lock) {
                schedule();
                goto repeat;
diff -urN 2.3.13/include/linux/sched.h 2.3.13-wait_event/include/linux/sched.h
--- 2.3.13/include/linux/sched.h        Tue Aug 17 16:51:44 1999
+++ 2.3.13-wait_event/include/linux/sched.h     Tue Aug 17 18:34:07 1999
@@ -716,6 +716,7 @@
        add_wait_queue(&wq, &__wait);                                   \
        for (;;) {                                                      \
                current->state = TASK_UNINTERRUPTIBLE;                  \
+               mb();                                                   \
                if (condition)                                          \
                        break;                                          \
                schedule();                                             \
@@ -739,6 +740,7 @@
        add_wait_queue(&wq, &__wait);                                   \
        for (;;) {                                                      \
                current->state = TASK_INTERRUPTIBLE;                    \
+               mb();                                                   \
                if (condition)                                          \
                        break;                                          \
                if (!signal_pending(current)) {                         \
diff -urN 2.3.13/mm/filemap.c 2.3.13-wait_event/mm/filemap.c
--- 2.3.13/mm/filemap.c Thu Aug 12 02:53:25 1999
+++ 2.3.13-wait_event/mm/filemap.c      Tue Aug 17 18:49:20 1999
@@ -549,8 +549,9 @@
 
        add_wait_queue(&page->wait, &wait);
        do {
-               tsk->state = TASK_UNINTERRUPTIBLE;
                run_task_queue(&tq_disk);
+               tsk->state = TASK_UNINTERRUPTIBLE;
+               mb();
                if (!PageLocked(page))
                        break;
                schedule();
@@ -564,23 +565,8 @@
  */
 void lock_page(struct page *page)
 {
-       if (TryLockPage(page)) {
-               struct task_struct *tsk = current;
-               DECLARE_WAITQUEUE(wait, current);
-
-               run_task_queue(&tq_disk);
-               add_wait_queue(&page->wait, &wait);
-               tsk->state = TASK_UNINTERRUPTIBLE;
-
-               while (TryLockPage(page)) {
-                       run_task_queue(&tq_disk);
-                       schedule();
-                       tsk->state = TASK_UNINTERRUPTIBLE;
-               }
-
-               remove_wait_queue(&page->wait, &wait);
-               tsk->state = TASK_RUNNING;
-       }
+       while (TryLockPage(page))
+               ___wait_on_page(page);
 }
 
 
@@ -609,10 +595,11 @@
                struct task_struct *tsk = current;
                DECLARE_WAITQUEUE(wait, tsk);
 
+               run_task_queue(&tq_disk);
+
                add_wait_queue(&page->wait, &wait);
                tsk->state = TASK_UNINTERRUPTIBLE;
-
-               run_task_queue(&tq_disk);
+               mb();
                if (PageLocked(page))
                        schedule();
                tsk->state = TASK_RUNNING;
@@ -658,10 +645,11 @@
                struct task_struct *tsk = current;
                DECLARE_WAITQUEUE(wait, tsk);
 
+               run_task_queue(&tq_disk);
+
                add_wait_queue(&page->wait, &wait);
                tsk->state = TASK_UNINTERRUPTIBLE;
-
-               run_task_queue(&tq_disk);
+               mb();
                if (PageLocked(page))
                        schedule();
                tsk->state = TASK_RUNNING;
diff -urN 2.3.13/net/core/datagram.c 2.3.13-wait_event/net/core/datagram.c
--- 2.3.13/net/core/datagram.c  Tue Jul 13 02:01:30 1999
+++ 2.3.13-wait_event/net/core/datagram.c       Tue Aug 17 21:58:04 1999
@@ -58,6 +58,7 @@
 
        add_wait_queue(sk->sleep, &wait);
        current->state = TASK_INTERRUPTIBLE;
+       mb();
 
        if (skb_peek(&sk->receive_queue) == NULL)
                schedule();
diff -urN 2.3.13/net/core/sock.c 2.3.13-wait_event/net/core/sock.c
--- 2.3.13/net/core/sock.c      Tue Jul 13 02:01:20 1999
+++ 2.3.13-wait_event/net/core/sock.c   Tue Aug 17 18:50:33 1999
@@ -658,6 +658,7 @@
                if (signal_pending(current))
                        break;
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                if (atomic_read(&sk->wmem_alloc) < sk->sndbuf)
                        break;
                if (sk->shutdown & SEND_SHUTDOWN)
diff -urN 2.3.13/net/ipv4/af_inet.c 2.3.13-wait_event/net/ipv4/af_inet.c
--- 2.3.13/net/ipv4/af_inet.c   Tue Jul 13 02:02:40 1999
+++ 2.3.13-wait_event/net/ipv4/af_inet.c        Tue Aug 17 18:51:20 1999
@@ -582,6 +582,7 @@
 
        add_wait_queue(sk->sleep, &wait);
        current->state = TASK_INTERRUPTIBLE;
+       mb();
        while (sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV) {
                if (signal_pending(current))
                        break;
@@ -589,6 +590,7 @@
                        break;
                schedule();
                current->state = TASK_INTERRUPTIBLE;
+               mb();
        }
        current->state = TASK_RUNNING;
        remove_wait_queue(sk->sleep, &wait);
diff -urN 2.3.13/net/ipv4/tcp.c 2.3.13-wait_event/net/ipv4/tcp.c
--- 2.3.13/net/ipv4/tcp.c       Tue Jul 13 02:02:40 1999
+++ 2.3.13-wait_event/net/ipv4/tcp.c    Tue Aug 17 19:01:39 1999
@@ -681,6 +681,9 @@
 
                tsk->state = TASK_INTERRUPTIBLE;
                add_wait_queue(sk->sleep, &wait);
+               /* release_sock() grab the slock spinlock so it will serialize
+                  instruction and we'll flush to memory the
+                  TASK_INTERRUPTIBLE state before reading the sk->state. */
                release_sock(sk);
 
                if (((1 << sk->state) & ~(TCPF_ESTABLISHED|TCPF_CLOSE_WAIT)) &&
@@ -716,6 +719,7 @@
                        if (signal_pending(current))
                                break;
                        current->state = TASK_INTERRUPTIBLE;
+                       mb();
                        if (tcp_memory_free(sk))
                                break;
                        if (sk->shutdown & SEND_SHUTDOWN)
@@ -1186,6 +1190,7 @@
 
                /* Next get a buffer. */
                current->state = TASK_INTERRUPTIBLE;
+               mb();
 
                skb = skb_peek(&sk->receive_queue);
                do {
@@ -1542,6 +1547,7 @@
 
                while (1) {
                        tsk->state = TASK_INTERRUPTIBLE;
+                       mb();
                        if (!closing(sk))
                                break;
                        release_sock(sk);
diff -urN 2.3.13/net/irda/ircomm/irvtd_driver.c 
2.3.13-wait_event/net/irda/ircomm/irvtd_driver.c
--- 2.3.13/net/irda/ircomm/irvtd_driver.c       Tue Jul 13 02:01:42 1999
+++ 2.3.13-wait_event/net/irda/ircomm/irvtd_driver.c    Tue Aug 17 19:47:50 1999
@@ -693,6 +693,7 @@
        /* wait for a connection established */
        while (1) {
                current->state = TASK_INTERRUPTIBLE;
+               mb();
                
                if (tty_hung_up_p(filp) ||
                    !(driver->flags & ASYNC_INITIALIZED)) {
@@ -995,7 +996,6 @@
        while (driver->comm->tsap->disconnect_pend) {
                DEBUG(1, __FUNCTION__"():wait..\n");
                current->state = TASK_INTERRUPTIBLE;
-               current->counter = 0;   /* make us low-priority */
                schedule_timeout(HZ);    /* 1sec */
                if (signal_pending(current))
                        break;
@@ -1530,11 +1530,8 @@
 #ifdef IRVTD_DEBUG_IOCTL
        {
                /* kill time so that debug messages will come slowly  */
-               save_flags(flags);cli();
                current->state = TASK_INTERRUPTIBLE;
-               current->timeout = jiffies + HZ/4; /*0.25sec*/
-               schedule();
-               restore_flags(flags);
+               schedule_timeout(HZ/4); /*0.25sec*/
        }
 #endif
 
diff -urN 2.3.13/net/netlink/af_netlink.c 2.3.13-wait_event/net/netlink/af_netlink.c
--- 2.3.13/net/netlink/af_netlink.c     Tue Jul 13 02:01:30 1999
+++ 2.3.13-wait_event/net/netlink/af_netlink.c  Tue Aug 17 19:03:27 1999
@@ -352,6 +352,7 @@
                if (!nonblock) {
                        add_wait_queue(sk->sleep, &wait);
                        current->state = TASK_INTERRUPTIBLE;
+                       mb();
                }
 
                if (atomic_read(&sk->rmem_alloc) > sk->rcvbuf) {


Andrea

-
Linux SMP list: FIRST see FAQ at http://www.irisa.fr/prive/mentre/smp-faq/
To Unsubscribe: send "unsubscribe linux-smp" to [EMAIL PROTECTED]

Reply via email to