Changeset View
Changeset View
Standalone View
Standalone View
head/sys/vm/uma_core.c
Show First 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
/* | /* | ||||
* This is the zone and keg from which all zones are spawned. | * This is the zone and keg from which all zones are spawned. | ||||
*/ | */ | ||||
static uma_zone_t kegs; | static uma_zone_t kegs; | ||||
static uma_zone_t zones; | static uma_zone_t zones; | ||||
/* This is the zone from which all offpage uma_slab_ts are allocated. */ | /* | ||||
static uma_zone_t slabzone; | * These are the two zones from which all offpage uma_slab_ts are allocated. | ||||
* | |||||
* One zone is for slab headers that can represent a larger number of items, | |||||
* making the slabs themselves more efficient, and the other zone is for | |||||
* headers that are smaller and represent fewer items, making the headers more | |||||
* efficient. | |||||
*/ | |||||
#define SLABZONE_SIZE(setsize) \ | |||||
(sizeof(struct uma_hash_slab) + BITSET_SIZE(setsize) * SLAB_BITSETS) | |||||
#define SLABZONE0_SETSIZE (PAGE_SIZE / 16) | |||||
#define SLABZONE1_SETSIZE SLAB_MAX_SETSIZE | |||||
#define SLABZONE0_SIZE SLABZONE_SIZE(SLABZONE0_SETSIZE) | |||||
#define SLABZONE1_SIZE SLABZONE_SIZE(SLABZONE1_SETSIZE) | |||||
static uma_zone_t slabzones[2]; | |||||
/* | /* | ||||
* The initial hash tables come out of this zone so they can be allocated | * The initial hash tables come out of this zone so they can be allocated | ||||
* prior to malloc coming up. | * prior to malloc coming up. | ||||
*/ | */ | ||||
static uma_zone_t hashzone; | static uma_zone_t hashzone; | ||||
/* The boot-time adjusted value for cache line alignment. */ | /* The boot-time adjusted value for cache line alignment. */ | ||||
▲ Show 20 Lines • Show All 216 Lines • ▼ Show 20 Lines | |||||
SYSCTL_PROC(_vm, OID_AUTO, zone_stats, CTLFLAG_RD|CTLFLAG_MPSAFE|CTLTYPE_STRUCT, | SYSCTL_PROC(_vm, OID_AUTO, zone_stats, CTLFLAG_RD|CTLFLAG_MPSAFE|CTLTYPE_STRUCT, | ||||
0, 0, sysctl_vm_zone_stats, "s,struct uma_type_header", "Zone Stats"); | 0, 0, sysctl_vm_zone_stats, "s,struct uma_type_header", "Zone Stats"); | ||||
static int zone_warnings = 1; | static int zone_warnings = 1; | ||||
SYSCTL_INT(_vm, OID_AUTO, zone_warnings, CTLFLAG_RWTUN, &zone_warnings, 0, | SYSCTL_INT(_vm, OID_AUTO, zone_warnings, CTLFLAG_RWTUN, &zone_warnings, 0, | ||||
"Warn when UMA zones becomes full"); | "Warn when UMA zones becomes full"); | ||||
/* | /* | ||||
* Select the slab zone for an offpage slab with the given maximum item count. | |||||
*/ | |||||
static inline uma_zone_t | |||||
slabzone(int ipers) | |||||
{ | |||||
return (slabzones[ipers > SLABZONE0_SETSIZE]); | |||||
} | |||||
/* | |||||
* This routine checks to see whether or not it's safe to enable buckets. | * This routine checks to see whether or not it's safe to enable buckets. | ||||
*/ | */ | ||||
static void | static void | ||||
bucket_enable(void) | bucket_enable(void) | ||||
{ | { | ||||
KASSERT(booted >= BOOT_BUCKETS, ("Bucket enable before init")); | KASSERT(booted >= BOOT_BUCKETS, ("Bucket enable before init")); | ||||
bucketdisable = vm_page_count_min(); | bucketdisable = vm_page_count_min(); | ||||
▲ Show 20 Lines • Show All 812 Lines • ▼ Show 20 Lines | #ifdef INVARIANTS | ||||
* invocations. | * invocations. | ||||
*/ | */ | ||||
if (!uma_dbg_kskip(keg, slab_item(slab, keg, i)) || | if (!uma_dbg_kskip(keg, slab_item(slab, keg, i)) || | ||||
keg->uk_fini != trash_fini) | keg->uk_fini != trash_fini) | ||||
#endif | #endif | ||||
keg->uk_fini(slab_item(slab, keg, i), keg->uk_size); | keg->uk_fini(slab_item(slab, keg, i), keg->uk_size); | ||||
} | } | ||||
if (keg->uk_flags & UMA_ZFLAG_OFFPAGE) | if (keg->uk_flags & UMA_ZFLAG_OFFPAGE) | ||||
zone_free_item(keg->uk_slabzone, slab, NULL, SKIP_NONE); | zone_free_item(slabzone(keg->uk_ipers), slab_tohashslab(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); | ||||
} | } | ||||
/* | /* | ||||
* Frees pages from a keg back to the system. This is done on demand from | * Frees pages from a keg back to the system. This is done on demand from | ||||
* the pageout daemon. | * the pageout daemon. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 116 Lines • ▼ Show 20 Lines | keg_alloc_slab(uma_keg_t keg, uma_zone_t zone, int domain, int flags, | ||||
KASSERT(domain >= 0 && domain < vm_ndomains, | KASSERT(domain >= 0 && domain < vm_ndomains, | ||||
("keg_alloc_slab: domain %d out of range", domain)); | ("keg_alloc_slab: domain %d out of range", domain)); | ||||
allocf = keg->uk_allocf; | allocf = keg->uk_allocf; | ||||
slab = NULL; | slab = NULL; | ||||
mem = NULL; | mem = NULL; | ||||
if (keg->uk_flags & UMA_ZFLAG_OFFPAGE) { | if (keg->uk_flags & UMA_ZFLAG_OFFPAGE) { | ||||
slab = zone_alloc_item(keg->uk_slabzone, NULL, domain, aflags); | uma_hash_slab_t hslab; | ||||
if (slab == NULL) | hslab = zone_alloc_item(slabzone(keg->uk_ipers), NULL, | ||||
domain, aflags); | |||||
if (hslab == NULL) | |||||
goto fail; | goto fail; | ||||
slab = &hslab->uhs_slab; | |||||
} | } | ||||
/* | /* | ||||
* This reproduces the old vm_zone behavior of zero filling pages the | * This reproduces the old vm_zone behavior of zero filling pages the | ||||
* first time they are added to a zone. | * first time they are added to a zone. | ||||
* | * | ||||
* Malloced items are zeroed in uma_zalloc. | * Malloced items are zeroed in uma_zalloc. | ||||
*/ | */ | ||||
if ((keg->uk_flags & UMA_ZONE_MALLOC) == 0) | if ((keg->uk_flags & UMA_ZONE_MALLOC) == 0) | ||||
aflags |= M_ZERO; | aflags |= M_ZERO; | ||||
else | else | ||||
aflags &= ~M_ZERO; | aflags &= ~M_ZERO; | ||||
if (keg->uk_flags & UMA_ZONE_NODUMP) | if (keg->uk_flags & UMA_ZONE_NODUMP) | ||||
aflags |= M_NODUMP; | aflags |= M_NODUMP; | ||||
/* zone is passed for legacy reasons. */ | /* zone is passed for legacy reasons. */ | ||||
size = keg->uk_ppera * PAGE_SIZE; | size = keg->uk_ppera * PAGE_SIZE; | ||||
mem = allocf(zone, size, domain, &sflags, aflags); | mem = allocf(zone, size, domain, &sflags, aflags); | ||||
if (mem == NULL) { | if (mem == NULL) { | ||||
if (keg->uk_flags & UMA_ZFLAG_OFFPAGE) | if (keg->uk_flags & UMA_ZFLAG_OFFPAGE) | ||||
zone_free_item(keg->uk_slabzone, slab, NULL, SKIP_NONE); | zone_free_item(slabzone(keg->uk_ipers), | ||||
slab_tohashslab(slab), NULL, SKIP_NONE); | |||||
goto fail; | goto fail; | ||||
} | } | ||||
uma_total_inc(size); | uma_total_inc(size); | ||||
/* For HASH zones all pages go to the same uma_domain. */ | /* For HASH zones all pages go to the same uma_domain. */ | ||||
if ((keg->uk_flags & UMA_ZFLAG_HASH) != 0) | if ((keg->uk_flags & UMA_ZFLAG_HASH) != 0) | ||||
domain = 0; | domain = 0; | ||||
/* Point the slab into the allocated memory */ | /* Point the slab into the allocated memory */ | ||||
if (!(keg->uk_flags & UMA_ZFLAG_OFFPAGE)) | if (!(keg->uk_flags & UMA_ZFLAG_OFFPAGE)) | ||||
slab = (uma_slab_t )(mem + keg->uk_pgoff); | slab = (uma_slab_t )(mem + keg->uk_pgoff); | ||||
else | else | ||||
((uma_hash_slab_t)slab)->uhs_data = mem; | slab_tohashslab(slab)->uhs_data = mem; | ||||
if (keg->uk_flags & UMA_ZFLAG_VTOSLAB) | if (keg->uk_flags & UMA_ZFLAG_VTOSLAB) | ||||
for (i = 0; i < keg->uk_ppera; i++) | for (i = 0; i < keg->uk_ppera; i++) | ||||
vsetzoneslab((vm_offset_t)mem + (i * PAGE_SIZE), | vsetzoneslab((vm_offset_t)mem + (i * PAGE_SIZE), | ||||
zone, slab); | zone, slab); | ||||
slab->us_freecount = keg->uk_ipers; | slab->us_freecount = keg->uk_ipers; | ||||
slab->us_flags = sflags; | slab->us_flags = sflags; | ||||
▲ Show 20 Lines • Show All 412 Lines • ▼ Show 20 Lines | keg_layout(uma_keg_t keg) | ||||
format = 0; | format = 0; | ||||
ipers = 0; | ipers = 0; | ||||
/* | /* | ||||
* Calculate the size of each allocation (rsize) according to | * Calculate the size of each allocation (rsize) according to | ||||
* alignment. If the requested size is smaller than we have | * alignment. If the requested size is smaller than we have | ||||
* allocation bits for we round it up. | * allocation bits for we round it up. | ||||
*/ | */ | ||||
rsize = MAX(keg->uk_size, UMA_SLAB_SIZE / SLAB_MAX_SETSIZE); | rsize = MAX(keg->uk_size, UMA_SMALLEST_UNIT); | ||||
rsize = roundup2(rsize, alignsize); | rsize = roundup2(rsize, alignsize); | ||||
if ((keg->uk_flags & UMA_ZONE_PCPU) != 0) { | if ((keg->uk_flags & UMA_ZONE_PCPU) != 0) { | ||||
slabsize = UMA_PCPU_ALLOC_SIZE; | slabsize = UMA_PCPU_ALLOC_SIZE; | ||||
pages = mp_maxid + 1; | pages = mp_maxid + 1; | ||||
} else if ((keg->uk_flags & UMA_ZONE_CACHESPREAD) != 0) { | } else if ((keg->uk_flags & UMA_ZONE_CACHESPREAD) != 0) { | ||||
/* | /* | ||||
* We want one item to start on every align boundary in a page. | * We want one item to start on every align boundary in a page. | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | keg_layout(uma_keg_t keg) | ||||
* | * | ||||
* XXX We could try growing slabsize to limit max waste as well. | * XXX We could try growing slabsize to limit max waste as well. | ||||
* Historically this was not done because the VM could not | * Historically this was not done because the VM could not | ||||
* efficiently handle contiguous allocations. | * efficiently handle contiguous allocations. | ||||
*/ | */ | ||||
eff = UMA_FRAC_FIXPT(ipers * rsize, slabsize); | eff = UMA_FRAC_FIXPT(ipers * rsize, slabsize); | ||||
ipers_offpage = slab_ipers_hdr(keg->uk_size, rsize, slabsize, false); | ipers_offpage = slab_ipers_hdr(keg->uk_size, rsize, slabsize, false); | ||||
eff_offpage = UMA_FRAC_FIXPT(ipers_offpage * rsize, | eff_offpage = UMA_FRAC_FIXPT(ipers_offpage * rsize, | ||||
slabsize + slab_sizeof(SLAB_MAX_SETSIZE)); | slabsize + slabzone(ipers_offpage)->uz_keg->uk_rsize); | ||||
if (ipers == 0 || (eff < UMA_MIN_EFF && eff < eff_offpage)) { | if (ipers == 0 || (eff < UMA_MIN_EFF && eff < eff_offpage)) { | ||||
CTR5(KTR_UMA, "UMA decided we need offpage slab headers for " | CTR5(KTR_UMA, "UMA decided we need offpage slab headers for " | ||||
"keg: %s(%p), minimum efficiency allowed = %u%%, " | "keg: %s(%p), minimum efficiency allowed = %u%%, " | ||||
"old efficiency = %u%%, offpage efficiency = %u%%", | "old efficiency = %u%%, offpage efficiency = %u%%", | ||||
keg->uk_name, keg, UMA_FIXPT_PCT(UMA_MIN_EFF), | keg->uk_name, keg, UMA_FIXPT_PCT(UMA_MIN_EFF), | ||||
UMA_FIXPT_PCT(eff), UMA_FIXPT_PCT(eff_offpage)); | UMA_FIXPT_PCT(eff), UMA_FIXPT_PCT(eff_offpage)); | ||||
format = UMA_ZFLAG_OFFPAGE; | format = UMA_ZFLAG_OFFPAGE; | ||||
ipers = ipers_offpage; | ipers = ipers_offpage; | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | keg_ctor(void *mem, int size, void *udata, int flags) | ||||
bzero(keg, size); | bzero(keg, size); | ||||
keg->uk_size = arg->size; | keg->uk_size = arg->size; | ||||
keg->uk_init = arg->uminit; | keg->uk_init = arg->uminit; | ||||
keg->uk_fini = arg->fini; | keg->uk_fini = arg->fini; | ||||
keg->uk_align = arg->align; | keg->uk_align = arg->align; | ||||
keg->uk_reserve = 0; | keg->uk_reserve = 0; | ||||
keg->uk_flags = arg->flags; | keg->uk_flags = arg->flags; | ||||
keg->uk_slabzone = NULL; | |||||
/* | /* | ||||
* We use a global round-robin policy by default. Zones with | * We use a global round-robin policy by default. Zones with | ||||
* UMA_ZONE_FIRSTTOUCH set will use first-touch instead, in which | * UMA_ZONE_FIRSTTOUCH set will use first-touch instead, in which | ||||
* case the iterator is never run. | * case the iterator is never run. | ||||
*/ | */ | ||||
keg->uk_dr.dr_policy = DOMAINSET_RR(); | keg->uk_dr.dr_policy = DOMAINSET_RR(); | ||||
keg->uk_dr.dr_iter = 0; | keg->uk_dr.dr_iter = 0; | ||||
Show All 29 Lines | |||||
#ifdef NUMA | #ifdef NUMA | ||||
if ((keg->uk_flags & | if ((keg->uk_flags & | ||||
(UMA_ZFLAG_HASH | UMA_ZONE_VM | UMA_ZONE_ROUNDROBIN)) == 0) | (UMA_ZFLAG_HASH | UMA_ZONE_VM | UMA_ZONE_ROUNDROBIN)) == 0) | ||||
keg->uk_flags |= UMA_ZONE_FIRSTTOUCH; | keg->uk_flags |= UMA_ZONE_FIRSTTOUCH; | ||||
else if ((keg->uk_flags & UMA_ZONE_FIRSTTOUCH) == 0) | else if ((keg->uk_flags & UMA_ZONE_FIRSTTOUCH) == 0) | ||||
keg->uk_flags |= UMA_ZONE_ROUNDROBIN; | keg->uk_flags |= UMA_ZONE_ROUNDROBIN; | ||||
#endif | #endif | ||||
if (keg->uk_flags & UMA_ZFLAG_OFFPAGE) | |||||
keg->uk_slabzone = slabzone; | |||||
/* | /* | ||||
* If we haven't booted yet we need allocations to go through the | * If we haven't booted yet we need allocations to go through the | ||||
* startup cache until the vm is ready. | * startup cache until the vm is ready. | ||||
*/ | */ | ||||
if (booted < BOOT_PAGEALLOC) | if (booted < BOOT_PAGEALLOC) | ||||
keg->uk_allocf = startup_alloc; | keg->uk_allocf = startup_alloc; | ||||
#ifdef UMA_MD_SMALL_ALLOC | #ifdef UMA_MD_SMALL_ALLOC | ||||
else if (keg->uk_ppera == 1) | else if (keg->uk_ppera == 1) | ||||
▲ Show 20 Lines • Show All 529 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Count how many pages do we need to bootstrap. VM supplies | * Count how many pages do we need to bootstrap. VM supplies | ||||
* its need in early zones in the argument, we add up our zones, | * its need in early zones in the argument, we add up our zones, | ||||
* which consist of the UMA Slabs, UMA Hash and 9 Bucket zones. The | * which consist of the UMA Slabs, UMA Hash and 9 Bucket zones. The | ||||
* zone of zones and zone of kegs are accounted separately. | * zone of zones and zone of kegs are accounted separately. | ||||
*/ | */ | ||||
#define UMA_BOOT_ZONES 11 | #define UMA_BOOT_ZONES 12 | ||||
static int zsize, ksize; | static int zsize, ksize; | ||||
int | int | ||||
uma_startup_count(int vm_zones) | uma_startup_count(int vm_zones) | ||||
{ | { | ||||
int zones, pages; | int zones, pages; | ||||
u_int zppera, zipers; | u_int zppera, zipers; | ||||
u_int kppera, kipers; | u_int kppera, kipers; | ||||
size_t space, size; | size_t space, size; | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | #endif | ||||
args.dtor = zone_dtor; | args.dtor = zone_dtor; | ||||
args.uminit = zero_init; | args.uminit = zero_init; | ||||
args.fini = NULL; | args.fini = NULL; | ||||
args.keg = NULL; | args.keg = NULL; | ||||
args.align = UMA_SUPER_ALIGN - 1; | args.align = UMA_SUPER_ALIGN - 1; | ||||
args.flags = UMA_ZFLAG_INTERNAL; | args.flags = UMA_ZFLAG_INTERNAL; | ||||
zone_ctor(zones, zsize, &args, M_WAITOK); | zone_ctor(zones, zsize, &args, M_WAITOK); | ||||
/* Now make a zone for slab headers */ | /* Now make zones for slab headers */ | ||||
slabzone = uma_zcreate("UMA Slabs", sizeof(struct uma_hash_slab), | slabzones[0] = uma_zcreate("UMA Slabs 0", SLABZONE0_SIZE, | ||||
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZFLAG_INTERNAL); | NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZFLAG_INTERNAL); | ||||
slabzones[1] = uma_zcreate("UMA Slabs 1", SLABZONE1_SIZE, | |||||
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZFLAG_INTERNAL); | |||||
hashzone = uma_zcreate("UMA Hash", | hashzone = uma_zcreate("UMA Hash", | ||||
sizeof(struct slabhead *) * UMA_HASH_SIZE_INIT, | sizeof(struct slabhead *) * UMA_HASH_SIZE_INIT, | ||||
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZFLAG_INTERNAL); | NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZFLAG_INTERNAL); | ||||
booted = BOOT_STRAPPED; | booted = BOOT_STRAPPED; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 667 Lines • ▼ Show 20 Lines | restart: | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
static void * | static void * | ||||
slab_alloc_item(uma_keg_t keg, uma_slab_t slab) | slab_alloc_item(uma_keg_t keg, uma_slab_t slab) | ||||
{ | { | ||||
uma_domain_t dom; | uma_domain_t dom; | ||||
void *item; | void *item; | ||||
uint8_t freei; | int freei; | ||||
KEG_LOCK_ASSERT(keg, slab->us_domain); | KEG_LOCK_ASSERT(keg, slab->us_domain); | ||||
dom = &keg->uk_domain[slab->us_domain]; | dom = &keg->uk_domain[slab->us_domain]; | ||||
freei = BIT_FFS(keg->uk_ipers, &slab->us_free) - 1; | freei = BIT_FFS(keg->uk_ipers, &slab->us_free) - 1; | ||||
BIT_CLR(keg->uk_ipers, freei, &slab->us_free); | BIT_CLR(keg->uk_ipers, freei, &slab->us_free); | ||||
item = slab_item(slab, keg, freei); | item = slab_item(slab, keg, freei); | ||||
slab->us_freecount--; | slab->us_freecount--; | ||||
▲ Show 20 Lines • Show All 665 Lines • ▼ Show 20 Lines | uma_zfree_domain(uma_zone_t zone, void *item, void *udata) | ||||
zone_free_item(zone, item, udata, SKIP_NONE); | zone_free_item(zone, item, udata, SKIP_NONE); | ||||
} | } | ||||
static void | static void | ||||
slab_free_item(uma_zone_t zone, uma_slab_t slab, void *item) | slab_free_item(uma_zone_t zone, uma_slab_t slab, void *item) | ||||
{ | { | ||||
uma_keg_t keg; | uma_keg_t keg; | ||||
uma_domain_t dom; | uma_domain_t dom; | ||||
uint8_t freei; | int freei; | ||||
keg = zone->uz_keg; | keg = zone->uz_keg; | ||||
KEG_LOCK_ASSERT(keg, slab->us_domain); | KEG_LOCK_ASSERT(keg, slab->us_domain); | ||||
/* Do we need to remove from any lists? */ | /* Do we need to remove from any lists? */ | ||||
dom = &keg->uk_domain[slab->us_domain]; | dom = &keg->uk_domain[slab->us_domain]; | ||||
if (slab->us_freecount+1 == keg->uk_ipers) { | if (slab->us_freecount+1 == keg->uk_ipers) { | ||||
LIST_REMOVE(slab, us_link); | LIST_REMOVE(slab, us_link); | ||||
▲ Show 20 Lines • Show All 399 Lines • ▼ Show 20 Lines | default: | ||||
panic("unhandled reclamation request %d", req); | panic("unhandled reclamation request %d", req); | ||||
} | } | ||||
/* | /* | ||||
* Some slabs may have been freed but this zone will be visited early | * Some slabs may have been freed but this zone will be visited early | ||||
* we visit again so that we can free pages that are empty once other | * we visit again so that we can free pages that are empty once other | ||||
* zones are drained. We have to do the same for buckets. | * zones are drained. We have to do the same for buckets. | ||||
*/ | */ | ||||
zone_drain(slabzone, NULL); | zone_drain(slabzones[0], NULL); | ||||
zone_drain(slabzones[1], NULL); | |||||
bucket_zone_drain(); | bucket_zone_drain(); | ||||
sx_xunlock(&uma_reclaim_lock); | sx_xunlock(&uma_reclaim_lock); | ||||
} | } | ||||
static volatile int uma_reclaim_needed; | static volatile int uma_reclaim_needed; | ||||
void | void | ||||
uma_reclaim_wakeup(void) | uma_reclaim_wakeup(void) | ||||
▲ Show 20 Lines • Show All 355 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
sysctl_handle_uma_slab_efficiency(SYSCTL_HANDLER_ARGS) | sysctl_handle_uma_slab_efficiency(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
uma_keg_t keg = arg1; | uma_keg_t keg = arg1; | ||||
int avail, effpct, total; | int avail, effpct, total; | ||||
total = keg->uk_ppera * PAGE_SIZE; | total = keg->uk_ppera * PAGE_SIZE; | ||||
if ((keg->uk_flags & UMA_ZFLAG_OFFPAGE) != 0) | if ((keg->uk_flags & UMA_ZFLAG_OFFPAGE) != 0) | ||||
total += slab_sizeof(SLAB_MAX_SETSIZE); | total += slabzone(keg->uk_ipers)->uz_keg->uk_rsize; | ||||
/* | /* | ||||
* We consider the client's requested size and alignment here, not the | * We consider the client's requested size and alignment here, not the | ||||
* real size determination uk_rsize, because we also adjust the real | * real size determination uk_rsize, because we also adjust the real | ||||
* size for internal implementation reasons (max bitset size). | * size for internal implementation reasons (max bitset size). | ||||
*/ | */ | ||||
avail = keg->uk_ipers * roundup2(keg->uk_size, keg->uk_align + 1); | avail = keg->uk_ipers * roundup2(keg->uk_size, keg->uk_align + 1); | ||||
if ((keg->uk_flags & UMA_ZONE_PCPU) != 0) | if ((keg->uk_flags & UMA_ZONE_PCPU) != 0) | ||||
avail *= mp_maxid + 1; | avail *= mp_maxid + 1; | ||||
▲ Show 20 Lines • Show All 261 Lines • Show Last 20 Lines |