On Tuesday, May 08, 2012 12:07:12 pm Ian Lepore wrote: > I just realized that I've accidentally coded a sequence similar to this > in a driver: > > s = intr_disable(); > // do stuff here > tsleep(sc, 0, "twird", hz / 4); > // more stuff > intr_restore(s); > > Much to my surpise this works, including waking up due to wakeup(sc) > being called from an interrupt handler. So apparently tsleep() results > in interrupts being re-enabled during the sleep, although nothing in the > manpage says that will happen. > > Can I safely rely on this behavior, or is it working by accident? > > (Please no lectures on the evils of disabling interrupts... This is not > a multi-GHz multi-core Xeon, it's a 180mhz embedded SoC with buggy > builtin devices that will drop or corrupt data if an interrupt happens > during the "do stuff here" part of the code.)
This happens to work because spinlock_enter/spinlock_exit also disable interrupts (so the new thread will re-enable interrupts when it resumes). However, if we switched spinlock_enter/exit to do something else in the future (e.g. to raise TPR as I have patches to do), then this would break. One option is to use spinlock_enter/exit instead of intr_disable/restore. However, you should probably just use a spin lock instead and use msleep_spin() instead of tsleep(). You can then use the spin lock in your filter interrupt handler around wakeup to prevent lost wakeups. Note that in a kernel without the SMP option, spin locks just devolve to spinlock_enter/exit anyway. -- John Baldwin _______________________________________________ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"