diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index 6a4c4579b1df..d49deeaa6dfa 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -1393,7 +1393,17 @@ uma_startup(void *bootmem) #ifdef UMA_DEBUG printf("Creating uma keg headers zone and keg.\n"); #endif - mtx_init(&uma_mtx, "UMA lock", NULL, MTX_DEF); + /* + * The general UMA lock is a recursion-allowed lock because + * there is a code path where, while we're still configured + * to use startup_alloc() for backend page allocations, we + * may end up in uma_reclaim() which calls zone_foreach(zone_drain), + * which grabs uma_mtx, only to later call into startup_alloc() + * because while freeing we needed to allocate a bucket. Since + * startup_alloc() also takes uma_mtx, we need to be able to + * recurse on it. + */ + mtx_init(&uma_mtx, "UMA lock", NULL, MTX_DEF | MTX_RECURSE); /* "manually" create the initial zone */ args.name = "UMA Kegs";