the other places that do this:
net/ax25/af_ax25.c
net/x25/af_x25.c
net/rose/af_rose.c
net/irda/ircomm/irvtd_driver.c
(this one is not obvious: irvtd_close() leaks a cli() into
tty_ioctl.c:tty_wait_until_sent(), which does
sched.c:add_wait_queue(), dang.)
net/irda/af_irda.c, 2 places
net/irda/irmod.c, 1 place
net/ipx/af_spx.c, 3 places.
i've checked all other uses of sleep_on*(), and the rest seems to be safe.
On SMP it's not safe and not raceless to use sleep_on*() for asynchronous
events. I've attached a patch that tries to avoid the worst (the hang, but
not the wakeup race) and prints a warning.
-- mingo
--- linux/kernel/sched.c.orig2 Tue Mar 2 11:08:56 1999
+++ linux/kernel/sched.c Tue Mar 2 11:09:58 1999
@@ -948,8 +948,20 @@
return waking_non_zero_trylock(sem);
}
+static void check_irq (void)
+{
+ unsigned long flags;
+
+ __save_flags(flags);
+ if (!(flags & (1 << EFLAGS_IF_SHIFT))) {
+ show("bug: interrupts are off, should be on!");
+ sti();
+ }
+}
+
#define SLEEP_ON_VAR \
- struct wait_queue wait;
+ struct wait_queue wait; \
+ check_irq();
#define SLEEP_ON_HEAD \
wait.task = current; \
--- linux/arch/i386/kernel/irq.c.orig Mon Mar 1 12:25:36 1999
+++ linux/arch/i386/kernel/irq.c Mon Mar 1 12:25:43 1999
@@ -467,7 +467,7 @@
}
}
-static void show(char * str)
+void show(char * str)
{
int i;
unsigned long *stack;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/