Make uma_mtx MTX_RECURSE. Here's why:
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. This exact explanation also added as comment above mtx_init(). Trace showing recursion reported by: Peter Holm <peter-at-holm.cc>
This commit is contained in:
parent
51304a50f3
commit
7a6a2d65d4
@ -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";
|
||||
|
Loading…
Reference in New Issue
Block a user