|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2011 Free Software Foundation. ! 3: * ! 4: * This program is free software; you can redistribute it and/or modify ! 5: * it under the terms of the GNU General Public License as published by ! 6: * the Free Software Foundation; either version 2 of the License, or ! 7: * (at your option) any later version. ! 8: * ! 9: * This program is distributed in the hope that it will be useful, ! 10: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 12: * GNU General Public License for more details. ! 13: * ! 14: * You should have received a copy of the GNU General Public License along ! 15: * with this program; if not, write to the Free Software Foundation, Inc., ! 16: * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ! 17: */ ! 18: ! 19: /* ! 20: * Copyright (c) 2010, 2011 Richard Braun. ! 21: * All rights reserved. ! 22: * ! 23: * Redistribution and use in source and binary forms, with or without ! 24: * modification, are permitted provided that the following conditions ! 25: * are met: ! 26: * 1. Redistributions of source code must retain the above copyright ! 27: * notice, this list of conditions and the following disclaimer. ! 28: * 2. Redistributions in binary form must reproduce the above copyright ! 29: * notice, this list of conditions and the following disclaimer in the ! 30: * documentation and/or other materials provided with the distribution. ! 31: * ! 32: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ! 33: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ! 34: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ! 35: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ! 36: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ! 37: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ! 38: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ! 39: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ! 40: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ! 41: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ! 42: * ! 43: * ! 44: * Object caching memory allocator. ! 45: */ ! 46: ! 47: #ifndef _KERN_SLAB_H ! 48: #define _KERN_SLAB_H ! 49: ! 50: #include <kern/lock.h> ! 51: #include <kern/list.h> ! 52: #include <kern/rbtree.h> ! 53: #include <mach/machine/vm_types.h> ! 54: #include <sys/types.h> ! 55: #include <vm/vm_types.h> ! 56: ! 57: #if SLAB_USE_CPU_POOLS ! 58: /* ! 59: * L1 cache line size. ! 60: */ ! 61: #define CPU_L1_SIZE (1 << CPU_L1_SHIFT) ! 62: ! 63: /* ! 64: * Per-processor cache of pre-constructed objects. ! 65: * ! 66: * The flags member is a read-only CPU-local copy of the parent cache flags. ! 67: */ ! 68: struct kmem_cpu_pool { ! 69: simple_lock_data_t lock; ! 70: int flags; ! 71: int size; ! 72: int transfer_size; ! 73: int nr_objs; ! 74: void **array; ! 75: } __attribute__((aligned(CPU_L1_SIZE))); ! 76: ! 77: /* ! 78: * When a cache is created, its CPU pool type is determined from the buffer ! 79: * size. For small buffer sizes, many objects can be cached in a CPU pool. ! 80: * Conversely, for large buffer sizes, this would incur much overhead, so only ! 81: * a few objects are stored in a CPU pool. ! 82: */ ! 83: struct kmem_cpu_pool_type { ! 84: size_t buf_size; ! 85: int array_size; ! 86: size_t array_align; ! 87: struct kmem_cache *array_cache; ! 88: }; ! 89: #endif /* SLAB_USE_CPU_POOLS */ ! 90: ! 91: /* ! 92: * Buffer descriptor. ! 93: * ! 94: * For normal caches (i.e. without SLAB_CF_VERIFY), bufctls are located at the ! 95: * end of (but inside) each buffer. If SLAB_CF_VERIFY is set, bufctls are ! 96: * located after each buffer. ! 97: * ! 98: * When an object is allocated to a client, its bufctl isn't used. This memory ! 99: * is instead used for redzoning if cache debugging is in effect. ! 100: */ ! 101: union kmem_bufctl { ! 102: union kmem_bufctl *next; ! 103: unsigned long redzone; ! 104: }; ! 105: ! 106: /* ! 107: * Buffer tag. ! 108: * ! 109: * This structure is only used for SLAB_CF_VERIFY caches. It is located after ! 110: * the bufctl and includes information about the state of the buffer it ! 111: * describes (allocated or not). It should be thought of as a debugging ! 112: * extension of the bufctl. ! 113: */ ! 114: struct kmem_buftag { ! 115: unsigned long state; ! 116: }; ! 117: ! 118: /* ! 119: * Page-aligned collection of unconstructed buffers. ! 120: */ ! 121: struct kmem_slab { ! 122: struct list list_node; ! 123: struct rbtree_node tree_node; ! 124: unsigned long nr_refs; ! 125: union kmem_bufctl *first_free; ! 126: void *addr; ! 127: }; ! 128: ! 129: /* ! 130: * Type for constructor functions. ! 131: * ! 132: * The pre-constructed state of an object is supposed to include only ! 133: * elements such as e.g. linked lists, locks, reference counters. Therefore ! 134: * constructors are expected to 1) never fail and 2) not need any ! 135: * user-provided data. The first constraint implies that object construction ! 136: * never performs dynamic resource allocation, which also means there is no ! 137: * need for destructors. ! 138: */ ! 139: typedef void (*kmem_cache_ctor_t)(void *obj); ! 140: ! 141: /* ! 142: * Types for slab allocation/free functions. ! 143: * ! 144: * All addresses and sizes must be page-aligned. ! 145: */ ! 146: typedef vm_offset_t (*kmem_slab_alloc_fn_t)(vm_size_t); ! 147: typedef void (*kmem_slab_free_fn_t)(vm_offset_t, vm_size_t); ! 148: ! 149: /* ! 150: * Cache name buffer size. ! 151: */ ! 152: #define KMEM_CACHE_NAME_SIZE 32 ! 153: ! 154: /* ! 155: * Cache of objects. ! 156: * ! 157: * Locking order : cpu_pool -> cache. CPU pools locking is ordered by CPU ID. ! 158: */ ! 159: struct kmem_cache { ! 160: #if SLAB_USE_CPU_POOLS ! 161: /* CPU pool layer */ ! 162: struct kmem_cpu_pool cpu_pools[NCPUS]; ! 163: struct kmem_cpu_pool_type *cpu_pool_type; ! 164: #endif /* SLAB_USE_CPU_POOLS */ ! 165: ! 166: /* Slab layer */ ! 167: simple_lock_data_t lock; ! 168: struct list node; /* Cache list linkage */ ! 169: struct list partial_slabs; ! 170: struct list free_slabs; ! 171: struct rbtree active_slabs; ! 172: int flags; ! 173: size_t obj_size; /* User-provided size */ ! 174: size_t align; ! 175: size_t buf_size; /* Aligned object size */ ! 176: size_t bufctl_dist; /* Distance from buffer to bufctl */ ! 177: size_t slab_size; ! 178: size_t color; ! 179: size_t color_max; ! 180: unsigned long bufs_per_slab; ! 181: unsigned long nr_objs; /* Number of allocated objects */ ! 182: unsigned long nr_bufs; /* Total number of buffers */ ! 183: unsigned long nr_slabs; ! 184: unsigned long nr_free_slabs; ! 185: kmem_cache_ctor_t ctor; ! 186: kmem_slab_alloc_fn_t slab_alloc_fn; ! 187: kmem_slab_free_fn_t slab_free_fn; ! 188: char name[KMEM_CACHE_NAME_SIZE]; ! 189: size_t buftag_dist; /* Distance from buffer to buftag */ ! 190: size_t redzone_pad; /* Bytes from end of object to redzone word */ ! 191: }; ! 192: ! 193: /* ! 194: * Mach-style declarations for struct kmem_cache. ! 195: */ ! 196: typedef struct kmem_cache *kmem_cache_t; ! 197: #define KMEM_CACHE_NULL ((kmem_cache_t) 0) ! 198: ! 199: /* ! 200: * VM submap for slab allocations. ! 201: */ ! 202: extern vm_map_t kmem_map; ! 203: ! 204: /* ! 205: * Cache initialization flags. ! 206: */ ! 207: #define KMEM_CACHE_NOCPUPOOL 0x1 /* Don't use the per-cpu pools */ ! 208: #define KMEM_CACHE_NOOFFSLAB 0x2 /* Don't allocate external slab data */ ! 209: #define KMEM_CACHE_NORECLAIM 0x4 /* Never give slabs back to their source, ! 210: implies KMEM_CACHE_NOOFFSLAB */ ! 211: #define KMEM_CACHE_VERIFY 0x8 /* Use debugging facilities */ ! 212: ! 213: /* ! 214: * Initialize a cache. ! 215: */ ! 216: void kmem_cache_init(struct kmem_cache *cache, const char *name, ! 217: size_t obj_size, size_t align, kmem_cache_ctor_t ctor, ! 218: kmem_slab_alloc_fn_t slab_alloc_fn, ! 219: kmem_slab_free_fn_t slab_free_fn, int flags); ! 220: ! 221: /* ! 222: * Allocate an object from a cache. ! 223: */ ! 224: vm_offset_t kmem_cache_alloc(struct kmem_cache *cache); ! 225: ! 226: /* ! 227: * Release an object to its cache. ! 228: */ ! 229: void kmem_cache_free(struct kmem_cache *cache, vm_offset_t obj); ! 230: ! 231: /* ! 232: * Initialize the memory allocator module. ! 233: */ ! 234: void slab_bootstrap(void); ! 235: void slab_init(void); ! 236: ! 237: /* ! 238: * Release free slabs to the VM system. ! 239: */ ! 240: void slab_collect(void); ! 241: ! 242: /* ! 243: * Display a summary of all kernel caches. ! 244: */ ! 245: void slab_info(void); ! 246: ! 247: #endif /* _KERN_SLAB_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.