root/sys/sys/slaballoc.h
/*
 * KERN_SLABALLOC.H     - Kernel SLAB memory allocator
 *
 * Copyright (c) 2003,2004 The DragonFly Project.  All rights reserved.
 *
 * This code is derived from software contributed to The DragonFly Project
 * by Matthew Dillon <dillon@backplane.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name of The DragonFly Project nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific, prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _SYS_SLABALLOC_H_
#define _SYS_SLABALLOC_H_

#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)

#ifndef _SYS__MALLOC_H_
#include <sys/_malloc.h>
#endif
#include <machine/stdint.h>

/*
 * Note that any allocations which are exact multiples of PAGE_SIZE, or
 * which are >= ZALLOC_ZONE_LIMIT, will fall through to the kmem subsystem.
 */
#define ZALLOC_ZONE_LIMIT       (16 * 1024)     /* max slab-managed alloc */
#define ZALLOC_MIN_ZONE_SIZE    (32 * 1024)     /* minimum zone size */
#define ZALLOC_MAX_ZONE_SIZE    (128 * 1024)    /* maximum zone size */
#define ZALLOC_SLAB_MAGIC       0x736c6162      /* magic sanity */
#define ZALLOC_OVSZ_MAGIC       0x736c6163      /* magic sanity */
#define ZALLOC_SLAB_SLIDE       20


#if ZALLOC_ZONE_LIMIT == 16384
#define NZONES                  72
#elif ZALLOC_ZONE_LIMIT == 32768
#define NZONES                  80
#else
#error "I couldn't figure out NZONES"
#endif

/*
 * Chunk structure for free elements
 */
typedef struct SLChunk {
    struct SLChunk *c_Next;
} SLChunk;

#if defined(SLAB_DEBUG)
/*
 * Only used for kernels compiled w/SLAB_DEBUG
 */
struct ZSources {
    const char *file;
    int line;
};

#endif

/*
 * The IN-BAND zone header is placed at the beginning of each zone.
 *
 * NOTE! All fields are cpu-local except z_RChunks.  Remote cpus free
 *       chunks using atomic ops to z_RChunks and then signal local
 *       cpus as necessary.
 */
typedef struct SLZone {
    __int32_t   z_Magic;        /* magic number for sanity check */
    int         z_Cpu;          /* which cpu owns this zone? */
    struct globaldata *z_CpuGd; /* which cpu owns this zone? */
    TAILQ_ENTRY(SLZone) z_Entry;/* ZoneAry[] if z_NFree!=0, else Free*Zones */
    void        *z_UNused01;
    int         z_NFree;        /* total free chunks / ualloc space in zone */
    int         z_NMax;         /* maximum free chunks */
    char        *z_BasePtr;     /* pointer to start of chunk array */
    int         z_UIndex;       /* current initial allocation index */
    int         z_UEndIndex;    /* last (first) allocation index */
    int         z_ChunkSize;    /* chunk size for validation */
    int         z_ZoneIndex;
    int         z_Flags;
    SLChunk     *z_LChunks;     /* linked list of chunks current cpu */
    SLChunk     **z_LChunksp;   /* tailp */
    SLChunk     *z_RChunks;     /* linked list of chunks remote cpu */
    int         z_RSignal;      /* signal interlock */
    int         z_RCount;       /* prevent local destruction w/inflight ipis */
#if defined(SLAB_DEBUG)
#define SLAB_DEBUG_ENTRIES      32      /* must be power of 2 */
    struct ZSources z_Sources[SLAB_DEBUG_ENTRIES];
    struct ZSources z_AltSources[SLAB_DEBUG_ENTRIES];
#endif
#if defined(INVARIANTS)
    __uint32_t  z_Bitmap[];     /* bitmap of free chunks for sanity check */
#endif
} SLZone;

#define SLZF_UNOTZEROD          0x0001

TAILQ_HEAD(SLZoneList, SLZone);
typedef struct SLZoneList SLZoneList;

typedef struct SLGlobalData {
    SLZoneList  ZoneAry[NZONES];        /* linked list of zones NFree > 0 */
    SLZoneList  FreeZones;              /* whole zones that have become free */
    SLZoneList  FreeOvZones;            /* oversized zones */
    int         NFreeZones;             /* free zone count */
    int         JunkIndex;
    struct malloc_type ZoneInfo;        /* stats on meta-zones allocated */
} SLGlobalData;

#endif  /* _KERNEL */

#endif  /* _SYS_SLABALLOC_H_ */