Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 May 2012 11:35:19 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        freebsd-hackers@freebsd.org
Cc:        Ian Lepore <freebsd@damnhippie.dyndns.org>
Subject:   Re: Calling tsleep(9) with interrupts disabled
Message-ID:  <201205151135.19269.jhb@freebsd.org>
In-Reply-To: <1336493232.1503.29.camel@revolution.hippie.lan>
References:  <1336493232.1503.29.camel@revolution.hippie.lan>

next in thread | previous in thread | raw e-mail | index | archive | help
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



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