From owner-freebsd-hackers@FreeBSD.ORG Tue May 15 15:35:22 2012 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 55154106566C for ; Tue, 15 May 2012 15:35:22 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from bigwig.baldwin.cx (bigknife-pt.tunnel.tserv9.chi1.ipv6.he.net [IPv6:2001:470:1f10:75::2]) by mx1.freebsd.org (Postfix) with ESMTP id 2AF248FC15 for ; Tue, 15 May 2012 15:35:22 +0000 (UTC) Received: from jhbbsd.localnet (unknown [209.249.190.124]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id 89409B948; Tue, 15 May 2012 11:35:21 -0400 (EDT) From: John Baldwin To: freebsd-hackers@freebsd.org Date: Tue, 15 May 2012 11:35:19 -0400 User-Agent: KMail/1.13.5 (FreeBSD/8.2-CBSD-20110714-p13; KDE/4.5.5; amd64; ; ) References: <1336493232.1503.29.camel@revolution.hippie.lan> In-Reply-To: <1336493232.1503.29.camel@revolution.hippie.lan> MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <201205151135.19269.jhb@freebsd.org> X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.2.7 (bigwig.baldwin.cx); Tue, 15 May 2012 11:35:21 -0400 (EDT) Cc: Ian Lepore Subject: Re: Calling tsleep(9) with interrupts disabled X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 May 2012 15:35:22 -0000 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