Introduce a new lock for the purpose of synchronizing access to the

UMA boot pages.

Disable recursion on the general UMA lock now that startup_alloc() no
longer uses it.

Eliminate the variable uma_boot_free.  It serves no purpose.

Note: This change eliminates a lock-order reversal between a system
map mutex and the UMA lock.  See
http://sources.zabbadoz.net/freebsd/lor.html#109 for details.

MFC after: 3 days
This commit is contained in:
Alan Cox 2005-09-09 06:03:08 +00:00
parent dd415a50d6
commit f353d3388f

View File

@ -124,8 +124,8 @@ static struct mtx uma_mtx;
static LIST_HEAD(,uma_slab) uma_boot_pages =
LIST_HEAD_INITIALIZER(&uma_boot_pages);
/* Count of free boottime pages */
static int uma_boot_free = 0;
/* This mutex protects the boot time pages list */
static struct mtx uma_boot_pages_mtx;
/* Is the VM done starting up? */
static int booted = 0;
@ -905,24 +905,21 @@ static void *
startup_alloc(uma_zone_t zone, int bytes, u_int8_t *pflag, int wait)
{
uma_keg_t keg;
uma_slab_t tmps;
keg = zone->uz_keg;
/*
* Check our small startup cache to see if it has pages remaining.
*/
mtx_lock(&uma_mtx);
if (uma_boot_free != 0) {
uma_slab_t tmps;
tmps = LIST_FIRST(&uma_boot_pages);
mtx_lock(&uma_boot_pages_mtx);
if ((tmps = LIST_FIRST(&uma_boot_pages)) != NULL) {
LIST_REMOVE(tmps, us_link);
uma_boot_free--;
mtx_unlock(&uma_mtx);
mtx_unlock(&uma_boot_pages_mtx);
*pflag = tmps->us_flags;
return (tmps->us_data);
}
mtx_unlock(&uma_mtx);
mtx_unlock(&uma_boot_pages_mtx);
if (booted == 0)
panic("UMA: Increase UMA_BOOT_PAGES");
/*
@ -1513,17 +1510,7 @@ uma_startup(void *bootmem)
#ifdef UMA_DEBUG
printf("Creating uma keg headers zone and keg.\n");
#endif
/*
* 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);
mtx_init(&uma_mtx, "UMA lock", NULL, MTX_DEF);
/*
* Figure out the maximum number of items-per-slab we'll have if
@ -1617,8 +1604,8 @@ uma_startup(void *bootmem)
slab->us_data = (u_int8_t *)slab;
slab->us_flags = UMA_SLAB_BOOT;
LIST_INSERT_HEAD(&uma_boot_pages, slab, us_link);
uma_boot_free++;
}
mtx_init(&uma_boot_pages_mtx, "UMA boot pages", NULL, MTX_DEF);
#ifdef UMA_DEBUG
printf("Creating uma zone headers zone and keg.\n");