Annotation of Gnu-Mach/kern/slab.c, revision 1.1.1.1

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 and general purpose memory allocator.
                     45:  *
                     46:  * This allocator is based on the paper "The Slab Allocator: An Object-Caching
                     47:  * Kernel Memory Allocator" by Jeff Bonwick.
                     48:  *
                     49:  * It allows the allocation of objects (i.e. fixed-size typed buffers) from
                     50:  * caches and is efficient in both space and time. This implementation follows
                     51:  * many of the indications from the paper mentioned. The most notable
                     52:  * differences are outlined below.
                     53:  *
                     54:  * The per-cache self-scaling hash table for buffer-to-bufctl conversion,
                     55:  * described in 3.2.3 "Slab Layout for Large Objects", has been replaced by
                     56:  * a red-black tree storing slabs, sorted by address. The use of a
                     57:  * self-balancing tree for buffer-to-slab conversions provides a few advantages
                     58:  * over a hash table. Unlike a hash table, a BST provides a "lookup nearest"
                     59:  * operation, so obtaining the slab data (whether it is embedded in the slab or
                     60:  * off slab) from a buffer address simply consists of a "lookup nearest towards
                     61:  * 0" tree search. Storing slabs instead of buffers also considerably reduces
                     62:  * the number of elements to retain. Finally, a self-balancing tree is a true
                     63:  * self-scaling data structure, whereas a hash table requires periodic
                     64:  * maintenance and complete resizing, which is expensive. The only drawback is
                     65:  * that releasing a buffer to the slab layer takes logarithmic time instead of
                     66:  * constant time. But as the data set size is kept reasonable (because slabs
                     67:  * are stored instead of buffers) and because the CPU pool layer services most
                     68:  * requests, avoiding many accesses to the slab layer, it is considered an
                     69:  * acceptable tradeoff.
                     70:  *
                     71:  * This implementation uses per-cpu pools of objects, which service most
                     72:  * allocation requests. These pools act as caches (but are named differently
                     73:  * to avoid confusion with CPU caches) that reduce contention on multiprocessor
                     74:  * systems. When a pool is empty and cannot provide an object, it is filled by
                     75:  * transferring multiple objects from the slab layer. The symmetric case is
                     76:  * handled likewise.
                     77:  */
                     78: 
                     79: #include <string.h>
                     80: #include <kern/assert.h>
                     81: #include <kern/mach_clock.h>
                     82: #include <kern/printf.h>
                     83: #include <kern/slab.h>
                     84: #include <kern/kalloc.h>
                     85: #include <kern/cpu_number.h>
                     86: #include <mach/vm_param.h>
                     87: #include <mach/machine/vm_types.h>
                     88: #include <vm/vm_kern.h>
                     89: #include <vm/vm_types.h>
                     90: #include <sys/types.h>
                     91: 
                     92: #ifdef MACH_DEBUG
                     93: #include <mach_debug/slab_info.h>
                     94: #endif
                     95: 
                     96: /*
                     97:  * Utility macros.
                     98:  */
                     99: #define ARRAY_SIZE(x)   (sizeof(x) / sizeof((x)[0]))
                    100: #define P2ALIGNED(x, a) (((x) & ((a) - 1)) == 0)
                    101: #define ISP2(x)         P2ALIGNED(x, x)
                    102: #define P2ALIGN(x, a)   ((x) & -(a))
                    103: #define P2ROUND(x, a)   (-(-(x) & -(a)))
                    104: #define P2END(x, a)     (-(~(x) & -(a)))
                    105: #define likely(expr)    __builtin_expect(!!(expr), 1)
                    106: #define unlikely(expr)  __builtin_expect(!!(expr), 0)
                    107: 
                    108: /*
                    109:  * Minimum required alignment.
                    110:  */
                    111: #define KMEM_ALIGN_MIN 8
                    112: 
                    113: /*
                    114:  * Minimum number of buffers per slab.
                    115:  *
                    116:  * This value is ignored when the slab size exceeds a threshold.
                    117:  */
                    118: #define KMEM_MIN_BUFS_PER_SLAB 8
                    119: 
                    120: /*
                    121:  * Special slab size beyond which the minimum number of buffers per slab is
                    122:  * ignored when computing the slab size of a cache.
                    123:  */
                    124: #define KMEM_SLAB_SIZE_THRESHOLD (8 * PAGE_SIZE)
                    125: 
                    126: /*
                    127:  * Special buffer size under which slab data is unconditionnally allocated
                    128:  * from its associated slab.
                    129:  */
                    130: #define KMEM_BUF_SIZE_THRESHOLD (PAGE_SIZE / 8)
                    131: 
                    132: /*
                    133:  * Time (in ticks) between two garbage collection operations.
                    134:  */
                    135: #define KMEM_GC_INTERVAL (5 * hz)
                    136: 
                    137: /*
                    138:  * The transfer size of a CPU pool is computed by dividing the pool size by
                    139:  * this value.
                    140:  */
                    141: #define KMEM_CPU_POOL_TRANSFER_RATIO 2
                    142: 
                    143: /*
                    144:  * Redzone guard word.
                    145:  */
                    146: #ifdef __LP64__
                    147: #if _HOST_BIG_ENDIAN
                    148: #define KMEM_REDZONE_WORD 0xfeedfacefeedfaceUL
                    149: #else /* _HOST_BIG_ENDIAN */
                    150: #define KMEM_REDZONE_WORD 0xcefaedfecefaedfeUL
                    151: #endif /* _HOST_BIG_ENDIAN */
                    152: #else /* __LP64__ */
                    153: #if _HOST_BIG_ENDIAN
                    154: #define KMEM_REDZONE_WORD 0xfeedfaceUL
                    155: #else /* _HOST_BIG_ENDIAN */
                    156: #define KMEM_REDZONE_WORD 0xcefaedfeUL
                    157: #endif /* _HOST_BIG_ENDIAN */
                    158: #endif /* __LP64__ */
                    159: 
                    160: /*
                    161:  * Redzone byte for padding.
                    162:  */
                    163: #define KMEM_REDZONE_BYTE 0xbb
                    164: 
                    165: /*
                    166:  * Size of the VM submap from which default backend functions allocate.
                    167:  */
                    168: #define KMEM_MAP_SIZE (128 * 1024 * 1024)
                    169: 
                    170: /*
                    171:  * Shift for the first kalloc cache size.
                    172:  */
                    173: #define KALLOC_FIRST_SHIFT 5
                    174: 
                    175: /*
                    176:  * Number of caches backing general purpose allocations.
                    177:  */
                    178: #define KALLOC_NR_CACHES 13
                    179: 
                    180: /*
                    181:  * Values the buftag state member can take.
                    182:  */
                    183: #ifdef __LP64__
                    184: #if _HOST_BIG_ENDIAN
                    185: #define KMEM_BUFTAG_ALLOC   0xa110c8eda110c8edUL
                    186: #define KMEM_BUFTAG_FREE    0xf4eeb10cf4eeb10cUL
                    187: #else /* _HOST_BIG_ENDIAN */
                    188: #define KMEM_BUFTAG_ALLOC   0xedc810a1edc810a1UL
                    189: #define KMEM_BUFTAG_FREE    0x0cb1eef40cb1eef4UL
                    190: #endif /* _HOST_BIG_ENDIAN */
                    191: #else /* __LP64__ */
                    192: #if _HOST_BIG_ENDIAN
                    193: #define KMEM_BUFTAG_ALLOC   0xa110c8edUL
                    194: #define KMEM_BUFTAG_FREE    0xf4eeb10cUL
                    195: #else /* _HOST_BIG_ENDIAN */
                    196: #define KMEM_BUFTAG_ALLOC   0xedc810a1UL
                    197: #define KMEM_BUFTAG_FREE    0x0cb1eef4UL
                    198: #endif /* _HOST_BIG_ENDIAN */
                    199: #endif /* __LP64__ */
                    200: 
                    201: /*
                    202:  * Free and uninitialized patterns.
                    203:  *
                    204:  * These values are unconditionnally 64-bit wide since buffers are at least
                    205:  * 8-byte aligned.
                    206:  */
                    207: #if _HOST_BIG_ENDIAN
                    208: #define KMEM_FREE_PATTERN   0xdeadbeefdeadbeefULL
                    209: #define KMEM_UNINIT_PATTERN 0xbaddcafebaddcafeULL
                    210: #else /* _HOST_BIG_ENDIAN */
                    211: #define KMEM_FREE_PATTERN   0xefbeaddeefbeaddeULL
                    212: #define KMEM_UNINIT_PATTERN 0xfecaddbafecaddbaULL
                    213: #endif /* _HOST_BIG_ENDIAN */
                    214: 
                    215: /*
                    216:  * Cache flags.
                    217:  *
                    218:  * The flags don't change once set and can be tested without locking.
                    219:  */
                    220: #define KMEM_CF_NO_CPU_POOL     0x01    /* CPU pool layer disabled */
                    221: #define KMEM_CF_SLAB_EXTERNAL   0x02    /* Slab data is off slab */
                    222: #define KMEM_CF_NO_RECLAIM      0x04    /* Slabs are not reclaimable */
                    223: #define KMEM_CF_VERIFY          0x08    /* Debugging facilities enabled */
                    224: #define KMEM_CF_DIRECT          0x10    /* No buf-to-slab tree lookup */
                    225: 
                    226: /*
                    227:  * Options for kmem_cache_alloc_verify().
                    228:  */
                    229: #define KMEM_AV_NOCONSTRUCT 0
                    230: #define KMEM_AV_CONSTRUCT   1
                    231: 
                    232: /*
                    233:  * Error codes for kmem_cache_error().
                    234:  */
                    235: #define KMEM_ERR_INVALID    0   /* Invalid address being freed */
                    236: #define KMEM_ERR_DOUBLEFREE 1   /* Freeing already free address */
                    237: #define KMEM_ERR_BUFTAG     2   /* Invalid buftag content */
                    238: #define KMEM_ERR_MODIFIED   3   /* Buffer modified while free */
                    239: #define KMEM_ERR_REDZONE    4   /* Redzone violation */
                    240: 
                    241: #if SLAB_USE_CPU_POOLS
                    242: /*
                    243:  * Available CPU pool types.
                    244:  *
                    245:  * For each entry, the CPU pool size applies from the entry buf_size
                    246:  * (excluded) up to (and including) the buf_size of the preceding entry.
                    247:  *
                    248:  * See struct kmem_cpu_pool_type for a description of the values.
                    249:  */
                    250: static struct kmem_cpu_pool_type kmem_cpu_pool_types[] = {
                    251:     {  32768,   1, 0,           NULL },
                    252:     {   4096,   8, CPU_L1_SIZE, NULL },
                    253:     {    256,  64, CPU_L1_SIZE, NULL },
                    254:     {      0, 128, CPU_L1_SIZE, NULL }
                    255: };
                    256: 
                    257: /*
                    258:  * Caches where CPU pool arrays are allocated from.
                    259:  */
                    260: static struct kmem_cache kmem_cpu_array_caches[ARRAY_SIZE(kmem_cpu_pool_types)];
                    261: #endif /* SLAB_USE_CPU_POOLS */
                    262: 
                    263: /*
                    264:  * Cache for off slab data.
                    265:  */
                    266: static struct kmem_cache kmem_slab_cache;
                    267: 
                    268: /*
                    269:  * General purpose caches array.
                    270:  */
                    271: static struct kmem_cache kalloc_caches[KALLOC_NR_CACHES];
                    272: 
                    273: /*
                    274:  * List of all caches managed by the allocator.
                    275:  */
                    276: static struct list kmem_cache_list;
                    277: static unsigned int kmem_nr_caches;
                    278: static simple_lock_data_t __attribute__((used)) kmem_cache_list_lock;
                    279: 
                    280: /*
                    281:  * VM submap for slab caches.
                    282:  */
                    283: static struct vm_map kmem_map_store;
                    284: vm_map_t kmem_map = &kmem_map_store;
                    285: 
                    286: /*
                    287:  * Time of the last memory reclaim, in clock ticks.
                    288:  */
                    289: static unsigned long kmem_gc_last_tick;
                    290: 
                    291: #define kmem_error(format, ...)                         \
                    292:     printf("mem: error: %s(): " format "\n", __func__,  \
                    293:            ## __VA_ARGS__)
                    294: 
                    295: #define kmem_warn(format, ...)                              \
                    296:     printf("mem: warning: %s(): " format "\n", __func__,    \
                    297:            ## __VA_ARGS__)
                    298: 
                    299: #define kmem_print(format, ...) \
                    300:     printf(format "\n", ## __VA_ARGS__)
                    301: 
                    302: static void kmem_cache_error(struct kmem_cache *cache, void *buf, int error,
                    303:                              void *arg);
                    304: static void * kmem_cache_alloc_from_slab(struct kmem_cache *cache);
                    305: static void kmem_cache_free_to_slab(struct kmem_cache *cache, void *buf);
                    306: 
                    307: static void * kmem_buf_verify_bytes(void *buf, void *pattern, size_t size)
                    308: {
                    309:     char *ptr, *pattern_ptr, *end;
                    310: 
                    311:     end = buf + size;
                    312: 
                    313:     for (ptr = buf, pattern_ptr = pattern; ptr < end; ptr++, pattern_ptr++)
                    314:         if (*ptr != *pattern_ptr)
                    315:             return ptr;
                    316: 
                    317:     return NULL;
                    318: }
                    319: 
                    320: static void * kmem_buf_verify(void *buf, uint64_t pattern, vm_size_t size)
                    321: {
                    322:     uint64_t *ptr, *end;
                    323: 
                    324:     assert(P2ALIGNED((unsigned long)buf, sizeof(uint64_t)));
                    325:     assert(P2ALIGNED(size, sizeof(uint64_t)));
                    326: 
                    327:     end = buf + size;
                    328: 
                    329:     for (ptr = buf; ptr < end; ptr++)
                    330:         if (*ptr != pattern)
                    331:             return kmem_buf_verify_bytes(ptr, &pattern, sizeof(pattern));
                    332: 
                    333:     return NULL;
                    334: }
                    335: 
                    336: static void kmem_buf_fill(void *buf, uint64_t pattern, size_t size)
                    337: {
                    338:     uint64_t *ptr, *end;
                    339: 
                    340:     assert(P2ALIGNED((unsigned long)buf, sizeof(uint64_t)));
                    341:     assert(P2ALIGNED(size, sizeof(uint64_t)));
                    342: 
                    343:     end = buf + size;
                    344: 
                    345:     for (ptr = buf; ptr < end; ptr++)
                    346:         *ptr = pattern;
                    347: }
                    348: 
                    349: static void * kmem_buf_verify_fill(void *buf, uint64_t old, uint64_t new,
                    350:                                    size_t size)
                    351: {
                    352:     uint64_t *ptr, *end;
                    353: 
                    354:     assert(P2ALIGNED((unsigned long)buf, sizeof(uint64_t)));
                    355:     assert(P2ALIGNED(size, sizeof(uint64_t)));
                    356: 
                    357:     end = buf + size;
                    358: 
                    359:     for (ptr = buf; ptr < end; ptr++) {
                    360:         if (*ptr != old)
                    361:             return kmem_buf_verify_bytes(ptr, &old, sizeof(old));
                    362: 
                    363:         *ptr = new;
                    364:     }
                    365: 
                    366:     return NULL;
                    367: }
                    368: 
                    369: static inline union kmem_bufctl *
                    370: kmem_buf_to_bufctl(void *buf, struct kmem_cache *cache)
                    371: {
                    372:     return (union kmem_bufctl *)(buf + cache->bufctl_dist);
                    373: }
                    374: 
                    375: static inline struct kmem_buftag *
                    376: kmem_buf_to_buftag(void *buf, struct kmem_cache *cache)
                    377: {
                    378:     return (struct kmem_buftag *)(buf + cache->buftag_dist);
                    379: }
                    380: 
                    381: static inline void * kmem_bufctl_to_buf(union kmem_bufctl *bufctl,
                    382:                                         struct kmem_cache *cache)
                    383: {
                    384:     return (void *)bufctl - cache->bufctl_dist;
                    385: }
                    386: 
                    387: static vm_offset_t kmem_pagealloc(vm_size_t size)
                    388: {
                    389:     vm_offset_t addr;
                    390:     kern_return_t kr;
                    391: 
                    392:     kr = kmem_alloc_wired(kmem_map, &addr, size);
                    393: 
                    394:     if (kr != KERN_SUCCESS)
                    395:         return 0;
                    396: 
                    397:     return addr;
                    398: }
                    399: 
                    400: static void kmem_pagefree(vm_offset_t ptr, vm_size_t size)
                    401: {
                    402:     kmem_free(kmem_map, ptr, size);
                    403: }
                    404: 
                    405: static void kmem_slab_create_verify(struct kmem_slab *slab,
                    406:                                     struct kmem_cache *cache)
                    407: {
                    408:     struct kmem_buftag *buftag;
                    409:     size_t buf_size;
                    410:     unsigned long buffers;
                    411:     void *buf;
                    412: 
                    413:     buf_size = cache->buf_size;
                    414:     buf = slab->addr;
                    415:     buftag = kmem_buf_to_buftag(buf, cache);
                    416: 
                    417:     for (buffers = cache->bufs_per_slab; buffers != 0; buffers--) {
                    418:         kmem_buf_fill(buf, KMEM_FREE_PATTERN, cache->bufctl_dist);
                    419:         buftag->state = KMEM_BUFTAG_FREE;
                    420:         buf += buf_size;
                    421:         buftag = kmem_buf_to_buftag(buf, cache);
                    422:     }
                    423: }
                    424: 
                    425: /*
                    426:  * Create an empty slab for a cache.
                    427:  *
                    428:  * The caller must drop all locks before calling this function.
                    429:  */
                    430: static struct kmem_slab * kmem_slab_create(struct kmem_cache *cache,
                    431:                                            size_t color)
                    432: {
                    433:     struct kmem_slab *slab;
                    434:     union kmem_bufctl *bufctl;
                    435:     size_t buf_size;
                    436:     unsigned long buffers;
                    437:     void *slab_buf;
                    438: 
                    439:     if (cache->slab_alloc_fn == NULL)
                    440:         slab_buf = (void *)kmem_pagealloc(cache->slab_size);
                    441:     else
                    442:         slab_buf = (void *)cache->slab_alloc_fn(cache->slab_size);
                    443: 
                    444:     if (slab_buf == NULL)
                    445:         return NULL;
                    446: 
                    447:     if (cache->flags & KMEM_CF_SLAB_EXTERNAL) {
                    448:         assert(!(cache->flags & KMEM_CF_NO_RECLAIM));
                    449:         slab = (struct kmem_slab *)kmem_cache_alloc(&kmem_slab_cache);
                    450: 
                    451:         if (slab == NULL) {
                    452:             if (cache->slab_free_fn == NULL)
                    453:                 kmem_pagefree((vm_offset_t)slab_buf, cache->slab_size);
                    454:             else
                    455:                 cache->slab_free_fn((vm_offset_t)slab_buf, cache->slab_size);
                    456: 
                    457:             return NULL;
                    458:         }
                    459:     } else {
                    460:         slab = (struct kmem_slab *)(slab_buf + cache->slab_size) - 1;
                    461:     }
                    462: 
                    463:     list_node_init(&slab->list_node);
                    464:     rbtree_node_init(&slab->tree_node);
                    465:     slab->nr_refs = 0;
                    466:     slab->first_free = NULL;
                    467:     slab->addr = slab_buf + color;
                    468: 
                    469:     buf_size = cache->buf_size;
                    470:     bufctl = kmem_buf_to_bufctl(slab->addr, cache);
                    471: 
                    472:     for (buffers = cache->bufs_per_slab; buffers != 0; buffers--) {
                    473:         bufctl->next = slab->first_free;
                    474:         slab->first_free = bufctl;
                    475:         bufctl = (union kmem_bufctl *)((void *)bufctl + buf_size);
                    476:     }
                    477: 
                    478:     if (cache->flags & KMEM_CF_VERIFY)
                    479:         kmem_slab_create_verify(slab, cache);
                    480: 
                    481:     return slab;
                    482: }
                    483: 
                    484: static void kmem_slab_destroy_verify(struct kmem_slab *slab,
                    485:                                      struct kmem_cache *cache)
                    486: {
                    487:     struct kmem_buftag *buftag;
                    488:     size_t buf_size;
                    489:     unsigned long buffers;
                    490:     void *buf, *addr;
                    491: 
                    492:     buf_size = cache->buf_size;
                    493:     buf = slab->addr;
                    494:     buftag = kmem_buf_to_buftag(buf, cache);
                    495: 
                    496:     for (buffers = cache->bufs_per_slab; buffers != 0; buffers--) {
                    497:         if (buftag->state != KMEM_BUFTAG_FREE)
                    498:             kmem_cache_error(cache, buf, KMEM_ERR_BUFTAG, buftag);
                    499: 
                    500:         addr = kmem_buf_verify(buf, KMEM_FREE_PATTERN, cache->bufctl_dist);
                    501: 
                    502:         if (addr != NULL)
                    503:             kmem_cache_error(cache, buf, KMEM_ERR_MODIFIED, addr);
                    504: 
                    505:         buf += buf_size;
                    506:         buftag = kmem_buf_to_buftag(buf, cache);
                    507:     }
                    508: }
                    509: 
                    510: /*
                    511:  * Destroy a slab.
                    512:  *
                    513:  * The caller must drop all locks before calling this function.
                    514:  */
                    515: static void kmem_slab_destroy(struct kmem_slab *slab, struct kmem_cache *cache)
                    516: {
                    517:     vm_offset_t slab_buf;
                    518: 
                    519:     assert(slab->nr_refs == 0);
                    520:     assert(slab->first_free != NULL);
                    521:     assert(!(cache->flags & KMEM_CF_NO_RECLAIM));
                    522: 
                    523:     if (cache->flags & KMEM_CF_VERIFY)
                    524:         kmem_slab_destroy_verify(slab, cache);
                    525: 
                    526:     slab_buf = (vm_offset_t)P2ALIGN((unsigned long)slab->addr, PAGE_SIZE);
                    527: 
                    528:     if (cache->slab_free_fn == NULL)
                    529:         kmem_pagefree(slab_buf, cache->slab_size);
                    530:     else
                    531:         cache->slab_free_fn(slab_buf, cache->slab_size);
                    532: 
                    533:     if (cache->flags & KMEM_CF_SLAB_EXTERNAL)
                    534:         kmem_cache_free(&kmem_slab_cache, (vm_offset_t)slab);
                    535: }
                    536: 
                    537: static inline int kmem_slab_use_tree(int flags)
                    538: {
                    539:     return !(flags & KMEM_CF_DIRECT) || (flags & KMEM_CF_VERIFY);
                    540: }
                    541: 
                    542: static inline int kmem_slab_cmp_lookup(const void *addr,
                    543:                                        const struct rbtree_node *node)
                    544: {
                    545:     struct kmem_slab *slab;
                    546: 
                    547:     slab = rbtree_entry(node, struct kmem_slab, tree_node);
                    548: 
                    549:     if (addr == slab->addr)
                    550:         return 0;
                    551:     else if (addr < slab->addr)
                    552:         return -1;
                    553:     else
                    554:         return 1;
                    555: }
                    556: 
                    557: static inline int kmem_slab_cmp_insert(const struct rbtree_node *a,
                    558:                                        const struct rbtree_node *b)
                    559: {
                    560:     struct kmem_slab *slab;
                    561: 
                    562:     slab = rbtree_entry(a, struct kmem_slab, tree_node);
                    563:     return kmem_slab_cmp_lookup(slab->addr, b);
                    564: }
                    565: 
                    566: #if SLAB_USE_CPU_POOLS
                    567: static void kmem_cpu_pool_init(struct kmem_cpu_pool *cpu_pool,
                    568:                                struct kmem_cache *cache)
                    569: {
                    570:     simple_lock_init(&cpu_pool->lock);
                    571:     cpu_pool->flags = cache->flags;
                    572:     cpu_pool->size = 0;
                    573:     cpu_pool->transfer_size = 0;
                    574:     cpu_pool->nr_objs = 0;
                    575:     cpu_pool->array = NULL;
                    576: }
                    577: 
                    578: /*
                    579:  * Return a CPU pool.
                    580:  *
                    581:  * This function will generally return the pool matching the CPU running the
                    582:  * calling thread. Because of context switches and thread migration, the
                    583:  * caller might be running on another processor after this function returns.
                    584:  * Although not optimal, this should rarely happen, and it doesn't affect the
                    585:  * allocator operations in any other way, as CPU pools are always valid, and
                    586:  * their access is serialized by a lock.
                    587:  */
                    588: static inline struct kmem_cpu_pool * kmem_cpu_pool_get(struct kmem_cache *cache)
                    589: {
                    590:     return &cache->cpu_pools[cpu_number()];
                    591: }
                    592: 
                    593: static inline void kmem_cpu_pool_build(struct kmem_cpu_pool *cpu_pool,
                    594:                                        struct kmem_cache *cache, void **array)
                    595: {
                    596:     cpu_pool->size = cache->cpu_pool_type->array_size;
                    597:     cpu_pool->transfer_size = (cpu_pool->size
                    598:                                + KMEM_CPU_POOL_TRANSFER_RATIO - 1)
                    599:                               / KMEM_CPU_POOL_TRANSFER_RATIO;
                    600:     cpu_pool->array = array;
                    601: }
                    602: 
                    603: static inline void * kmem_cpu_pool_pop(struct kmem_cpu_pool *cpu_pool)
                    604: {
                    605:     cpu_pool->nr_objs--;
                    606:     return cpu_pool->array[cpu_pool->nr_objs];
                    607: }
                    608: 
                    609: static inline void kmem_cpu_pool_push(struct kmem_cpu_pool *cpu_pool, void *obj)
                    610: {
                    611:     cpu_pool->array[cpu_pool->nr_objs] = obj;
                    612:     cpu_pool->nr_objs++;
                    613: }
                    614: 
                    615: static int kmem_cpu_pool_fill(struct kmem_cpu_pool *cpu_pool,
                    616:                               struct kmem_cache *cache)
                    617: {
                    618:     kmem_cache_ctor_t ctor;
                    619:     void *buf;
                    620:     int i;
                    621: 
                    622:     ctor = (cpu_pool->flags & KMEM_CF_VERIFY) ? NULL : cache->ctor;
                    623: 
                    624:     simple_lock(&cache->lock);
                    625: 
                    626:     for (i = 0; i < cpu_pool->transfer_size; i++) {
                    627:         buf = kmem_cache_alloc_from_slab(cache);
                    628: 
                    629:         if (buf == NULL)
                    630:             break;
                    631: 
                    632:         if (ctor != NULL)
                    633:             ctor(buf);
                    634: 
                    635:         kmem_cpu_pool_push(cpu_pool, buf);
                    636:     }
                    637: 
                    638:     simple_unlock(&cache->lock);
                    639: 
                    640:     return i;
                    641: }
                    642: 
                    643: static void kmem_cpu_pool_drain(struct kmem_cpu_pool *cpu_pool,
                    644:                                 struct kmem_cache *cache)
                    645: {
                    646:     void *obj;
                    647:     int i;
                    648: 
                    649:     simple_lock(&cache->lock);
                    650: 
                    651:     for (i = cpu_pool->transfer_size; i > 0; i--) {
                    652:         obj = kmem_cpu_pool_pop(cpu_pool);
                    653:         kmem_cache_free_to_slab(cache, obj);
                    654:     }
                    655: 
                    656:     simple_unlock(&cache->lock);
                    657: }
                    658: #endif /* SLAB_USE_CPU_POOLS */
                    659: 
                    660: static void kmem_cache_error(struct kmem_cache *cache, void *buf, int error,
                    661:                              void *arg)
                    662: {
                    663:     struct kmem_buftag *buftag;
                    664: 
                    665:     kmem_error("cache: %s, buffer: %p", cache->name, (void *)buf);
                    666: 
                    667:     switch(error) {
                    668:     case KMEM_ERR_INVALID:
                    669:         kmem_error("freeing invalid address");
                    670:         break;
                    671:     case KMEM_ERR_DOUBLEFREE:
                    672:         kmem_error("attempting to free the same address twice");
                    673:         break;
                    674:     case KMEM_ERR_BUFTAG:
                    675:         buftag = arg;
                    676:         kmem_error("invalid buftag content, buftag state: %p",
                    677:                    (void *)buftag->state);
                    678:         break;
                    679:     case KMEM_ERR_MODIFIED:
                    680:         kmem_error("free buffer modified, fault address: %p, "
                    681:                    "offset in buffer: %td", arg, arg - buf);
                    682:         break;
                    683:     case KMEM_ERR_REDZONE:
                    684:         kmem_error("write beyond end of buffer, fault address: %p, "
                    685:                    "offset in buffer: %td", arg, arg - buf);
                    686:         break;
                    687:     default:
                    688:         kmem_error("unknown error");
                    689:     }
                    690: 
                    691:     /*
                    692:      * Never reached.
                    693:      */
                    694: }
                    695: 
                    696: /*
                    697:  * Compute an appropriate slab size for the given cache.
                    698:  *
                    699:  * Once the slab size is known, this function sets the related properties
                    700:  * (buffers per slab and maximum color). It can also set the KMEM_CF_DIRECT
                    701:  * and/or KMEM_CF_SLAB_EXTERNAL flags depending on the resulting layout.
                    702:  */
                    703: static void kmem_cache_compute_sizes(struct kmem_cache *cache, int flags)
                    704: {
                    705:     size_t i, buffers, buf_size, slab_size, free_slab_size, optimal_size;
                    706:     size_t waste, waste_min;
                    707:     int embed, optimal_embed = optimal_embed;
                    708: 
                    709:     buf_size = cache->buf_size;
                    710: 
                    711:     if (buf_size < KMEM_BUF_SIZE_THRESHOLD)
                    712:         flags |= KMEM_CACHE_NOOFFSLAB;
                    713: 
                    714:     i = 0;
                    715:     waste_min = (size_t)-1;
                    716: 
                    717:     do {
                    718:         i++;
                    719:         slab_size = P2ROUND(i * buf_size, PAGE_SIZE);
                    720:         free_slab_size = slab_size;
                    721: 
                    722:         if (flags & KMEM_CACHE_NOOFFSLAB)
                    723:             free_slab_size -= sizeof(struct kmem_slab);
                    724: 
                    725:         buffers = free_slab_size / buf_size;
                    726:         waste = free_slab_size % buf_size;
                    727: 
                    728:         if (buffers > i)
                    729:             i = buffers;
                    730: 
                    731:         if (flags & KMEM_CACHE_NOOFFSLAB)
                    732:             embed = 1;
                    733:         else if (sizeof(struct kmem_slab) <= waste) {
                    734:             embed = 1;
                    735:             waste -= sizeof(struct kmem_slab);
                    736:         } else {
                    737:             embed = 0;
                    738:         }
                    739: 
                    740:         if (waste <= waste_min) {
                    741:             waste_min = waste;
                    742:             optimal_size = slab_size;
                    743:             optimal_embed = embed;
                    744:         }
                    745:     } while ((buffers < KMEM_MIN_BUFS_PER_SLAB)
                    746:              && (slab_size < KMEM_SLAB_SIZE_THRESHOLD));
                    747: 
                    748:     assert(!(flags & KMEM_CACHE_NOOFFSLAB) || optimal_embed);
                    749: 
                    750:     cache->slab_size = optimal_size;
                    751:     slab_size = cache->slab_size - (optimal_embed
                    752:                 ? sizeof(struct kmem_slab)
                    753:                 : 0);
                    754:     cache->bufs_per_slab = slab_size / buf_size;
                    755:     cache->color_max = slab_size % buf_size;
                    756: 
                    757:     if (cache->color_max >= PAGE_SIZE)
                    758:         cache->color_max = PAGE_SIZE - 1;
                    759: 
                    760:     if (optimal_embed) {
                    761:         if (cache->slab_size == PAGE_SIZE)
                    762:             cache->flags |= KMEM_CF_DIRECT;
                    763:     } else {
                    764:         cache->flags |= KMEM_CF_SLAB_EXTERNAL;
                    765:     }
                    766: }
                    767: 
                    768: void kmem_cache_init(struct kmem_cache *cache, const char *name,
                    769:                      size_t obj_size, size_t align, kmem_cache_ctor_t ctor,
                    770:                      kmem_slab_alloc_fn_t slab_alloc_fn,
                    771:                      kmem_slab_free_fn_t slab_free_fn, int flags)
                    772: {
                    773: #if SLAB_USE_CPU_POOLS
                    774:     struct kmem_cpu_pool_type *cpu_pool_type;
                    775:     size_t i;
                    776: #endif /* SLAB_USE_CPU_POOLS */
                    777:     size_t buf_size;
                    778: 
                    779: #if SLAB_VERIFY
                    780:     cache->flags = KMEM_CF_VERIFY;
                    781: #else /* SLAB_VERIFY */
                    782:     cache->flags = 0;
                    783: #endif /* SLAB_VERIFY */
                    784: 
                    785:     if (flags & KMEM_CACHE_NOCPUPOOL)
                    786:         cache->flags |= KMEM_CF_NO_CPU_POOL;
                    787: 
                    788:     if (flags & KMEM_CACHE_NORECLAIM) {
                    789:         assert(slab_free_fn == NULL);
                    790:         flags |= KMEM_CACHE_NOOFFSLAB;
                    791:         cache->flags |= KMEM_CF_NO_RECLAIM;
                    792:     }
                    793: 
                    794:     if (flags & KMEM_CACHE_VERIFY)
                    795:         cache->flags |= KMEM_CF_VERIFY;
                    796: 
                    797:     if (align < KMEM_ALIGN_MIN)
                    798:         align = KMEM_ALIGN_MIN;
                    799: 
                    800:     assert(obj_size > 0);
                    801:     assert(ISP2(align));
                    802:     assert(align < PAGE_SIZE);
                    803: 
                    804:     buf_size = P2ROUND(obj_size, align);
                    805: 
                    806:     simple_lock_init(&cache->lock);
                    807:     list_node_init(&cache->node);
                    808:     list_init(&cache->partial_slabs);
                    809:     list_init(&cache->free_slabs);
                    810:     rbtree_init(&cache->active_slabs);
                    811:     cache->obj_size = obj_size;
                    812:     cache->align = align;
                    813:     cache->buf_size = buf_size;
                    814:     cache->bufctl_dist = buf_size - sizeof(union kmem_bufctl);
                    815:     cache->color = 0;
                    816:     cache->nr_objs = 0;
                    817:     cache->nr_bufs = 0;
                    818:     cache->nr_slabs = 0;
                    819:     cache->nr_free_slabs = 0;
                    820:     cache->ctor = ctor;
                    821:     cache->slab_alloc_fn = slab_alloc_fn;
                    822:     cache->slab_free_fn = slab_free_fn;
                    823:     strncpy(cache->name, name, sizeof(cache->name));
                    824:     cache->name[sizeof(cache->name) - 1] = '\0';
                    825:     cache->buftag_dist = 0;
                    826:     cache->redzone_pad = 0;
                    827: 
                    828:     if (cache->flags & KMEM_CF_VERIFY) {
                    829:         cache->bufctl_dist = buf_size;
                    830:         cache->buftag_dist = cache->bufctl_dist + sizeof(union kmem_bufctl);
                    831:         cache->redzone_pad = cache->bufctl_dist - cache->obj_size;
                    832:         buf_size += sizeof(union kmem_bufctl) + sizeof(struct kmem_buftag);
                    833:         buf_size = P2ROUND(buf_size, align);
                    834:         cache->buf_size = buf_size;
                    835:     }
                    836: 
                    837:     kmem_cache_compute_sizes(cache, flags);
                    838: 
                    839: #if SLAB_USE_CPU_POOLS
                    840:     for (cpu_pool_type = kmem_cpu_pool_types;
                    841:          buf_size <= cpu_pool_type->buf_size;
                    842:          cpu_pool_type++);
                    843: 
                    844:     cache->cpu_pool_type = cpu_pool_type;
                    845: 
                    846:     for (i = 0; i < ARRAY_SIZE(cache->cpu_pools); i++)
                    847:         kmem_cpu_pool_init(&cache->cpu_pools[i], cache);
                    848: #endif /* SLAB_USE_CPU_POOLS */
                    849: 
                    850:     simple_lock(&kmem_cache_list_lock);
                    851:     list_insert_tail(&kmem_cache_list, &cache->node);
                    852:     kmem_nr_caches++;
                    853:     simple_unlock(&kmem_cache_list_lock);
                    854: }
                    855: 
                    856: static inline int kmem_cache_empty(struct kmem_cache *cache)
                    857: {
                    858:     return cache->nr_objs == cache->nr_bufs;
                    859: }
                    860: 
                    861: static int kmem_cache_grow(struct kmem_cache *cache)
                    862: {
                    863:     struct kmem_slab *slab;
                    864:     size_t color;
                    865:     int empty;
                    866: 
                    867:     simple_lock(&cache->lock);
                    868: 
                    869:     if (!kmem_cache_empty(cache)) {
                    870:         simple_unlock(&cache->lock);
                    871:         return 1;
                    872:     }
                    873: 
                    874:     color = cache->color;
                    875:     cache->color += cache->align;
                    876: 
                    877:     if (cache->color > cache->color_max)
                    878:         cache->color = 0;
                    879: 
                    880:     simple_unlock(&cache->lock);
                    881: 
                    882:     slab = kmem_slab_create(cache, color);
                    883: 
                    884:     simple_lock(&cache->lock);
                    885: 
                    886:     if (slab != NULL) {
                    887:         list_insert_head(&cache->free_slabs, &slab->list_node);
                    888:         cache->nr_bufs += cache->bufs_per_slab;
                    889:         cache->nr_slabs++;
                    890:         cache->nr_free_slabs++;
                    891:     }
                    892: 
                    893:     /*
                    894:      * Even if our slab creation failed, another thread might have succeeded
                    895:      * in growing the cache.
                    896:      */
                    897:     empty = kmem_cache_empty(cache);
                    898: 
                    899:     simple_unlock(&cache->lock);
                    900: 
                    901:     return !empty;
                    902: }
                    903: 
                    904: static void kmem_cache_reap(struct kmem_cache *cache)
                    905: {
                    906:     struct kmem_slab *slab;
                    907:     struct list dead_slabs;
                    908:     unsigned long nr_free_slabs;
                    909: 
                    910:     if (cache->flags & KMEM_CF_NO_RECLAIM)
                    911:         return;
                    912: 
                    913:     simple_lock(&cache->lock);
                    914:     list_set_head(&dead_slabs, &cache->free_slabs);
                    915:     list_init(&cache->free_slabs);
                    916:     nr_free_slabs = cache->nr_free_slabs;
                    917:     cache->nr_bufs -= cache->bufs_per_slab * nr_free_slabs;
                    918:     cache->nr_slabs -= nr_free_slabs;
                    919:     cache->nr_free_slabs = 0;
                    920:     simple_unlock(&cache->lock);
                    921: 
                    922:     while (!list_empty(&dead_slabs)) {
                    923:         slab = list_first_entry(&dead_slabs, struct kmem_slab, list_node);
                    924:         list_remove(&slab->list_node);
                    925:         kmem_slab_destroy(slab, cache);
                    926:         nr_free_slabs--;
                    927:     }
                    928: 
                    929:     assert(nr_free_slabs == 0);
                    930: }
                    931: 
                    932: /*
                    933:  * Allocate a raw (unconstructed) buffer from the slab layer of a cache.
                    934:  *
                    935:  * The cache must be locked before calling this function.
                    936:  */
                    937: static void * kmem_cache_alloc_from_slab(struct kmem_cache *cache)
                    938: {
                    939:     struct kmem_slab *slab;
                    940:     union kmem_bufctl *bufctl;
                    941: 
                    942:     if (!list_empty(&cache->partial_slabs))
                    943:         slab = list_first_entry(&cache->partial_slabs, struct kmem_slab,
                    944:                                 list_node);
                    945:     else if (!list_empty(&cache->free_slabs))
                    946:         slab = list_first_entry(&cache->free_slabs, struct kmem_slab,
                    947:                                 list_node);
                    948:     else
                    949:         return NULL;
                    950: 
                    951:     bufctl = slab->first_free;
                    952:     assert(bufctl != NULL);
                    953:     slab->first_free = bufctl->next;
                    954:     slab->nr_refs++;
                    955:     cache->nr_objs++;
                    956: 
                    957:     if (slab->nr_refs == cache->bufs_per_slab) {
                    958:         /* The slab has become complete */
                    959:         list_remove(&slab->list_node);
                    960: 
                    961:         if (slab->nr_refs == 1)
                    962:             cache->nr_free_slabs--;
                    963:     } else if (slab->nr_refs == 1) {
                    964:         /*
                    965:          * The slab has become partial. Insert the new slab at the end of
                    966:          * the list to reduce fragmentation.
                    967:          */
                    968:         list_remove(&slab->list_node);
                    969:         list_insert_tail(&cache->partial_slabs, &slab->list_node);
                    970:         cache->nr_free_slabs--;
                    971:     }
                    972: 
                    973:     if ((slab->nr_refs == 1) && kmem_slab_use_tree(cache->flags))
                    974:         rbtree_insert(&cache->active_slabs, &slab->tree_node,
                    975:                       kmem_slab_cmp_insert);
                    976: 
                    977:     return kmem_bufctl_to_buf(bufctl, cache);
                    978: }
                    979: 
                    980: /*
                    981:  * Release a buffer to the slab layer of a cache.
                    982:  *
                    983:  * The cache must be locked before calling this function.
                    984:  */
                    985: static void kmem_cache_free_to_slab(struct kmem_cache *cache, void *buf)
                    986: {
                    987:     struct kmem_slab *slab;
                    988:     union kmem_bufctl *bufctl;
                    989: 
                    990:     if (cache->flags & KMEM_CF_DIRECT) {
                    991:         assert(cache->slab_size == PAGE_SIZE);
                    992:         slab = (struct kmem_slab *)P2END((unsigned long)buf, cache->slab_size)
                    993:                - 1;
                    994:     } else {
                    995:         struct rbtree_node *node;
                    996: 
                    997:         node = rbtree_lookup_nearest(&cache->active_slabs, buf,
                    998:                                      kmem_slab_cmp_lookup, RBTREE_LEFT);
                    999:         assert(node != NULL);
                   1000:         slab = rbtree_entry(node, struct kmem_slab, tree_node);
                   1001:         assert((unsigned long)buf < (P2ALIGN((unsigned long)slab->addr
                   1002:                                              + cache->slab_size, PAGE_SIZE)));
                   1003:     }
                   1004: 
                   1005:     assert(slab->nr_refs >= 1);
                   1006:     assert(slab->nr_refs <= cache->bufs_per_slab);
                   1007:     bufctl = kmem_buf_to_bufctl(buf, cache);
                   1008:     bufctl->next = slab->first_free;
                   1009:     slab->first_free = bufctl;
                   1010:     slab->nr_refs--;
                   1011:     cache->nr_objs--;
                   1012: 
                   1013:     if (slab->nr_refs == 0) {
                   1014:         /* The slab has become free */
                   1015: 
                   1016:         if (kmem_slab_use_tree(cache->flags))
                   1017:             rbtree_remove(&cache->active_slabs, &slab->tree_node);
                   1018: 
                   1019:         if (cache->bufs_per_slab > 1)
                   1020:             list_remove(&slab->list_node);
                   1021: 
                   1022:         list_insert_head(&cache->free_slabs, &slab->list_node);
                   1023:         cache->nr_free_slabs++;
                   1024:     } else if (slab->nr_refs == (cache->bufs_per_slab - 1)) {
                   1025:         /* The slab has become partial */
                   1026:         list_insert_head(&cache->partial_slabs, &slab->list_node);
                   1027:     }
                   1028: }
                   1029: 
                   1030: static void kmem_cache_alloc_verify(struct kmem_cache *cache, void *buf,
                   1031:                                     int construct)
                   1032: {
                   1033:     struct kmem_buftag *buftag;
                   1034:     union kmem_bufctl *bufctl;
                   1035:     void *addr;
                   1036: 
                   1037:     buftag = kmem_buf_to_buftag(buf, cache);
                   1038: 
                   1039:     if (buftag->state != KMEM_BUFTAG_FREE)
                   1040:         kmem_cache_error(cache, buf, KMEM_ERR_BUFTAG, buftag);
                   1041: 
                   1042:     addr = kmem_buf_verify_fill(buf, KMEM_FREE_PATTERN, KMEM_UNINIT_PATTERN,
                   1043:                                 cache->bufctl_dist);
                   1044: 
                   1045:     if (addr != NULL)
                   1046:         kmem_cache_error(cache, buf, KMEM_ERR_MODIFIED, addr);
                   1047: 
                   1048:     addr = buf + cache->obj_size;
                   1049:     memset(addr, KMEM_REDZONE_BYTE, cache->redzone_pad);
                   1050: 
                   1051:     bufctl = kmem_buf_to_bufctl(buf, cache);
                   1052:     bufctl->redzone = KMEM_REDZONE_WORD;
                   1053:     buftag->state = KMEM_BUFTAG_ALLOC;
                   1054: 
                   1055:     if (construct && (cache->ctor != NULL))
                   1056:         cache->ctor(buf);
                   1057: }
                   1058: 
                   1059: vm_offset_t kmem_cache_alloc(struct kmem_cache *cache)
                   1060: {
                   1061:     int filled;
                   1062:     void *buf;
                   1063: 
                   1064: #if SLAB_USE_CPU_POOLS
                   1065:     struct kmem_cpu_pool *cpu_pool;
                   1066: 
                   1067:     cpu_pool = kmem_cpu_pool_get(cache);
                   1068: 
                   1069:     if (cpu_pool->flags & KMEM_CF_NO_CPU_POOL)
                   1070:         goto slab_alloc;
                   1071: 
                   1072:     simple_lock(&cpu_pool->lock);
                   1073: 
                   1074: fast_alloc:
                   1075:     if (likely(cpu_pool->nr_objs > 0)) {
                   1076:         buf = kmem_cpu_pool_pop(cpu_pool);
                   1077:         simple_unlock(&cpu_pool->lock);
                   1078: 
                   1079:         if (cpu_pool->flags & KMEM_CF_VERIFY)
                   1080:             kmem_cache_alloc_verify(cache, buf, KMEM_AV_CONSTRUCT);
                   1081: 
                   1082:         return (vm_offset_t)buf;
                   1083:     }
                   1084: 
                   1085:     if (cpu_pool->array != NULL) {
                   1086:         filled = kmem_cpu_pool_fill(cpu_pool, cache);
                   1087: 
                   1088:         if (!filled) {
                   1089:             simple_unlock(&cpu_pool->lock);
                   1090: 
                   1091:             filled = kmem_cache_grow(cache);
                   1092: 
                   1093:             if (!filled)
                   1094:                 return 0;
                   1095: 
                   1096:             simple_lock(&cpu_pool->lock);
                   1097:         }
                   1098: 
                   1099:         goto fast_alloc;
                   1100:     }
                   1101: 
                   1102:     simple_unlock(&cpu_pool->lock);
                   1103: #endif /* SLAB_USE_CPU_POOLS */
                   1104: 
                   1105: slab_alloc:
                   1106:     simple_lock(&cache->lock);
                   1107:     buf = kmem_cache_alloc_from_slab(cache);
                   1108:     simple_unlock(&cache->lock);
                   1109: 
                   1110:     if (buf == NULL) {
                   1111:         filled = kmem_cache_grow(cache);
                   1112: 
                   1113:         if (!filled)
                   1114:             return 0;
                   1115: 
                   1116:         goto slab_alloc;
                   1117:     }
                   1118: 
                   1119:     if (cache->flags & KMEM_CF_VERIFY)
                   1120:         kmem_cache_alloc_verify(cache, buf, KMEM_AV_NOCONSTRUCT);
                   1121: 
                   1122:     if (cache->ctor != NULL)
                   1123:         cache->ctor(buf);
                   1124: 
                   1125:     return (vm_offset_t)buf;
                   1126: }
                   1127: 
                   1128: static void kmem_cache_free_verify(struct kmem_cache *cache, void *buf)
                   1129: {
                   1130:     struct rbtree_node *node;
                   1131:     struct kmem_buftag *buftag;
                   1132:     struct kmem_slab *slab;
                   1133:     union kmem_bufctl *bufctl;
                   1134:     unsigned char *redzone_byte;
                   1135:     unsigned long slabend;
                   1136: 
                   1137:     simple_lock(&cache->lock);
                   1138:     node = rbtree_lookup_nearest(&cache->active_slabs, buf,
                   1139:                                  kmem_slab_cmp_lookup, RBTREE_LEFT);
                   1140:     simple_unlock(&cache->lock);
                   1141: 
                   1142:     if (node == NULL)
                   1143:         kmem_cache_error(cache, buf, KMEM_ERR_INVALID, NULL);
                   1144: 
                   1145:     slab = rbtree_entry(node, struct kmem_slab, tree_node);
                   1146:     slabend = P2ALIGN((unsigned long)slab->addr + cache->slab_size, PAGE_SIZE);
                   1147: 
                   1148:     if ((unsigned long)buf >= slabend)
                   1149:         kmem_cache_error(cache, buf, KMEM_ERR_INVALID, NULL);
                   1150: 
                   1151:     if ((((unsigned long)buf - (unsigned long)slab->addr) % cache->buf_size)
                   1152:         != 0)
                   1153:         kmem_cache_error(cache, buf, KMEM_ERR_INVALID, NULL);
                   1154: 
                   1155:     /*
                   1156:      * As the buffer address is valid, accessing its buftag is safe.
                   1157:      */
                   1158:     buftag = kmem_buf_to_buftag(buf, cache);
                   1159: 
                   1160:     if (buftag->state != KMEM_BUFTAG_ALLOC) {
                   1161:         if (buftag->state == KMEM_BUFTAG_FREE)
                   1162:             kmem_cache_error(cache, buf, KMEM_ERR_DOUBLEFREE, NULL);
                   1163:         else
                   1164:             kmem_cache_error(cache, buf, KMEM_ERR_BUFTAG, buftag);
                   1165:     }
                   1166: 
                   1167:     redzone_byte = buf + cache->obj_size;
                   1168:     bufctl = kmem_buf_to_bufctl(buf, cache);
                   1169: 
                   1170:     while (redzone_byte < (unsigned char *)bufctl) {
                   1171:         if (*redzone_byte != KMEM_REDZONE_BYTE)
                   1172:             kmem_cache_error(cache, buf, KMEM_ERR_REDZONE, redzone_byte);
                   1173: 
                   1174:         redzone_byte++;
                   1175:     }
                   1176: 
                   1177:     if (bufctl->redzone != KMEM_REDZONE_WORD) {
                   1178:         unsigned long word;
                   1179: 
                   1180:         word = KMEM_REDZONE_WORD;
                   1181:         redzone_byte = kmem_buf_verify_bytes(&bufctl->redzone, &word,
                   1182:                                              sizeof(bufctl->redzone));
                   1183:         kmem_cache_error(cache, buf, KMEM_ERR_REDZONE, redzone_byte);
                   1184:     }
                   1185: 
                   1186:     kmem_buf_fill(buf, KMEM_FREE_PATTERN, cache->bufctl_dist);
                   1187:     buftag->state = KMEM_BUFTAG_FREE;
                   1188: }
                   1189: 
                   1190: void kmem_cache_free(struct kmem_cache *cache, vm_offset_t obj)
                   1191: {
                   1192: #if SLAB_USE_CPU_POOLS
                   1193:     struct kmem_cpu_pool *cpu_pool;
                   1194:     void **array;
                   1195: 
                   1196:     cpu_pool = kmem_cpu_pool_get(cache);
                   1197: 
                   1198:     if (cpu_pool->flags & KMEM_CF_VERIFY) {
                   1199: #else /* SLAB_USE_CPU_POOLS */
                   1200:     if (cache->flags & KMEM_CF_VERIFY) {
                   1201: #endif /* SLAB_USE_CPU_POOLS */
                   1202:         kmem_cache_free_verify(cache, (void *)obj);
                   1203:     }
                   1204: 
                   1205: #if SLAB_USE_CPU_POOLS
                   1206:     if (cpu_pool->flags & KMEM_CF_NO_CPU_POOL)
                   1207:         goto slab_free;
                   1208: 
                   1209:     simple_lock(&cpu_pool->lock);
                   1210: 
                   1211: fast_free:
                   1212:     if (likely(cpu_pool->nr_objs < cpu_pool->size)) {
                   1213:         kmem_cpu_pool_push(cpu_pool, (void *)obj);
                   1214:         simple_unlock(&cpu_pool->lock);
                   1215:         return;
                   1216:     }
                   1217: 
                   1218:     if (cpu_pool->array != NULL) {
                   1219:         kmem_cpu_pool_drain(cpu_pool, cache);
                   1220:         goto fast_free;
                   1221:     }
                   1222: 
                   1223:     simple_unlock(&cpu_pool->lock);
                   1224: 
                   1225:     array = (void *)kmem_cache_alloc(cache->cpu_pool_type->array_cache);
                   1226: 
                   1227:     if (array != NULL) {
                   1228:         simple_lock(&cpu_pool->lock);
                   1229: 
                   1230:         /*
                   1231:          * Another thread may have built the CPU pool while the lock was
                   1232:          * dropped.
                   1233:          */
                   1234:         if (cpu_pool->array != NULL) {
                   1235:             simple_unlock(&cpu_pool->lock);
                   1236:             kmem_cache_free(cache->cpu_pool_type->array_cache,
                   1237:                             (vm_offset_t)array);
                   1238:             simple_lock(&cpu_pool->lock);
                   1239:             goto fast_free;
                   1240:         }
                   1241: 
                   1242:         kmem_cpu_pool_build(cpu_pool, cache, array);
                   1243:         goto fast_free;
                   1244:     }
                   1245: 
                   1246: slab_free:
                   1247: #endif /* SLAB_USE_CPU_POOLS */
                   1248: 
                   1249:     simple_lock(&cache->lock);
                   1250:     kmem_cache_free_to_slab(cache, (void *)obj);
                   1251:     simple_unlock(&cache->lock);
                   1252: }
                   1253: 
                   1254: void slab_collect(void)
                   1255: {
                   1256:     struct kmem_cache *cache;
                   1257: 
                   1258:     if (elapsed_ticks <= (kmem_gc_last_tick + KMEM_GC_INTERVAL))
                   1259:         return;
                   1260: 
                   1261:     kmem_gc_last_tick = elapsed_ticks;
                   1262: 
                   1263:     simple_lock(&kmem_cache_list_lock);
                   1264: 
                   1265:     list_for_each_entry(&kmem_cache_list, cache, node)
                   1266:         kmem_cache_reap(cache);
                   1267: 
                   1268:     simple_unlock(&kmem_cache_list_lock);
                   1269: }
                   1270: 
                   1271: void slab_bootstrap(void)
                   1272: {
                   1273:     /* Make sure a bufctl can always be stored in a buffer */
                   1274:     assert(sizeof(union kmem_bufctl) <= KMEM_ALIGN_MIN);
                   1275: 
                   1276:     list_init(&kmem_cache_list);
                   1277:     simple_lock_init(&kmem_cache_list_lock);
                   1278: }
                   1279: 
                   1280: void slab_init(void)
                   1281: {
                   1282:     vm_offset_t min, max;
                   1283: 
                   1284: #if SLAB_USE_CPU_POOLS
                   1285:     struct kmem_cpu_pool_type *cpu_pool_type;
                   1286:     char name[KMEM_CACHE_NAME_SIZE];
                   1287:     size_t i, size;
                   1288: #endif /* SLAB_USE_CPU_POOLS */
                   1289: 
                   1290:     kmem_submap(kmem_map, kernel_map, &min, &max, KMEM_MAP_SIZE, FALSE);
                   1291: 
                   1292: #if SLAB_USE_CPU_POOLS
                   1293:     for (i = 0; i < ARRAY_SIZE(kmem_cpu_pool_types); i++) {
                   1294:         cpu_pool_type = &kmem_cpu_pool_types[i];
                   1295:         cpu_pool_type->array_cache = &kmem_cpu_array_caches[i];
                   1296:         sprintf(name, "kmem_cpu_array_%d", cpu_pool_type->array_size);
                   1297:         size = sizeof(void *) * cpu_pool_type->array_size;
                   1298:         kmem_cache_init(cpu_pool_type->array_cache, name, size,
                   1299:                         cpu_pool_type->array_align, NULL, NULL, NULL, 0);
                   1300:     }
                   1301: #endif /* SLAB_USE_CPU_POOLS */
                   1302: 
                   1303:     /*
                   1304:      * Prevent off slab data for the slab cache to avoid infinite recursion.
                   1305:      */
                   1306:     kmem_cache_init(&kmem_slab_cache, "kmem_slab", sizeof(struct kmem_slab),
                   1307:                     0, NULL, NULL, NULL, KMEM_CACHE_NOOFFSLAB);
                   1308: }
                   1309: 
                   1310: static vm_offset_t kalloc_pagealloc(vm_size_t size)
                   1311: {
                   1312:     vm_offset_t addr;
                   1313:     kern_return_t kr;
                   1314: 
                   1315:     kr = kmem_alloc_wired(kmem_map, &addr, size);
                   1316: 
                   1317:     if (kr != KERN_SUCCESS)
                   1318:         return 0;
                   1319: 
                   1320:     return addr;
                   1321: }
                   1322: 
                   1323: static void kalloc_pagefree(vm_offset_t ptr, vm_size_t size)
                   1324: {
                   1325:     kmem_free(kmem_map, ptr, size);
                   1326: }
                   1327: 
                   1328: void kalloc_init(void)
                   1329: {
                   1330:     char name[KMEM_CACHE_NAME_SIZE];
                   1331:     size_t i, size;
                   1332: 
                   1333:     size = 1 << KALLOC_FIRST_SHIFT;
                   1334: 
                   1335:     for (i = 0; i < ARRAY_SIZE(kalloc_caches); i++) {
                   1336:         sprintf(name, "kalloc_%lu", size);
                   1337:         kmem_cache_init(&kalloc_caches[i], name, size, 0, NULL,
                   1338:                         kalloc_pagealloc, kalloc_pagefree, 0);
                   1339:         size <<= 1;
                   1340:     }
                   1341: }
                   1342: 
                   1343: /*
                   1344:  * Return the kalloc cache index matching the given allocation size, which
                   1345:  * must be strictly greater than 0.
                   1346:  */
                   1347: static inline size_t kalloc_get_index(unsigned long size)
                   1348: {
                   1349:     assert(size != 0);
                   1350: 
                   1351:     size = (size - 1) >> KALLOC_FIRST_SHIFT;
                   1352: 
                   1353:     if (size == 0)
                   1354:         return 0;
                   1355:     else
                   1356:         return (sizeof(long) * 8) - __builtin_clzl(size);
                   1357: }
                   1358: 
                   1359: static void kalloc_verify(struct kmem_cache *cache, void *buf, size_t size)
                   1360: {
                   1361:     size_t redzone_size;
                   1362:     void *redzone;
                   1363: 
                   1364:     assert(size <= cache->obj_size);
                   1365: 
                   1366:     redzone = buf + size;
                   1367:     redzone_size = cache->obj_size - size;
                   1368:     memset(redzone, KMEM_REDZONE_BYTE, redzone_size);
                   1369: }
                   1370: 
                   1371: vm_offset_t kalloc(vm_size_t size)
                   1372: {
                   1373:     size_t index;
                   1374:     void *buf;
                   1375: 
                   1376:     if (size == 0)
                   1377:         return 0;
                   1378: 
                   1379:     index = kalloc_get_index(size);
                   1380: 
                   1381:     if (index < ARRAY_SIZE(kalloc_caches)) {
                   1382:         struct kmem_cache *cache;
                   1383: 
                   1384:         cache = &kalloc_caches[index];
                   1385:         buf = (void *)kmem_cache_alloc(cache);
                   1386: 
                   1387:         if ((buf != 0) && (cache->flags & KMEM_CF_VERIFY))
                   1388:             kalloc_verify(cache, buf, size);
                   1389:     } else
                   1390:         buf = (void *)kalloc_pagealloc(size);
                   1391: 
                   1392:     return (vm_offset_t)buf;
                   1393: }
                   1394: 
                   1395: static void kfree_verify(struct kmem_cache *cache, void *buf, size_t size)
                   1396: {
                   1397:     unsigned char *redzone_byte, *redzone_end;
                   1398: 
                   1399:     assert(size <= cache->obj_size);
                   1400: 
                   1401:     redzone_byte = buf + size;
                   1402:     redzone_end = buf + cache->obj_size;
                   1403: 
                   1404:     while (redzone_byte < redzone_end) {
                   1405:         if (*redzone_byte != KMEM_REDZONE_BYTE)
                   1406:             kmem_cache_error(cache, buf, KMEM_ERR_REDZONE, redzone_byte);
                   1407: 
                   1408:         redzone_byte++;
                   1409:     }
                   1410: }
                   1411: 
                   1412: void kfree(vm_offset_t data, vm_size_t size)
                   1413: {
                   1414:     size_t index;
                   1415: 
                   1416:     if ((data == 0) || (size == 0))
                   1417:         return;
                   1418: 
                   1419:     index = kalloc_get_index(size);
                   1420: 
                   1421:     if (index < ARRAY_SIZE(kalloc_caches)) {
                   1422:         struct kmem_cache *cache;
                   1423: 
                   1424:         cache = &kalloc_caches[index];
                   1425: 
                   1426:         if (cache->flags & KMEM_CF_VERIFY)
                   1427:             kfree_verify(cache, (void *)data, size);
                   1428: 
                   1429:         kmem_cache_free(cache, data);
                   1430:     } else {
                   1431:         kalloc_pagefree(data, size);
                   1432:     }
                   1433: }
                   1434: 
                   1435: void slab_info(void)
                   1436: {
                   1437:     struct kmem_cache *cache;
                   1438:     vm_size_t mem_usage, mem_reclaimable;
                   1439: 
                   1440:     printf("cache                  obj slab  bufs   objs   bufs "
                   1441:            "   total reclaimable\n"
                   1442:            "name                  size size /slab  usage  count "
                   1443:            "  memory      memory\n");
                   1444: 
                   1445:     simple_lock(&kmem_cache_list_lock);
                   1446: 
                   1447:     list_for_each_entry(&kmem_cache_list, cache, node) {
                   1448:         simple_lock(&cache->lock);
                   1449: 
                   1450:         mem_usage = (cache->nr_slabs * cache->slab_size) >> 10;
                   1451:         mem_reclaimable = (cache->nr_free_slabs * cache->slab_size) >> 10;
                   1452: 
                   1453:         printf("%-19s %6lu %3luk  %4lu %6lu %6lu %7uk %10uk\n",
                   1454:                cache->name, cache->obj_size, cache->slab_size >> 10,
                   1455:                cache->bufs_per_slab, cache->nr_objs, cache->nr_bufs,
                   1456:                mem_usage, mem_reclaimable);
                   1457: 
                   1458:         simple_unlock(&cache->lock);
                   1459:     }
                   1460: 
                   1461:     simple_unlock(&kmem_cache_list_lock);
                   1462: }
                   1463: 
                   1464: #if MACH_DEBUG
                   1465: kern_return_t host_slab_info(host_t host, cache_info_array_t *infop,
                   1466:                              unsigned int *infoCntp)
                   1467: {
                   1468:     struct kmem_cache *cache;
                   1469:     cache_info_t *info;
                   1470:     unsigned int i, nr_caches;
                   1471:     vm_size_t info_size = info_size;
                   1472:     kern_return_t kr;
                   1473: 
                   1474:     if (host == HOST_NULL)
                   1475:         return KERN_INVALID_HOST;
                   1476: 
                   1477:     /*
                   1478:      * Assume the cache list is unaltered once the kernel is ready.
                   1479:      */
                   1480: 
                   1481:     simple_lock(&kmem_cache_list_lock);
                   1482:     nr_caches = kmem_nr_caches;
                   1483:     simple_unlock(&kmem_cache_list_lock);
                   1484: 
                   1485:     if (nr_caches <= *infoCntp)
                   1486:         info = *infop;
                   1487:     else {
                   1488:         vm_offset_t info_addr;
                   1489: 
                   1490:         info_size = round_page(nr_caches * sizeof(*info));
                   1491:         kr = kmem_alloc_pageable(ipc_kernel_map, &info_addr, info_size);
                   1492: 
                   1493:         if (kr != KERN_SUCCESS)
                   1494:             return kr;
                   1495: 
                   1496:         info = (cache_info_t *)info_addr;
                   1497:     }
                   1498: 
                   1499:     if (info == NULL)
                   1500:         return KERN_RESOURCE_SHORTAGE;
                   1501: 
                   1502:     i = 0;
                   1503: 
                   1504:     list_for_each_entry(&kmem_cache_list, cache, node) {
                   1505:         simple_lock(&cache_lock);
                   1506:         info[i].flags = ((cache->flags & KMEM_CF_NO_CPU_POOL)
                   1507:                          ? CACHE_FLAGS_NO_CPU_POOL : 0)
                   1508:                         | ((cache->flags & KMEM_CF_SLAB_EXTERNAL)
                   1509:                            ? CACHE_FLAGS_SLAB_EXTERNAL : 0)
                   1510:                         | ((cache->flags & KMEM_CF_NO_RECLAIM)
                   1511:                            ? CACHE_FLAGS_NO_RECLAIM : 0)
                   1512:                         | ((cache->flags & KMEM_CF_VERIFY)
                   1513:                            ? CACHE_FLAGS_VERIFY : 0)
                   1514:                         | ((cache->flags & KMEM_CF_DIRECT)
                   1515:                            ? CACHE_FLAGS_DIRECT : 0);
                   1516: #if SLAB_USE_CPU_POOLS
                   1517:         info[i].cpu_pool_size = cache->cpu_pool_type->array_size;
                   1518: #else /* SLAB_USE_CPU_POOLS */
                   1519:         info[i].cpu_pool_size = 0;
                   1520: #endif /* SLAB_USE_CPU_POOLS */
                   1521:         info[i].obj_size = cache->obj_size;
                   1522:         info[i].align = cache->align;
                   1523:         info[i].buf_size = cache->buf_size;
                   1524:         info[i].slab_size = cache->slab_size;
                   1525:         info[i].bufs_per_slab = cache->bufs_per_slab;
                   1526:         info[i].nr_objs = cache->nr_objs;
                   1527:         info[i].nr_bufs = cache->nr_bufs;
                   1528:         info[i].nr_slabs = cache->nr_slabs;
                   1529:         info[i].nr_free_slabs = cache->nr_free_slabs;
                   1530:         strncpy(info[i].name, cache->name, sizeof(info[i].name));
                   1531:         info[i].name[sizeof(info[i].name) - 1] = '\0';
                   1532:         simple_unlock(&cache->lock);
                   1533: 
                   1534:         i++;
                   1535:     }
                   1536: 
                   1537:     if (info != *infop) {
                   1538:         vm_map_copy_t copy;
                   1539:         vm_size_t used;
                   1540: 
                   1541:         used = nr_caches * sizeof(*info);
                   1542: 
                   1543:         if (used != info_size)
                   1544:             memset((char *)info + used, 0, info_size - used);
                   1545: 
                   1546:         kr = vm_map_copyin(ipc_kernel_map, (vm_offset_t)info, used, TRUE,
                   1547:                            &copy);
                   1548: 
                   1549:         assert(kr == KERN_SUCCESS);
                   1550:         *infop = (cache_info_t *)copy;
                   1551:     }
                   1552: 
                   1553:     *infoCntp = nr_caches;
                   1554: 
                   1555:     return KERN_SUCCESS;
                   1556: }
                   1557: #endif /* MACH_DEBUG */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.