Chapter3:MemoryManagement
As discussed in Section 3.6.3, each slab head is followed by an array with as many entries as there are
objects on the slab. The kernel refers to this array to find the position of the next free object. The data
type used to do this iskmem_bufctl_t, which is nothing more than an ordinaryunsigned intvariable
appropriately abstracted bytypedef.
The number of objectsnumis used to calculate the head size; this is needed to determine the number
of objects in a slab — and is another example of the chicken-and-egg problem. The kernel solves this
problem by systematically incrementing the number of objects to check whether a given configuration
still fits in the available space.
cache_estimateis repeatedly invoked in awhileloop, and each time the availablegfp_orderis incre-
mented by 1 — thus doubling the slab size each time starting with a single page frame. The kernel
terminates the loop and is satisfied with the result ifoneof the following conditions applies:
❑ 8*left_overis less than the size of the slab; that is, less than one-eighth of the space is wasted.
❑ gfp_orderis greater than or equal to the value stored inslab_break_gfp_order.
slab_break_gfp_orderhas the valueBREAK_GFP_ORDER_LO = 1if the machine has less
than 32 MiB of main memory; otherwise, its value isBREAK_GFP_ORDER_HI = 2.
❑ The management head is stored off-slab, and the number of objects is greater than the value
stored inoffslab_limit.offslab_limitspecifies the maximum number ofkmem_bufctl_t
instances that can be held together with an instance ofstruct slabin a memory block reserved
withkmalloc. If the number of objects in a slab exceedsthisvalue,itisnolongerpossibleto
reserve the required space, with the result thatgfp_orderis decremented by 1, the data are
recalculated, and the loop is exited.
Of course, the kernel always makes sure that there is space for at least one object on the slab, as a cache
with no objects makes little sense.
The size of the slab head is rounded to ensure that the entry immediately following the head is properly
aligned.
mm/slab.c
...
slab_size = ALIGN(cachep->num*sizeof(kmem_bufctl_t)
+ sizeof(struct slab), align);
...
ALIGN(x,y)is a standard macro provided by the kernel that computes the required space that is sufficient
to store the objectx, but is additionally an integer-valued multiple ofalign. Table 3-9 provides some
exemplary alignment calculations.
If sufficient free space is available to store the slab head on-slab although it should actually be stored
off-slab, the kernel gladly makes use of the opportunity. TheCFLGS_OFF_SLABis deleted, and the head is
stored on the slab despite the earlier decision to do the opposite or despite the default setting.
The following steps are performed to color the slab:
mm/slab.c
cachep->colour_off = cache_line_size();
/* Offset must be a multiple of the alignment. */