From owner-svn-src-head@freebsd.org Thu Nov 19 19:16:37 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 103EEA33FF2; Thu, 19 Nov 2015 19:16:37 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from bigwig.baldwin.cx (bigwig.baldwin.cx [IPv6:2001:470:1f11:75::1]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C8BB41A4A; Thu, 19 Nov 2015 19:16:36 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from ralph.baldwin.cx (c-73-231-226-104.hsd1.ca.comcast.net [73.231.226.104]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id DDE61B9C2; Thu, 19 Nov 2015 14:16:35 -0500 (EST) From: John Baldwin To: "Jonathan T. Looney" Cc: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r291074 - in head: share/man/man9 sys/kern sys/vm Date: Thu, 19 Nov 2015 09:58:45 -0800 Message-ID: <8452745.P4SYfkWpxv@ralph.baldwin.cx> User-Agent: KMail/4.14.3 (FreeBSD/10.2-STABLE; KDE/4.14.3; amd64; ; ) In-Reply-To: <201511191404.tAJE4reJ064779@repo.freebsd.org> References: <201511191404.tAJE4reJ064779@repo.freebsd.org> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.2.7 (bigwig.baldwin.cx); Thu, 19 Nov 2015 14:16:36 -0500 (EST) X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Nov 2015 19:16:37 -0000 On Thursday, November 19, 2015 02:04:53 PM Jonathan T. Looney wrote: > Author: jtl > Date: Thu Nov 19 14:04:53 2015 > New Revision: 291074 > URL: https://svnweb.freebsd.org/changeset/base/291074 > > Log: > Consistently enforce the restriction against calling malloc/free when in a > critical section. > > uma_zalloc_arg()/uma_zalloc_free() may acquire a sleepable lock on the > zone. The malloc() family of functions may call uma_zalloc_arg() or > uma_zalloc_free(). > > The malloc(9) man page currently claims that free() will never sleep. > It also implies that the malloc() family of functions will not sleep > when called with M_NOWAIT. However, it is more correct to say that > these functions will not sleep indefinitely. Indeed, they may acquire > a sleepable lock. However, a developer may overlook this restriction > because the WITNESS check that catches attempts to call the malloc() > family of functions within a critical section is inconsistenly > applied. Mutexes are not sleepable locks. sx(9) locks are sleepable locks. "sleep" in synchronization language in FreeBSD means "indefinite sleep", or at least any resource contention that cannot be alleviated purely by CPU execution (when you "block" on a mutex, you will get to run once the lock owner has sufficient CPU time to make progress and release the mutex, whereas waiting for a disk I/O to complete (and thus possibly for M_WAITOK malloc()) or a network packet to arrive is not purely dependent on CPU cycles). The locking(9) page expounds on this more and explicitly lists which locks are sleepable and which are not. > This change clarifies the language of the malloc(9) man page to clarify > the restriction against calling the malloc() family of functions > while in a critical section or holding a spin lock. It also adds > KASSERTs at appropriate points to make the enforcement of this > restriction more consistent. All of these KASSERTs are redundant. WITNESS will already warn for all of these in mtx_lock() itself. If your argument is that you want a panic when WITNESS is not present, then the better place to add assertions is in the locking primitives themselves (e.g. mtx_lock/rw_*lock). Note that if you are going to document in each section 9 manpage which APIs are not safe to call in a critical section, you will need to update just about every section 9 manpage. A more prudent approach would probably be to instead go the sigaction(2) route and instead document the subset of APIs which are permissible to call in critical_enter(9). The list is probably not very long. Off the top of my head I can think of sched_*, swi_sched, taskqueue_enqueue_fast, and little else. In summary, I would prefer you to revert this. If you want the assertions to fire even when WITNESS is disabled then I think we should move them into the the non-sleepable lock primitives themselves so that we catch 90+% of the problem APIs instead of just 1. Documenting the "safe" APIs in critical(9) is also more scalable than one-off notes in section 9 manpages for similar reasons. Longer term I think it would be nice to have a separate section for section 9 pages that indicates which contexts it can be called in, though I'd like that to have a consistent name and consistent language. Note though that we do not have this section currently for all of section 2/3 to indicate which are safe to call in signal context or not, in part because of the enormity of the task. Another question you might consider is why are you using spin mutexes in the first place (and then calling malloc())? Other OS's that I am familiar with do not permit you to malloc() while holding a spin lock (Linux, Solaris, OS X, etc.). This is fairly common and even folks who aren't familiar with FreeBSD and use MTX_SPIN in drivers because they are used to using spin locks in drivers on Linux (when they should use MTX_DEF instead) don't make this mistake. -- John Baldwin