diff options
author | jeff <jeff@FreeBSD.org> | 2002-10-24 06:17:30 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2002-10-24 06:17:30 +0000 |
commit | 203e2484f565853ba1bc6aa8cdbc1b6bf55a8196 (patch) | |
tree | bb9408bc8235dfe2acadbc08b8e2c654609fbc5a /sys | |
parent | 1a4ad6f6853d7f3de7ef3c0aae85f7ba6e0f28e1 (diff) | |
download | FreeBSD-src-203e2484f565853ba1bc6aa8cdbc1b6bf55a8196.zip FreeBSD-src-203e2484f565853ba1bc6aa8cdbc1b6bf55a8196.tar.gz |
- Move the destructor calls so that they are not called with the zone lock
held. This avoids a lock order reversal when destroying zones.
Unfortunately, this also means that the free checks are not done before
the destructor is called.
Reported by: phk
Diffstat (limited to 'sys')
-rw-r--r-- | sys/vm/uma_core.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index a639481..b2dafde 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -1638,6 +1638,9 @@ uma_zfree_arg(uma_zone_t zone, void *item, void *udata) if (zone->uz_flags & UMA_ZFLAG_FULL) goto zfree_internal; + if (zone->uz_dtor) + zone->uz_dtor(item, zone->uz_size, udata); + zfree_restart: cpu = PCPU_GET(cpuid); CPU_LOCK(zone, cpu); @@ -1657,8 +1660,6 @@ zfree_start: KASSERT(bucket->ub_bucket[bucket->ub_ptr] == NULL, ("uma_zfree: Freeing to non free bucket index.")); bucket->ub_bucket[bucket->ub_ptr] = item; - if (zone->uz_dtor) - zone->uz_dtor(item, zone->uz_size, udata); #ifdef INVARIANTS if (zone->uz_flags & UMA_ZFLAG_MALLOC) uma_dbg_free(zone, udata, item); @@ -1774,6 +1775,9 @@ uma_zfree_internal(uma_zone_t zone, void *item, void *udata, int skip) u_int8_t *mem; u_int8_t freei; + if (!skip && zone->uz_dtor) + zone->uz_dtor(item, zone->uz_size, udata); + ZONE_LOCK(zone); if (!(zone->uz_flags & UMA_ZFLAG_MALLOC)) { @@ -1813,9 +1817,6 @@ uma_zfree_internal(uma_zone_t zone, void *item, void *udata, int skip) /* Zone statistics */ zone->uz_free++; - if (!skip && zone->uz_dtor) - zone->uz_dtor(item, zone->uz_size, udata); - if (zone->uz_flags & UMA_ZFLAG_FULL) { if (zone->uz_pages < zone->uz_maxpages) zone->uz_flags &= ~UMA_ZFLAG_FULL; |