uma.h revision 92758
192654Sjeff/* 292654Sjeff * Copyright (c) 2002, Jeffrey Roberson <jroberson@chesapeake.net> 392654Sjeff * All rights reserved. 492654Sjeff * 592654Sjeff * Redistribution and use in source and binary forms, with or without 692654Sjeff * modification, are permitted provided that the following conditions 792654Sjeff * are met: 892654Sjeff * 1. Redistributions of source code must retain the above copyright 992654Sjeff * notice unmodified, this list of conditions, and the following 1092654Sjeff * disclaimer. 1192654Sjeff * 2. Redistributions in binary form must reproduce the above copyright 1292654Sjeff * notice, this list of conditions and the following disclaimer in the 1392654Sjeff * documentation and/or other materials provided with the distribution. 1492654Sjeff * 1592654Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1692654Sjeff * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1792654Sjeff * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1892654Sjeff * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1992654Sjeff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2092654Sjeff * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2192654Sjeff * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2292654Sjeff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2392654Sjeff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2492654Sjeff * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2592654Sjeff * 2692654Sjeff * $FreeBSD: head/sys/vm/uma.h 92758 2002-03-20 05:28:34Z jeff $ 2792654Sjeff * 2892654Sjeff */ 2992654Sjeff 3092654Sjeff/* 3192654Sjeff * uma.h - External definitions for the Universal Memory Allocator 3292654Sjeff * 3392654Sjeff * Jeff Roberson <jroberson@chesapeake.net> 3492654Sjeff*/ 3592654Sjeff 3692654Sjeff#ifndef VM_UMA_H 3792654Sjeff#define VM_UMA_H 3892654Sjeff 3992654Sjeff#include <sys/param.h> /* For NULL */ 4092654Sjeff#include <sys/malloc.h> /* For M_* */ 4192654Sjeff 4292654Sjeff/* User visable parameters */ 4392654Sjeff#define UMA_SMALLEST_UNIT (PAGE_SIZE / 256) /* Smallest item allocated */ 4492654Sjeff 4592654Sjeff/* Types and type defs */ 4692654Sjeff 4792654Sjeffstruct uma_zone; 4892654Sjeff/* Opaque type used as a handle to the zone */ 4992654Sjefftypedef struct uma_zone * uma_zone_t; 5092654Sjeff 5192654Sjeff/* 5292654Sjeff * Item constructor 5392654Sjeff * 5492654Sjeff * Arguments: 5592654Sjeff * item A pointer to the memory which has been allocated. 5692654Sjeff * arg The arg field passed to uma_zalloc_arg 5792654Sjeff * size The size of the allocated item 5892654Sjeff * 5992654Sjeff * Returns: 6092654Sjeff * Nothing 6192654Sjeff * 6292654Sjeff * Discussion: 6392654Sjeff * The constructor is called just before the memory is returned 6492654Sjeff * to the user. It may block if neccisary. 6592654Sjeff */ 6692654Sjefftypedef void (*uma_ctor)(void *mem, int size, void *arg); 6792654Sjeff 6892654Sjeff/* 6992654Sjeff * Item destructor 7092654Sjeff * 7192654Sjeff * Arguments: 7292654Sjeff * item A pointer to the memory which has been allocated. 7392654Sjeff * size The size of the item being destructed. 7492654Sjeff * arg Argument passed through uma_zfree_arg 7592654Sjeff * 7692654Sjeff * Returns: 7792654Sjeff * Nothing 7892654Sjeff * 7992654Sjeff * Discussion: 8092654Sjeff * The destructor may perform operations that differ from those performed 8192654Sjeff * by the initializer, but it must leave the object in the same state. 8292654Sjeff * This IS type stable storage. This is called after EVERY zfree call. 8392654Sjeff */ 8492654Sjefftypedef void (*uma_dtor)(void *mem, int size, void *arg); 8592654Sjeff 8692654Sjeff/* 8792654Sjeff * Item initializer 8892654Sjeff * 8992654Sjeff * Arguments: 9092654Sjeff * item A pointer to the memory which has been allocated. 9192654Sjeff * size The size of the item being initialized. 9292654Sjeff * 9392654Sjeff * Returns: 9492654Sjeff * Nothing 9592654Sjeff * 9692654Sjeff * Discussion: 9792654Sjeff * The initializer is called when the memory is cached in the uma zone. 9892654Sjeff * this should be the same state that the destructor leaves the object in. 9992654Sjeff */ 10092654Sjefftypedef void (*uma_init)(void *mem, int size); 10192654Sjeff 10292654Sjeff/* 10392654Sjeff * Item discard function 10492654Sjeff * 10592654Sjeff * Arguments: 10692654Sjeff * item A pointer to memory which has been 'freed' but has not left the 10792654Sjeff * zone's cache. 10892654Sjeff * size The size of the item being discarded. 10992654Sjeff * 11092654Sjeff * Returns: 11192654Sjeff * Nothing 11292654Sjeff * 11392654Sjeff * Discussion: 11492654Sjeff * This routine is called when memory leaves a zone and is returned to the 11592654Sjeff * system for other uses. It is the counter part to the init function. 11692654Sjeff */ 11792654Sjefftypedef void (*uma_fini)(void *mem, int size); 11892654Sjeff 11992654Sjeff/* 12092654Sjeff * What's the difference between initializing and constructing? 12192654Sjeff * 12292654Sjeff * The item is initialized when it is cached, and this is the state that the 12392654Sjeff * object should be in when returned to the allocator. The purpose of this is 12492654Sjeff * to remove some code which would otherwise be called on each allocation by 12592654Sjeff * utilizing a known, stable state. This differs from the constructor which 12692654Sjeff * will be called on EVERY allocation. 12792654Sjeff * 12892654Sjeff * For example, in the initializer you may want to initialize embeded locks, 12992654Sjeff * NULL list pointers, set up initial states, magic numbers, etc. This way if 13092654Sjeff * the object is held in the allocator and re-used it won't be neccisary to 13192654Sjeff * re-initialize it. 13292654Sjeff * 13392654Sjeff * The constructor may be used to lock a data structure, link it on to lists, 13492654Sjeff * bump reference counts or total counts of outstanding structures, etc. 13592654Sjeff * 13692654Sjeff */ 13792654Sjeff 13892654Sjeff 13992654Sjeff/* Function proto types */ 14092654Sjeff 14192654Sjeff/* 14292654Sjeff * Create a new uma zone 14392654Sjeff * 14492654Sjeff * Arguments: 14592654Sjeff * name The text name of the zone for debugging and stats, this memory 14692654Sjeff * should not be freed until the zone has been deallocated. 14792654Sjeff * size The size of the object that is being created. 14892654Sjeff * ctor The constructor that is called when the object is allocated 14992654Sjeff * dtor The destructor that is called when the object is freed. 15092654Sjeff * init An initializer that sets up the initial state of the memory. 15192654Sjeff * fini A discard function that undoes initialization done by init. 15292654Sjeff * ctor/dtor/init/fini may all be null, see notes above. 15392654Sjeff * align A bitmask that corisponds to the requested alignment 15492654Sjeff * eg 4 would be 0x3 15592654Sjeff * flags A set of parameters that control the behavior of the zone 15692654Sjeff * 15792654Sjeff * Returns: 15892654Sjeff * A pointer to a structure which is intended to be opaque to users of 15992654Sjeff * the interface. The value may be null if the wait flag is not set. 16092654Sjeff */ 16192654Sjeff 16292654Sjeffuma_zone_t uma_zcreate(char *name, int size, uma_ctor ctor, uma_dtor dtor, 16392654Sjeff uma_init uminit, uma_fini fini, int align, 16492654Sjeff u_int16_t flags); 16592654Sjeff 16692654Sjeff/* Definitions for uma_zcreate flags */ 16792654Sjeff#define UMA_ZONE_PAGEABLE 0x0001 /* Return items not fully backed by 16892654Sjeff physical memory XXX Not yet */ 16992654Sjeff#define UMA_ZONE_ZINIT 0x0002 /* Initialize with zeros */ 17092654Sjeff#define UMA_ZONE_STATIC 0x0004 /* Staticly sized zone */ 17192654Sjeff#define UMA_ZONE_OFFPAGE 0x0008 /* Force the slab structure allocation 17292654Sjeff off of the real memory */ 17392654Sjeff#define UMA_ZONE_MALLOC 0x0010 /* For use by malloc(9) only! */ 17492654Sjeff#define UMA_ZONE_NOFREE 0x0020 /* Do not free slabs of this type! */ 17592654Sjeff 17692654Sjeff/* Definitions for align */ 17792654Sjeff#define UMA_ALIGN_PTR (sizeof(void *) - 1) /* Alignment fit for ptr */ 17892654Sjeff#define UMA_ALIGN_LONG (sizeof(long) - 1) /* "" long */ 17992654Sjeff#define UMA_ALIGN_INT (sizeof(int) - 1) /* "" int */ 18092654Sjeff#define UMA_ALIGN_SHORT (sizeof(short) - 1) /* "" short */ 18192654Sjeff#define UMA_ALIGN_CHAR (sizeof(char) - 1) /* "" char */ 18292654Sjeff#define UMA_ALIGN_CACHE (16 - 1) /* Cache line size align */ 18392654Sjeff 18492654Sjeff/* 18592654Sjeff * Destroys a uma zone 18692654Sjeff * 18792654Sjeff * Arguments: 18892654Sjeff * zone The zone we want to destroy. 18992654Sjeff * wait This flag indicates whether or not we should wait for all 19092654Sjeff * allocations to free, or return an errno on outstanding memory. 19192654Sjeff * 19292654Sjeff * Returns: 19392654Sjeff * 0 on successful completion, or EWOULDBLOCK if there are outstanding 19492654Sjeff * allocations and the wait flag is M_NOWAIT 19592654Sjeff */ 19692654Sjeff 19792654Sjeffint uma_zdestroy(uma_zone_t zone, int wait); 19892654Sjeff 19992654Sjeff/* 20092654Sjeff * Allocates an item out of a zone 20192654Sjeff * 20292654Sjeff * Arguments: 20392654Sjeff * zone The zone we are allocating from 20492654Sjeff * arg This data is passed to the ctor function 20592654Sjeff * wait This flag indicates whether or not we are allowed to block while 20692654Sjeff * allocating memory for this zone should we run out. 20792654Sjeff * 20892654Sjeff * Returns: 20992654Sjeff * A non null pointer to an initialized element from the zone is 21092654Sjeff * garanteed if the wait flag is M_WAITOK, otherwise a null pointer may be 21192654Sjeff * returned if the zone is empty or the ctor failed. 21292654Sjeff */ 21392654Sjeff 21492654Sjeffvoid *uma_zalloc_arg(uma_zone_t zone, void *arg, int wait); 21592654Sjeff 21692654Sjeff/* 21792654Sjeff * Allocates an item out of a zone without supplying an argument 21892654Sjeff * 21992654Sjeff * This is just a wrapper for uma_zalloc_arg for convenience. 22092654Sjeff * 22192654Sjeff */ 22292654Sjeffstatic __inline void *uma_zalloc(uma_zone_t zone, int wait); 22392654Sjeff 22492654Sjeffstatic __inline void * 22592654Sjeffuma_zalloc(uma_zone_t zone, int wait) 22692654Sjeff{ 22792654Sjeff return uma_zalloc_arg(zone, NULL, wait); 22892654Sjeff} 22992654Sjeff 23092654Sjeff/* 23192654Sjeff * Frees an item back into the specified zone. 23292654Sjeff * 23392654Sjeff * Arguments: 23492654Sjeff * zone The zone the item was originally allocated out of. 23592654Sjeff * item The memory to be freed. 23692654Sjeff * arg Argument passed to the destructor 23792654Sjeff * 23892654Sjeff * Returns: 23992654Sjeff * Nothing. 24092654Sjeff */ 24192654Sjeff 24292654Sjeffvoid uma_zfree_arg(uma_zone_t zone, void *item, void *arg); 24392654Sjeff 24492654Sjeff/* 24592654Sjeff * Frees an item back to a zone without supplying an argument 24692654Sjeff * 24792654Sjeff * This is just a wrapper for uma_zfree_arg for convenience. 24892654Sjeff * 24992654Sjeff */ 25092654Sjeffstatic __inline void uma_zfree(uma_zone_t zone, void *item); 25192654Sjeff 25292654Sjeffstatic __inline void 25392654Sjeffuma_zfree(uma_zone_t zone, void *item) 25492654Sjeff{ 25592654Sjeff return uma_zfree_arg(zone, item, NULL); 25692654Sjeff} 25792654Sjeff 25892654Sjeff/* 25992654Sjeff * XXX The rest of the prototypes in this header are h0h0 magic for the VM. 26092654Sjeff * If you think you need to use it for a normal zone you're probably incorrect. 26192654Sjeff */ 26292654Sjeff 26392654Sjeff/* 26492654Sjeff * Backend page supplier routines 26592654Sjeff * 26692654Sjeff * Arguments: 26792654Sjeff * zone The zone that is requesting pages 26892654Sjeff * size The number of bytes being requested 26992654Sjeff * pflag Flags for these memory pages, see below. 27092654Sjeff * wait Indicates our willingness to block. 27192654Sjeff * 27292654Sjeff * Returns: 27392654Sjeff * A pointer to the alloced memory or NULL on failure. 27492654Sjeff */ 27592654Sjeff 27692654Sjefftypedef void *(*uma_alloc)(uma_zone_t zone, int size, u_int8_t *pflag, int wait); 27792654Sjeff 27892654Sjeff/* 27992654Sjeff * Backend page free routines 28092654Sjeff * 28192654Sjeff * Arguments: 28292654Sjeff * item A pointer to the previously allocated pages 28392654Sjeff * size The original size of the allocation 28492654Sjeff * pflag The flags for the slab. See UMA_SLAB_* below 28592654Sjeff * 28692654Sjeff * Returns: 28792654Sjeff * None 28892654Sjeff */ 28992654Sjefftypedef void (*uma_free)(void *item, int size, u_int8_t pflag); 29092654Sjeff 29192654Sjeff 29292654Sjeff 29392654Sjeff/* 29492654Sjeff * Sets up the uma allocator. (Called by vm_mem_init) 29592654Sjeff * 29692654Sjeff * Arguments: 29792654Sjeff * bootmem A pointer to memory used to bootstrap the system. 29892654Sjeff * 29992654Sjeff * Returns: 30092654Sjeff * Nothing 30192654Sjeff * 30292654Sjeff * Discussion: 30392654Sjeff * This memory is used for zones which allocate things before the 30492654Sjeff * backend page supplier can give us pages. It should be 30592654Sjeff * UMA_SLAB_SIZE * UMA_BOOT_PAGES bytes. (see uma_int.h) 30692654Sjeff * 30792654Sjeff */ 30892654Sjeff 30992654Sjeffvoid uma_startup(void *bootmem); 31092654Sjeff 31192654Sjeff/* 31292654Sjeff * Finishes starting up the allocator. This should 31392654Sjeff * be called when kva is ready for normal allocs. 31492654Sjeff * 31592654Sjeff * Arguments: 31692654Sjeff * hash An area of memory that will become the malloc hash 31792654Sjeff * elems The number of elements in this array 31892654Sjeff * 31992654Sjeff * Returns: 32092654Sjeff * Nothing 32192654Sjeff * 32292654Sjeff * Discussion: 32392654Sjeff * uma_startup2 is called by kmeminit() to prepare the malloc 32492654Sjeff * hash bucket, and enable use of uma for malloc ops. 32592654Sjeff */ 32692654Sjeff 32792654Sjeffvoid uma_startup2(void *hash, u_long elems); 32892654Sjeff 32992654Sjeff/* 33092654Sjeff * Reclaims unused memory for all zones 33192654Sjeff * 33292654Sjeff * Arguments: 33392654Sjeff * None 33492654Sjeff * Returns: 33592654Sjeff * None 33692654Sjeff * 33792654Sjeff * This should only be called by the page out daemon. 33892654Sjeff */ 33992654Sjeff 34092654Sjeffvoid uma_reclaim(void); 34192654Sjeff 34292654Sjeff/* 34392654Sjeff * Switches the backing object of a zone 34492654Sjeff * 34592654Sjeff * Arguments: 34692654Sjeff * zone The zone to update 34792654Sjeff * obj The obj to use for future allocations 34892654Sjeff * size The size of the object to allocate 34992654Sjeff * 35092654Sjeff * Returns: 35192654Sjeff * 0 if kva space can not be allocated 35292654Sjeff * 1 if successful 35392654Sjeff * 35492654Sjeff * Discussion: 35592654Sjeff * A NULL object can be used and uma will allocate one for you. Setting 35692654Sjeff * the size will limit the amount of memory allocated to this zone. 35792654Sjeff * 35892654Sjeff */ 35992654Sjeffstruct vm_object; 36092654Sjeffint uma_zone_set_obj(uma_zone_t zone, struct vm_object *obj, int size); 36192654Sjeff 36292758Sjeff/* 36392758Sjeff * Sets a high limit on the number of items allowed in a zone 36492758Sjeff * 36592758Sjeff * Arguments: 36692758Sjeff * zone The zone to limit 36792758Sjeff * 36892758Sjeff * Returns: 36992758Sjeff * Nothing 37092758Sjeff */ 37192758Sjeffvoid uma_zone_set_max(uma_zone_t zone, int nitems); 37292654Sjeff 37392654Sjeff/* 37492654Sjeff * Replaces the standard page_alloc or obj_alloc functions for this zone 37592654Sjeff * 37692654Sjeff * Arguments: 37792654Sjeff * zone The zone whos back end allocator is being changed. 37892654Sjeff * allocf A pointer to the allocation function 37992654Sjeff * 38092654Sjeff * Returns: 38192654Sjeff * Nothing 38292654Sjeff * 38392654Sjeff * Discussion: 38492654Sjeff * This could be used to implement pageable allocation, or perhaps 38592654Sjeff * even DMA allocators if used in conjunction with the OFFPAGE 38692654Sjeff * zone flag. 38792654Sjeff */ 38892654Sjeff 38992654Sjeffvoid uma_zone_set_allocf(uma_zone_t zone, uma_alloc allocf); 39092654Sjeff 39192654Sjeff/* 39292654Sjeff * Used for freeing memory provided by the allocf above 39392654Sjeff * 39492654Sjeff * Arguments: 39592654Sjeff * zone The zone that intends to use this free routine. 39692654Sjeff * freef The page freeing routine. 39792654Sjeff * 39892654Sjeff * Returns: 39992654Sjeff * Nothing 40092654Sjeff */ 40192654Sjeff 40292654Sjeffvoid uma_zone_set_freef(uma_zone_t zone, uma_free freef); 40392654Sjeff 40492654Sjeff/* 40592654Sjeff * These flags are setable in the allocf and visable in the freef. 40692654Sjeff */ 40792654Sjeff#define UMA_SLAB_BOOT 0x01 /* Slab alloced from boot pages */ 40892654Sjeff#define UMA_SLAB_KMEM 0x02 /* Slab alloced from kmem_map */ 40992654Sjeff#define UMA_SLAB_KMAP 0x04 /* Slab alloced from kernel_map */ 41092654Sjeff#define UMA_SLAB_PRIV 0x08 /* Slab alloced from priv allocator */ 41192654Sjeff#define UMA_SLAB_OFFP 0x10 /* Slab is managed seperately */ 41292654Sjeff#define UMA_SLAB_MALLOC 0x20 /* Slab is a large malloc slab */ 41392654Sjeff/* 0x40 and 0x80 are available */ 41492654Sjeff 41592654Sjeff/* 41692654Sjeff * Used to pre-fill a zone with some number of items 41792654Sjeff * 41892654Sjeff * Arguments: 41992654Sjeff * zone The zone to fill 42092654Sjeff * itemcnt The number of items to reserve 42192654Sjeff * 42292654Sjeff * Returns: 42392654Sjeff * Nothing 42492654Sjeff * 42592654Sjeff * NOTE: This is blocking and should only be done at startup 42692654Sjeff */ 42792654Sjeffvoid uma_prealloc(uma_zone_t zone, int itemcnt); 42892654Sjeff 42992654Sjeff 43092654Sjeff#endif 431