Changeset View
Changeset View
Standalone View
Standalone View
head/sys/vm/uma_core.c
Show First 20 Lines • Show All 267 Lines • ▼ Show 20 Lines | |||||
static void uma_zero_item(void *, uma_zone_t); | static void uma_zero_item(void *, uma_zone_t); | ||||
void uma_print_zone(uma_zone_t); | void uma_print_zone(uma_zone_t); | ||||
void uma_print_stats(void); | void uma_print_stats(void); | ||||
static int sysctl_vm_zone_count(SYSCTL_HANDLER_ARGS); | static int sysctl_vm_zone_count(SYSCTL_HANDLER_ARGS); | ||||
static int sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS); | static int sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS); | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
static bool uma_dbg_kskip(uma_keg_t keg, void *mem); | |||||
static bool uma_dbg_zskip(uma_zone_t zone, void *mem); | |||||
static void uma_dbg_free(uma_zone_t zone, uma_slab_t slab, void *item); | static void uma_dbg_free(uma_zone_t zone, uma_slab_t slab, void *item); | ||||
static void uma_dbg_alloc(uma_zone_t zone, uma_slab_t slab, void *item); | static void uma_dbg_alloc(uma_zone_t zone, uma_slab_t slab, void *item); | ||||
static SYSCTL_NODE(_vm, OID_AUTO, debug, CTLFLAG_RD, 0, | |||||
"Memory allocation debugging"); | |||||
static u_int dbg_divisor = 1; | |||||
SYSCTL_UINT(_vm_debug, OID_AUTO, divisor, | |||||
CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &dbg_divisor, 0, | |||||
"Debug & thrash every this item in memory allocator"); | |||||
static counter_u64_t uma_dbg_cnt = EARLY_COUNTER; | |||||
static counter_u64_t uma_skip_cnt = EARLY_COUNTER; | |||||
SYSCTL_COUNTER_U64(_vm_debug, OID_AUTO, trashed, CTLFLAG_RD, | |||||
&uma_dbg_cnt, "memory items debugged"); | |||||
SYSCTL_COUNTER_U64(_vm_debug, OID_AUTO, skipped, CTLFLAG_RD, | |||||
&uma_skip_cnt, "memory items skipped, not debugged"); | |||||
#endif | #endif | ||||
SYSINIT(uma_startup3, SI_SUB_VM_CONF, SI_ORDER_SECOND, uma_startup3, NULL); | SYSINIT(uma_startup3, SI_SUB_VM_CONF, SI_ORDER_SECOND, uma_startup3, NULL); | ||||
SYSCTL_PROC(_vm, OID_AUTO, zone_count, CTLFLAG_RD|CTLTYPE_INT, | SYSCTL_PROC(_vm, OID_AUTO, zone_count, CTLFLAG_RD|CTLTYPE_INT, | ||||
0, 0, sysctl_vm_zone_count, "I", "Number of UMA zones"); | 0, 0, sysctl_vm_zone_count, "I", "Number of UMA zones"); | ||||
SYSCTL_PROC(_vm, OID_AUTO, zone_stats, CTLFLAG_RD|CTLTYPE_STRUCT, | SYSCTL_PROC(_vm, OID_AUTO, zone_stats, CTLFLAG_RD|CTLTYPE_STRUCT, | ||||
▲ Show 20 Lines • Show All 563 Lines • ▼ Show 20 Lines | keg_free_slab(uma_keg_t keg, uma_slab_t slab, int start) | ||||
CTR4(KTR_UMA, "keg_free_slab keg %s(%p) slab %p, returning %d bytes", | CTR4(KTR_UMA, "keg_free_slab keg %s(%p) slab %p, returning %d bytes", | ||||
keg->uk_name, keg, slab, PAGE_SIZE * keg->uk_ppera); | keg->uk_name, keg, slab, PAGE_SIZE * keg->uk_ppera); | ||||
mem = slab->us_data; | mem = slab->us_data; | ||||
flags = slab->us_flags; | flags = slab->us_flags; | ||||
i = start; | i = start; | ||||
if (keg->uk_fini != NULL) { | if (keg->uk_fini != NULL) { | ||||
for (i--; i > -1; i--) | for (i--; i > -1; i--) | ||||
#ifdef INVARIANTS | |||||
/* | |||||
* trash_fini implies that dtor was trash_dtor. trash_fini | |||||
* would check that memory hasn't been modified since free, | |||||
* which executed trash_dtor. | |||||
* That's why we need to run uma_dbg_kskip() check here, | |||||
* albeit we don't make skip check for other init/fini | |||||
* invocations. | |||||
*/ | |||||
if (!uma_dbg_kskip(keg, slab->us_data + (keg->uk_rsize * i)) || | |||||
keg->uk_fini != trash_fini) | |||||
#endif | |||||
keg->uk_fini(slab->us_data + (keg->uk_rsize * i), | keg->uk_fini(slab->us_data + (keg->uk_rsize * i), | ||||
keg->uk_size); | keg->uk_size); | ||||
} | } | ||||
if (keg->uk_flags & UMA_ZONE_OFFPAGE) | if (keg->uk_flags & UMA_ZONE_OFFPAGE) | ||||
zone_free_item(keg->uk_slabzone, slab, NULL, SKIP_NONE); | zone_free_item(keg->uk_slabzone, slab, NULL, SKIP_NONE); | ||||
keg->uk_freef(mem, PAGE_SIZE * keg->uk_ppera, flags); | keg->uk_freef(mem, PAGE_SIZE * keg->uk_ppera, flags); | ||||
uma_total_dec(PAGE_SIZE * keg->uk_ppera); | uma_total_dec(PAGE_SIZE * keg->uk_ppera); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,088 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Initialize our callout handle | * Initialize our callout handle | ||||
* | * | ||||
*/ | */ | ||||
static void | static void | ||||
uma_startup3(void) | uma_startup3(void) | ||||
{ | { | ||||
booted = BOOT_RUNNING; | #ifdef INVARIANTS | ||||
TUNABLE_INT_FETCH("vm.debug.divisor", &dbg_divisor); | |||||
uma_dbg_cnt = counter_u64_alloc(M_WAITOK); | |||||
uma_skip_cnt = counter_u64_alloc(M_WAITOK); | |||||
#endif | |||||
callout_init(&uma_callout, 1); | callout_init(&uma_callout, 1); | ||||
callout_reset(&uma_callout, UMA_TIMEOUT * hz, uma_timeout, NULL); | callout_reset(&uma_callout, UMA_TIMEOUT * hz, uma_timeout, NULL); | ||||
booted = BOOT_RUNNING; | |||||
} | } | ||||
static uma_keg_t | static uma_keg_t | ||||
uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit, uma_fini fini, | uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit, uma_fini fini, | ||||
int align, uint32_t flags) | int align, uint32_t flags) | ||||
{ | { | ||||
struct uma_kctor_args args; | struct uma_kctor_args args; | ||||
▲ Show 20 Lines • Show All 228 Lines • ▼ Show 20 Lines | |||||
void * | void * | ||||
uma_zalloc_arg(uma_zone_t zone, void *udata, int flags) | uma_zalloc_arg(uma_zone_t zone, void *udata, int flags) | ||||
{ | { | ||||
uma_zone_domain_t zdom; | uma_zone_domain_t zdom; | ||||
uma_bucket_t bucket; | uma_bucket_t bucket; | ||||
uma_cache_t cache; | uma_cache_t cache; | ||||
void *item; | void *item; | ||||
int cpu, domain, lockfail; | int cpu, domain, lockfail; | ||||
#ifdef INVARIANTS | |||||
bool skipdbg; | |||||
#endif | |||||
/* Enable entropy collection for RANDOM_ENABLE_UMA kernel option */ | /* Enable entropy collection for RANDOM_ENABLE_UMA kernel option */ | ||||
random_harvest_fast_uma(&zone, sizeof(zone), 1, RANDOM_UMA); | random_harvest_fast_uma(&zone, sizeof(zone), 1, RANDOM_UMA); | ||||
/* This is the fast path allocation */ | /* This is the fast path allocation */ | ||||
CTR4(KTR_UMA, "uma_zalloc_arg thread %x zone %s(%p) flags %d", | CTR4(KTR_UMA, "uma_zalloc_arg thread %x zone %s(%p) flags %d", | ||||
curthread, zone->uz_name, zone, flags); | curthread, zone->uz_name, zone, flags); | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | if (bucket != NULL && bucket->ub_cnt > 0) { | ||||
bucket->ub_cnt--; | bucket->ub_cnt--; | ||||
item = bucket->ub_bucket[bucket->ub_cnt]; | item = bucket->ub_bucket[bucket->ub_cnt]; | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
bucket->ub_bucket[bucket->ub_cnt] = NULL; | bucket->ub_bucket[bucket->ub_cnt] = NULL; | ||||
#endif | #endif | ||||
KASSERT(item != NULL, ("uma_zalloc: Bucket pointer mangled.")); | KASSERT(item != NULL, ("uma_zalloc: Bucket pointer mangled.")); | ||||
cache->uc_allocs++; | cache->uc_allocs++; | ||||
critical_exit(); | critical_exit(); | ||||
#ifdef INVARIANTS | |||||
skipdbg = uma_dbg_zskip(zone, item); | |||||
#endif | |||||
if (zone->uz_ctor != NULL && | if (zone->uz_ctor != NULL && | ||||
#ifdef INVARIANTS | |||||
(!skipdbg || zone->uz_ctor != trash_ctor || | |||||
zone->uz_dtor != trash_dtor) && | |||||
#endif | |||||
zone->uz_ctor(item, zone->uz_size, udata, flags) != 0) { | zone->uz_ctor(item, zone->uz_size, udata, flags) != 0) { | ||||
atomic_add_long(&zone->uz_fails, 1); | atomic_add_long(&zone->uz_fails, 1); | ||||
zone_free_item(zone, item, udata, SKIP_DTOR); | zone_free_item(zone, item, udata, SKIP_DTOR); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
if (!skipdbg) | |||||
uma_dbg_alloc(zone, NULL, item); | uma_dbg_alloc(zone, NULL, item); | ||||
#endif | #endif | ||||
if (flags & M_ZERO) | if (flags & M_ZERO) | ||||
uma_zero_item(item, zone); | uma_zero_item(item, zone); | ||||
return (item); | return (item); | ||||
} | } | ||||
/* | /* | ||||
* We have run out of items in our alloc bucket. | * We have run out of items in our alloc bucket. | ||||
▲ Show 20 Lines • Show All 506 Lines • ▼ Show 20 Lines | |||||
* NULL if there is no memory and M_NOWAIT is set | * NULL if there is no memory and M_NOWAIT is set | ||||
* An item if successful | * An item if successful | ||||
*/ | */ | ||||
static void * | static void * | ||||
zone_alloc_item(uma_zone_t zone, void *udata, int domain, int flags) | zone_alloc_item(uma_zone_t zone, void *udata, int domain, int flags) | ||||
{ | { | ||||
void *item; | void *item; | ||||
#ifdef INVARIANTS | |||||
bool skipdbg; | |||||
#endif | |||||
item = NULL; | item = NULL; | ||||
if (zone->uz_import(zone->uz_arg, &item, 1, domain, flags) != 1) | if (zone->uz_import(zone->uz_arg, &item, 1, domain, flags) != 1) | ||||
goto fail; | goto fail; | ||||
atomic_add_long(&zone->uz_allocs, 1); | atomic_add_long(&zone->uz_allocs, 1); | ||||
#ifdef INVARIANTS | |||||
skipdbg = uma_dbg_zskip(zone, item); | |||||
#endif | |||||
/* | /* | ||||
* We have to call both the zone's init (not the keg's init) | * We have to call both the zone's init (not the keg's init) | ||||
* and the zone's ctor. This is because the item is going from | * and the zone's ctor. This is because the item is going from | ||||
* a keg slab directly to the user, and the user is expecting it | * a keg slab directly to the user, and the user is expecting it | ||||
* to be both zone-init'd as well as zone-ctor'd. | * to be both zone-init'd as well as zone-ctor'd. | ||||
*/ | */ | ||||
if (zone->uz_init != NULL) { | if (zone->uz_init != NULL) { | ||||
if (zone->uz_init(item, zone->uz_size, flags) != 0) { | if (zone->uz_init(item, zone->uz_size, flags) != 0) { | ||||
zone_free_item(zone, item, udata, SKIP_FINI); | zone_free_item(zone, item, udata, SKIP_FINI); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
} | } | ||||
if (zone->uz_ctor != NULL) { | if (zone->uz_ctor != NULL && | ||||
if (zone->uz_ctor(item, zone->uz_size, udata, flags) != 0) { | #ifdef INVARIANTS | ||||
(!skipdbg || zone->uz_ctor != trash_ctor || | |||||
zone->uz_dtor != trash_dtor) && | |||||
#endif | |||||
zone->uz_ctor(item, zone->uz_size, udata, flags) != 0) { | |||||
zone_free_item(zone, item, udata, SKIP_DTOR); | zone_free_item(zone, item, udata, SKIP_DTOR); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
} | |||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
if (!skipdbg) | |||||
uma_dbg_alloc(zone, NULL, item); | uma_dbg_alloc(zone, NULL, item); | ||||
#endif | #endif | ||||
if (flags & M_ZERO) | if (flags & M_ZERO) | ||||
uma_zero_item(item, zone); | uma_zero_item(item, zone); | ||||
CTR3(KTR_UMA, "zone_alloc_item item %p from %s(%p)", item, | CTR3(KTR_UMA, "zone_alloc_item item %p from %s(%p)", item, | ||||
zone->uz_name, zone); | zone->uz_name, zone); | ||||
return (item); | return (item); | ||||
fail: | fail: | ||||
CTR2(KTR_UMA, "zone_alloc_item failed from %s(%p)", | CTR2(KTR_UMA, "zone_alloc_item failed from %s(%p)", | ||||
zone->uz_name, zone); | zone->uz_name, zone); | ||||
atomic_add_long(&zone->uz_fails, 1); | atomic_add_long(&zone->uz_fails, 1); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
/* See uma.h */ | /* See uma.h */ | ||||
void | void | ||||
uma_zfree_arg(uma_zone_t zone, void *item, void *udata) | uma_zfree_arg(uma_zone_t zone, void *item, void *udata) | ||||
{ | { | ||||
uma_cache_t cache; | uma_cache_t cache; | ||||
uma_bucket_t bucket; | uma_bucket_t bucket; | ||||
uma_zone_domain_t zdom; | uma_zone_domain_t zdom; | ||||
int cpu, domain, lockfail; | int cpu, domain, lockfail; | ||||
#ifdef INVARIANTS | |||||
bool skipdbg; | |||||
#endif | |||||
/* Enable entropy collection for RANDOM_ENABLE_UMA kernel option */ | /* Enable entropy collection for RANDOM_ENABLE_UMA kernel option */ | ||||
random_harvest_fast_uma(&zone, sizeof(zone), 1, RANDOM_UMA); | random_harvest_fast_uma(&zone, sizeof(zone), 1, RANDOM_UMA); | ||||
CTR2(KTR_UMA, "uma_zfree_arg thread %x zone %s", curthread, | CTR2(KTR_UMA, "uma_zfree_arg thread %x zone %s", curthread, | ||||
zone->uz_name); | zone->uz_name); | ||||
KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(), | KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(), | ||||
("uma_zfree_arg: called with spinlock or critical section held")); | ("uma_zfree_arg: called with spinlock or critical section held")); | ||||
/* uma_zfree(..., NULL) does nothing, to match free(9). */ | /* uma_zfree(..., NULL) does nothing, to match free(9). */ | ||||
if (item == NULL) | if (item == NULL) | ||||
return; | return; | ||||
#ifdef DEBUG_MEMGUARD | #ifdef DEBUG_MEMGUARD | ||||
if (is_memguard_addr(item)) { | if (is_memguard_addr(item)) { | ||||
if (zone->uz_dtor != NULL) | if (zone->uz_dtor != NULL) | ||||
zone->uz_dtor(item, zone->uz_size, udata); | zone->uz_dtor(item, zone->uz_size, udata); | ||||
if (zone->uz_fini != NULL) | if (zone->uz_fini != NULL) | ||||
zone->uz_fini(item, zone->uz_size); | zone->uz_fini(item, zone->uz_size); | ||||
memguard_free(item); | memguard_free(item); | ||||
return; | return; | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
skipdbg = uma_dbg_zskip(zone, item); | |||||
if (skipdbg == false) { | |||||
if (zone->uz_flags & UMA_ZONE_MALLOC) | if (zone->uz_flags & UMA_ZONE_MALLOC) | ||||
uma_dbg_free(zone, udata, item); | uma_dbg_free(zone, udata, item); | ||||
else | else | ||||
uma_dbg_free(zone, NULL, item); | uma_dbg_free(zone, NULL, item); | ||||
#endif | } | ||||
if (zone->uz_dtor != NULL && (!skipdbg || | |||||
zone->uz_dtor != trash_dtor || zone->uz_ctor != trash_ctor)) | |||||
#else | |||||
if (zone->uz_dtor != NULL) | if (zone->uz_dtor != NULL) | ||||
#endif | |||||
zone->uz_dtor(item, zone->uz_size, udata); | zone->uz_dtor(item, zone->uz_size, udata); | ||||
/* | /* | ||||
* The race here is acceptable. If we miss it we'll just have to wait | * The race here is acceptable. If we miss it we'll just have to wait | ||||
* a little longer for the limits to be reset. | * a little longer for the limits to be reset. | ||||
*/ | */ | ||||
if (zone->uz_flags & UMA_ZFLAG_FULL) | if (zone->uz_flags & UMA_ZFLAG_FULL) | ||||
goto zfree_item; | goto zfree_item; | ||||
▲ Show 20 Lines • Show All 247 Lines • ▼ Show 20 Lines | |||||
* zone The zone to free to | * zone The zone to free to | ||||
* item The item we're freeing | * item The item we're freeing | ||||
* udata User supplied data for the dtor | * udata User supplied data for the dtor | ||||
* skip Skip dtors and finis | * skip Skip dtors and finis | ||||
*/ | */ | ||||
static void | static void | ||||
zone_free_item(uma_zone_t zone, void *item, void *udata, enum zfreeskip skip) | zone_free_item(uma_zone_t zone, void *item, void *udata, enum zfreeskip skip) | ||||
{ | { | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
if (skip == SKIP_NONE) { | bool skipdbg; | ||||
skipdbg = uma_dbg_zskip(zone, item); | |||||
if (skip == SKIP_NONE && !skipdbg) { | |||||
if (zone->uz_flags & UMA_ZONE_MALLOC) | if (zone->uz_flags & UMA_ZONE_MALLOC) | ||||
uma_dbg_free(zone, udata, item); | uma_dbg_free(zone, udata, item); | ||||
else | else | ||||
uma_dbg_free(zone, NULL, item); | uma_dbg_free(zone, NULL, item); | ||||
} | } | ||||
if (skip < SKIP_DTOR && zone->uz_dtor != NULL && | |||||
(!skipdbg || zone->uz_dtor != trash_dtor || | |||||
zone->uz_ctor != trash_ctor)) | |||||
#else | |||||
if (skip < SKIP_DTOR && zone->uz_dtor != NULL) | |||||
#endif | #endif | ||||
if (skip < SKIP_DTOR && zone->uz_dtor) | |||||
zone->uz_dtor(item, zone->uz_size, udata); | zone->uz_dtor(item, zone->uz_size, udata); | ||||
if (skip < SKIP_FINI && zone->uz_fini) | if (skip < SKIP_FINI && zone->uz_fini) | ||||
zone->uz_fini(item, zone->uz_size); | zone->uz_fini(item, zone->uz_size); | ||||
atomic_add_long(&zone->uz_frees, 1); | atomic_add_long(&zone->uz_frees, 1); | ||||
zone->uz_release(zone->uz_arg, &item, 1); | zone->uz_release(zone->uz_arg, &item, 1); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 701 Lines • ▼ Show 20 Lines | if (zone->uz_flags & UMA_ZONE_VTOSLAB) { | ||||
else | else | ||||
slab = (uma_slab_t)(mem + keg->uk_pgoff); | slab = (uma_slab_t)(mem + keg->uk_pgoff); | ||||
ZONE_UNLOCK(zone); | ZONE_UNLOCK(zone); | ||||
} | } | ||||
return (slab); | return (slab); | ||||
} | } | ||||
static bool | |||||
uma_dbg_zskip(uma_zone_t zone, void *mem) | |||||
{ | |||||
uma_keg_t keg; | |||||
if ((keg = zone_first_keg(zone)) == NULL) | |||||
return (true); | |||||
return (uma_dbg_kskip(keg, mem)); | |||||
} | |||||
static bool | |||||
uma_dbg_kskip(uma_keg_t keg, void *mem) | |||||
{ | |||||
uintptr_t idx; | |||||
if (dbg_divisor == 0) | |||||
return (true); | |||||
if (dbg_divisor == 1) | |||||
return (false); | |||||
idx = (uintptr_t)mem >> PAGE_SHIFT; | |||||
if (keg->uk_ipers > 1) { | |||||
idx *= keg->uk_ipers; | |||||
idx += ((uintptr_t)mem & PAGE_MASK) / keg->uk_rsize; | |||||
} | |||||
if ((idx / dbg_divisor) * dbg_divisor != idx) { | |||||
counter_u64_add(uma_skip_cnt, 1); | |||||
return (true); | |||||
} | |||||
counter_u64_add(uma_dbg_cnt, 1); | |||||
return (false); | |||||
} | |||||
/* | /* | ||||
* Set up the slab's freei data such that uma_dbg_free can function. | * Set up the slab's freei data such that uma_dbg_free can function. | ||||
* | * | ||||
*/ | */ | ||||
static void | static void | ||||
uma_dbg_alloc(uma_zone_t zone, uma_slab_t slab, void *item) | uma_dbg_alloc(uma_zone_t zone, uma_slab_t slab, void *item) | ||||
{ | { | ||||
uma_keg_t keg; | uma_keg_t keg; | ||||
int freei; | int freei; | ||||
if (zone_first_keg(zone) == NULL) | |||||
return; | |||||
if (slab == NULL) { | if (slab == NULL) { | ||||
slab = uma_dbg_getslab(zone, item); | slab = uma_dbg_getslab(zone, item); | ||||
if (slab == NULL) | if (slab == NULL) | ||||
panic("uma: item %p did not belong to zone %s\n", | panic("uma: item %p did not belong to zone %s\n", | ||||
item, zone->uz_name); | item, zone->uz_name); | ||||
} | } | ||||
keg = slab->us_keg; | keg = slab->us_keg; | ||||
freei = ((uintptr_t)item - (uintptr_t)slab->us_data) / keg->uk_rsize; | freei = ((uintptr_t)item - (uintptr_t)slab->us_data) / keg->uk_rsize; | ||||
Show All 12 Lines | |||||
* | * | ||||
*/ | */ | ||||
static void | static void | ||||
uma_dbg_free(uma_zone_t zone, uma_slab_t slab, void *item) | uma_dbg_free(uma_zone_t zone, uma_slab_t slab, void *item) | ||||
{ | { | ||||
uma_keg_t keg; | uma_keg_t keg; | ||||
int freei; | int freei; | ||||
if (zone_first_keg(zone) == NULL) | |||||
return; | |||||
if (slab == NULL) { | if (slab == NULL) { | ||||
slab = uma_dbg_getslab(zone, item); | slab = uma_dbg_getslab(zone, item); | ||||
if (slab == NULL) | if (slab == NULL) | ||||
panic("uma: Freed item %p did not belong to zone %s\n", | panic("uma: Freed item %p did not belong to zone %s\n", | ||||
item, zone->uz_name); | item, zone->uz_name); | ||||
} | } | ||||
keg = slab->us_keg; | keg = slab->us_keg; | ||||
freei = ((uintptr_t)item - (uintptr_t)slab->us_data) / keg->uk_rsize; | freei = ((uintptr_t)item - (uintptr_t)slab->us_data) / keg->uk_rsize; | ||||
▲ Show 20 Lines • Show All 84 Lines • Show Last 20 Lines |