summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authorbmilekic <bmilekic@FreeBSD.org>2005-01-11 03:33:09 +0000
committerbmilekic <bmilekic@FreeBSD.org>2005-01-11 03:33:09 +0000
commitbc2ae8f1d2437b97bf4b499b40c95256acae7f4f (patch)
tree23c3d843769264b7a442de741ce079dad1744f2a /sys/vm
parent845566c7e871990df59a079ee30e775e68415e09 (diff)
downloadFreeBSD-src-bc2ae8f1d2437b97bf4b499b40c95256acae7f4f.zip
FreeBSD-src-bc2ae8f1d2437b97bf4b499b40c95256acae7f4f.tar.gz
While we want the recursion protection for the bucket zones so that
recursion from the VM is handled (and the calling code that allocates buckets knows how to deal with it), we do not want to prevent allocation from the slab header zones (slabzone and slabrefzone) if uk_recurse is not zero for them. The reason is that it could lead to NULL being returned for the slab header allocations even in the M_WAITOK case, and the caller can't handle that (this is also explained in a comment with this commit). The problem analysis is documented in our mailing lists: http://docs.freebsd.org/cgi/getmsg.cgi?fetch=153445+0+archive/2004/freebsd-current/20041231.freebsd-current (see entire thread for proper context). Crash dump data provided by: Peter Holm <peter@holm.cc>
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/uma_core.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index d1512f5..aa873f1 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -1939,9 +1939,19 @@ uma_zone_slab(uma_zone_t zone, int flags)
* buckets there too we will recurse in kmem_alloc and bad
* things happen. So instead we return a NULL bucket, and make
* the code that allocates buckets smart enough to deal with it
+ *
+ * XXX: While we want this protection for the bucket zones so that
+ * recursion from the VM is handled (and the calling code that
+ * allocates buckets knows how to deal with it), we do not want
+ * to prevent allocation from the slab header zones (slabzone
+ * and slabrefzone) if uk_recurse is not zero for them. The
+ * reason is that it could lead to NULL being returned for
+ * slab header allocations even in the M_WAITOK case, and the
+ * caller can't handle that.
*/
if (keg->uk_flags & UMA_ZFLAG_INTERNAL && keg->uk_recurse != 0)
- return (NULL);
+ if ((zone != slabzone) && (zone != slabrefzone))
+ return (NULL);
slab = NULL;
OpenPOWER on IntegriCloud