Index: src/sys/vm/uma_core.c =================================================================== RCS file: /home/ncvs/src/sys/vm/uma_core.c,v retrieving revision 1.100 diff -u -r1.100 uma_core.c --- src/sys/vm/uma_core.c 4 Jul 2004 16:07:44 -0000 1.100 +++ src/sys/vm/uma_core.c 8 Jul 2004 18:28:23 -0000 @@ -1021,7 +1021,7 @@ keg->uk_rsize = rsize; - rsize += 1; /* Account for the byte of linkage */ + rsize += UMA_FRITM_SZ; /* Account for the linkage */ keg->uk_ipers = (UMA_SLAB_SIZE - sizeof(struct uma_slab)) / rsize; keg->uk_ppera = 1; @@ -1044,6 +1044,11 @@ ipers = UMA_SLAB_SIZE / keg->uk_rsize; if ((keg->uk_flags & UMA_ZONE_REFCNT) || (ipers > keg->uk_ipers)) { +#ifdef UMA_DEBUG + printf("UMA decided we need to go offpage for " + "zone: %s, calculated ipers: %d\n", + zone->uz_name, ipers); +#endif keg->uk_flags |= UMA_ZONE_OFFPAGE; if ((keg->uk_flags & UMA_ZONE_MALLOC) == 0) keg->uk_flags |= UMA_ZONE_HASH; @@ -1131,12 +1136,13 @@ keg->uk_init = zero_init; /* - * The +1 byte added to uk_size is to account for the byte of + * The +UMA_FRITM_SZ added to uk_size is to account for the * linkage that is added to the size in zone_small_init(). If * we don't account for this here then we may end up in * zone_small_init() with a calculated 'ipers' of 0. */ - if ((keg->uk_size+1) > (UMA_SLAB_SIZE - sizeof(struct uma_slab))) + if ((keg->uk_size+UMA_FRITM_SZ) > + (UMA_SLAB_SIZE - sizeof(struct uma_slab))) zone_large_init(zone); else zone_small_init(zone); @@ -1178,13 +1184,14 @@ int totsize; /* Size of the slab struct and free list */ - totsize = sizeof(struct uma_slab) + keg->uk_ipers; + totsize = sizeof(struct uma_slab) + + keg->uk_ipers * UMA_FRITM_SZ; if (totsize & UMA_ALIGN_PTR) totsize = (totsize & ~UMA_ALIGN_PTR) + (UMA_ALIGN_PTR + 1); keg->uk_pgoff = UMA_SLAB_SIZE - totsize; totsize = keg->uk_pgoff + sizeof(struct uma_slab) - + keg->uk_ipers; + + keg->uk_ipers * UMA_FRITM_SZ; /* I don't think it's possible, but I'll make sure anyway */ if (totsize > UMA_SLAB_SIZE) { printf("zone %s ipers %d rsize %d size %d\n", @@ -1465,6 +1472,7 @@ slabsize = UMA_SLAB_SIZE - sizeof(struct uma_slab); slabsize /= UMA_MAX_WASTE; slabsize++; /* In case there it's rounded */ + slabsize *= UMA_FRITM_SZ; /* sz of ea freeref in account */ slabsize += sizeof(struct uma_slab); /* Now make a zone for slab headers */ @@ -1480,7 +1488,7 @@ slabsize = UMA_SLAB_SIZE - sizeof(struct uma_slab_refcnt); slabsize /= UMA_MAX_WASTE; slabsize++; - slabsize += 4 * slabsize; + slabsize *= UMA_FRITMREF_SZ; slabsize += sizeof(struct uma_slab_refcnt); slabrefzone = uma_zcreate("UMA RCntSlabs", slabsize, Index: src/sys/vm/uma_int.h =================================================================== RCS file: /home/ncvs/src/sys/vm/uma_int.h,v retrieving revision 1.24 diff -u -r1.24 uma_int.h --- src/sys/vm/uma_int.h 31 May 2004 21:46:05 -0000 1.24 +++ src/sys/vm/uma_int.h 8 Jul 2004 18:28:23 -0000 @@ -232,10 +232,10 @@ unsigned long _us_size; /* Size of allocation */ } us_type; SLIST_ENTRY(uma_slab) us_hlink; /* Link for hash table */ + u_int16_t us_freecount; /* How many are free? */ u_int8_t *us_data; /* First item */ u_int8_t us_flags; /* Page flags see uma.h */ - u_int8_t us_freecount; /* How many are free? */ - u_int8_t us_firstfree; /* First free item index */ + u_int8_t us_firstfree; /* First free item index */ }; /* The standard slab structure */ @@ -266,6 +266,15 @@ #define us_flags us_head.us_flags #define us_freecount us_head.us_freecount #define us_firstfree us_head.us_firstfree + +/* + * These give us the size of one free item reference within our corresponding + * uma_slab structures, so that our calculations during zone setup are correct + * regardless of what the compiler decides to do with padding the structure + * arrays within uma_slab. + */ +#define UMA_FRITM_SZ (sizeof(struct uma_slab) - sizeof(struct uma_slab_head)) +#define UMA_FRITMREF_SZ (sizeof(struct uma_slab_refcnt) - sizeof(struct uma_slab_head)) typedef struct uma_slab * uma_slab_t; typedef struct uma_slab_refcnt * uma_slabrefcnt_t;