For not offpage zones the slab is placed at the end of page. Keg's uk_pgoff
is calculated to guarantee that struct uma_slab is placed at pointer size alignment. Calculation of real struct uma_slab size is done in keg_ctor() and yet again in keg_large_init(), to check if we need an extra page. This calculation can actually be performed at compile time. - Add SIZEOF_UMA_SLAB macro to calculate size of struct uma_slab placed at an end of a page with alignment requirement. - Use SIZEOF_UMA_SLAB in keg_ctor() and in keg_large_init(). This is a not a functional change. - Use SIZEOF_UMA_SLAB in UMA_SLAB_SPACE definition and in keg_small_init(). This is a potential bugfix, but in reality I don't think there are any systems affected, since compiler aligns struct uma_slab anyway.
This commit is contained in:
parent
b92c2c907e
commit
3d5e3df73f
@ -1453,7 +1453,7 @@ keg_small_init(uma_keg_t keg)
|
|||||||
if (keg->uk_flags & UMA_ZONE_OFFPAGE)
|
if (keg->uk_flags & UMA_ZONE_OFFPAGE)
|
||||||
shsize = 0;
|
shsize = 0;
|
||||||
else
|
else
|
||||||
shsize = sizeof(struct uma_slab);
|
shsize = SIZEOF_UMA_SLAB;
|
||||||
|
|
||||||
if (rsize <= slabsize - shsize)
|
if (rsize <= slabsize - shsize)
|
||||||
keg->uk_ipers = (slabsize - shsize) / rsize;
|
keg->uk_ipers = (slabsize - shsize) / rsize;
|
||||||
@ -1523,7 +1523,6 @@ keg_small_init(uma_keg_t keg)
|
|||||||
static void
|
static void
|
||||||
keg_large_init(uma_keg_t keg)
|
keg_large_init(uma_keg_t keg)
|
||||||
{
|
{
|
||||||
u_int shsize;
|
|
||||||
|
|
||||||
KASSERT(keg != NULL, ("Keg is null in keg_large_init"));
|
KASSERT(keg != NULL, ("Keg is null in keg_large_init"));
|
||||||
KASSERT((keg->uk_flags & UMA_ZFLAG_CACHEONLY) == 0,
|
KASSERT((keg->uk_flags & UMA_ZFLAG_CACHEONLY) == 0,
|
||||||
@ -1536,23 +1535,17 @@ keg_large_init(uma_keg_t keg)
|
|||||||
keg->uk_rsize = keg->uk_size;
|
keg->uk_rsize = keg->uk_size;
|
||||||
|
|
||||||
/* Check whether we have enough space to not do OFFPAGE. */
|
/* Check whether we have enough space to not do OFFPAGE. */
|
||||||
if ((keg->uk_flags & UMA_ZONE_OFFPAGE) == 0) {
|
if ((keg->uk_flags & UMA_ZONE_OFFPAGE) == 0 &&
|
||||||
shsize = sizeof(struct uma_slab);
|
PAGE_SIZE * keg->uk_ppera - keg->uk_rsize < SIZEOF_UMA_SLAB) {
|
||||||
if (shsize & UMA_ALIGN_PTR)
|
/*
|
||||||
shsize = (shsize & ~UMA_ALIGN_PTR) +
|
* We can't do OFFPAGE if we're internal, in which case
|
||||||
(UMA_ALIGN_PTR + 1);
|
* we need an extra page per allocation to contain the
|
||||||
|
* slab header.
|
||||||
if (PAGE_SIZE * keg->uk_ppera - keg->uk_rsize < shsize) {
|
*/
|
||||||
/*
|
if ((keg->uk_flags & UMA_ZFLAG_INTERNAL) == 0)
|
||||||
* We can't do OFFPAGE if we're internal, in which case
|
keg->uk_flags |= UMA_ZONE_OFFPAGE;
|
||||||
* we need an extra page per allocation to contain the
|
else
|
||||||
* slab header.
|
keg->uk_ppera++;
|
||||||
*/
|
|
||||||
if ((keg->uk_flags & UMA_ZFLAG_INTERNAL) == 0)
|
|
||||||
keg->uk_flags |= UMA_ZONE_OFFPAGE;
|
|
||||||
else
|
|
||||||
keg->uk_ppera++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((keg->uk_flags & UMA_ZONE_OFFPAGE) &&
|
if ((keg->uk_flags & UMA_ZONE_OFFPAGE) &&
|
||||||
@ -1693,20 +1686,11 @@ keg_ctor(void *mem, int size, void *udata, int flags)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're putting the slab header in the actual page we need to
|
* If we're putting the slab header in the actual page we need to
|
||||||
* figure out where in each page it goes. This calculates a right
|
* figure out where in each page it goes. See SIZEOF_UMA_SLAB
|
||||||
* justified offset into the memory on an ALIGN_PTR boundary.
|
* macro definition.
|
||||||
*/
|
*/
|
||||||
if (!(keg->uk_flags & UMA_ZONE_OFFPAGE)) {
|
if (!(keg->uk_flags & UMA_ZONE_OFFPAGE)) {
|
||||||
u_int totsize;
|
keg->uk_pgoff = (PAGE_SIZE * keg->uk_ppera) - SIZEOF_UMA_SLAB;
|
||||||
|
|
||||||
/* Size of the slab struct and free list */
|
|
||||||
totsize = sizeof(struct uma_slab);
|
|
||||||
|
|
||||||
if (totsize & UMA_ALIGN_PTR)
|
|
||||||
totsize = (totsize & ~UMA_ALIGN_PTR) +
|
|
||||||
(UMA_ALIGN_PTR + 1);
|
|
||||||
keg->uk_pgoff = (PAGE_SIZE * keg->uk_ppera) - totsize;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The only way the following is possible is if with our
|
* The only way the following is possible is if with our
|
||||||
* UMA_ALIGN_PTR adjustments we are now bigger than
|
* UMA_ALIGN_PTR adjustments we are now bigger than
|
||||||
@ -1714,13 +1698,10 @@ keg_ctor(void *mem, int size, void *udata, int flags)
|
|||||||
* mathematically possible for all cases, so we make
|
* mathematically possible for all cases, so we make
|
||||||
* sure here anyway.
|
* sure here anyway.
|
||||||
*/
|
*/
|
||||||
totsize = keg->uk_pgoff + sizeof(struct uma_slab);
|
KASSERT(keg->uk_pgoff + sizeof(struct uma_slab) <=
|
||||||
if (totsize > PAGE_SIZE * keg->uk_ppera) {
|
PAGE_SIZE * keg->uk_ppera,
|
||||||
printf("zone %s ipers %d rsize %d size %d\n",
|
("zone %s ipers %d rsize %d size %d slab won't fit",
|
||||||
zone->uz_name, keg->uk_ipers, keg->uk_rsize,
|
zone->uz_name, keg->uk_ipers, keg->uk_rsize, keg->uk_size));
|
||||||
keg->uk_size);
|
|
||||||
panic("UMA slab won't fit.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keg->uk_flags & UMA_ZONE_HASH)
|
if (keg->uk_flags & UMA_ZONE_HASH)
|
||||||
|
@ -139,9 +139,17 @@
|
|||||||
#define UMA_MAX_WASTE 10
|
#define UMA_MAX_WASTE 10
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Size of memory in a not offpage slab available for actual items.
|
* Actual size of uma_slab when it is placed at an end of a page
|
||||||
|
* with pointer sized alignment requirement.
|
||||||
*/
|
*/
|
||||||
#define UMA_SLAB_SPACE (UMA_SLAB_SIZE - sizeof(struct uma_slab))
|
#define SIZEOF_UMA_SLAB ((sizeof(struct uma_slab) & UMA_ALIGN_PTR) ? \
|
||||||
|
(sizeof(struct uma_slab) & ~UMA_ALIGN_PTR) + \
|
||||||
|
(UMA_ALIGN_PTR + 1) : sizeof(struct uma_slab))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Size of memory in a not offpage single page slab available for actual items.
|
||||||
|
*/
|
||||||
|
#define UMA_SLAB_SPACE (PAGE_SIZE - SIZEOF_UMA_SLAB)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* I doubt there will be many cases where this is exceeded. This is the initial
|
* I doubt there will be many cases where this is exceeded. This is the initial
|
||||||
|
Loading…
x
Reference in New Issue
Block a user