Poniżej przedstawione są najważniejsze pola trzech struktur danych: kmem_cache_t (opisującej schowek), kmem_slab_t (opisującej taflę) i cache_sizes_t (specjalnie dla tablicy cache_sizes).
struct kmem_cache_s {
struct list_head slabs;
struct list_head *firstnotfull;
unsigned int objsize;
unsigned int flags;
unsigned int num;
spinlock_t spinlock;
#ifdef CONFIG_SMP
unsigned int batchcount;
#endif
unsigned int gfporder;
unsigned int gfpflags;
size_t colour;
unsigned int colour_off;
unsigned int colour_next;
kmem_cache_t *slabp_cache;
unsigned int growing;
unsigned int dflags;
void (*ctor)(void *, kmem_cache_t *, unsigned long);
void (*dtor)(void *, kmem_cache_t *, unsigned long);
unsigned long failures;
char name[CACHE_NAMELEN];
struct list_head next;
#ifdef CONFIG_SMP
cpucache_t *cpudata[NR_CPUS];
#endif
};
typedef struct kmem_cache_s kmem_cache_t;
typedef struct slab_s {
struct list_head list;
unsigned long colouroff;
void *s_mem;
unsigned int inuse;
kmem_bufctl_t free;
} slab_t;
typedef struct cache_sizes {
size_t cs_size;
kmem_cache_t *cs_cachep;
kmem_cache_t *cs_dmacachep;
} cache_sizes_t;
Interesować nas też będą dwie zmienne:
static kmem_cache_t cache_cache = {
slabs: LIST_HEAD_INIT(cache_cache.slabs),
firstnotfull: &cache_cache.slabs,
objsize: sizeof(kmem_cache_t),
flags: SLAB_NO_REAP,
spinlock: SPIN_LOCK_UNLOCKED,
colour_off: L1_CACHE_BYTES,
name: "kmem_cache",
};
static cache_sizes_t cache_sizes[] = {
#if PAGE_SIZE == 4096
{ 32, NULL, NULL},
#endif
{ 64, NULL, NULL},
{ 128, NULL, NULL},
...
{131072, NULL, NULL},
{ 0, NULL, NULL}
};
Jak widać, początkowo wskaźniki do schowków zawierają wartość NULL.
To normalne: pola te zostaną wypełnione dopiero przy inicjowaniu zarządzania
pamięcią (funkcja kmem_cache_sizes_init).