uma.h revision 103531
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 103531 2002-09-18 08:26:30Z 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 16295925Sarruma_zone_t uma_zcreate(char *name, size_t 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! */ 17595758Sjeff#define UMA_ZONE_MTXCLASS 0x0040 /* Create a new lock class */ 176103531Sjeff#define UMA_ZONE_VM 0x0080 /* 177103531Sjeff * Used for internal vm datastructures 178103531Sjeff * only. 179103531Sjeff */ 180103531Sjeff#define UMA_ZONE_HASH 0x0100 /* 181103531Sjeff * Use a hash table instead of caching 182103531Sjeff * information in the vm_page. 183103531Sjeff */ 18492654Sjeff 18592654Sjeff/* Definitions for align */ 18692654Sjeff#define UMA_ALIGN_PTR (sizeof(void *) - 1) /* Alignment fit for ptr */ 18792654Sjeff#define UMA_ALIGN_LONG (sizeof(long) - 1) /* "" long */ 18892654Sjeff#define UMA_ALIGN_INT (sizeof(int) - 1) /* "" int */ 18992654Sjeff#define UMA_ALIGN_SHORT (sizeof(short) - 1) /* "" short */ 19092654Sjeff#define UMA_ALIGN_CHAR (sizeof(char) - 1) /* "" char */ 19192654Sjeff#define UMA_ALIGN_CACHE (16 - 1) /* Cache line size align */ 19292654Sjeff 19392654Sjeff/* 19494161Sjeff * Destroys an empty uma zone. If the zone is not empty uma complains loudly. 19592654Sjeff * 19692654Sjeff * Arguments: 19792654Sjeff * zone The zone we want to destroy. 19892654Sjeff * 19992654Sjeff */ 20092654Sjeff 20194161Sjeffvoid uma_zdestroy(uma_zone_t zone); 20292654Sjeff 20392654Sjeff/* 20492654Sjeff * Allocates an item out of a zone 20592654Sjeff * 20692654Sjeff * Arguments: 20792654Sjeff * zone The zone we are allocating from 20892654Sjeff * arg This data is passed to the ctor function 20995766Sjeff * flags See sys/malloc.h for available flags. 21092654Sjeff * 21192654Sjeff * Returns: 21292654Sjeff * A non null pointer to an initialized element from the zone is 21392654Sjeff * garanteed if the wait flag is M_WAITOK, otherwise a null pointer may be 21492654Sjeff * returned if the zone is empty or the ctor failed. 21592654Sjeff */ 21692654Sjeff 21795766Sjeffvoid *uma_zalloc_arg(uma_zone_t zone, void *arg, int flags); 21892654Sjeff 21992654Sjeff/* 22092654Sjeff * Allocates an item out of a zone without supplying an argument 22192654Sjeff * 22292654Sjeff * This is just a wrapper for uma_zalloc_arg for convenience. 22392654Sjeff * 22492654Sjeff */ 22595766Sjeffstatic __inline void *uma_zalloc(uma_zone_t zone, int flags); 22692654Sjeff 22792654Sjeffstatic __inline void * 22895766Sjeffuma_zalloc(uma_zone_t zone, int flags) 22992654Sjeff{ 23095766Sjeff return uma_zalloc_arg(zone, NULL, flags); 23192654Sjeff} 23292654Sjeff 23392654Sjeff/* 23492654Sjeff * Frees an item back into the specified zone. 23592654Sjeff * 23692654Sjeff * Arguments: 23792654Sjeff * zone The zone the item was originally allocated out of. 23892654Sjeff * item The memory to be freed. 23992654Sjeff * arg Argument passed to the destructor 24092654Sjeff * 24192654Sjeff * Returns: 24292654Sjeff * Nothing. 24392654Sjeff */ 24492654Sjeff 24592654Sjeffvoid uma_zfree_arg(uma_zone_t zone, void *item, void *arg); 24692654Sjeff 24792654Sjeff/* 24892654Sjeff * Frees an item back to a zone without supplying an argument 24992654Sjeff * 25092654Sjeff * This is just a wrapper for uma_zfree_arg for convenience. 25192654Sjeff * 25292654Sjeff */ 25392654Sjeffstatic __inline void uma_zfree(uma_zone_t zone, void *item); 25492654Sjeff 25592654Sjeffstatic __inline void 25692654Sjeffuma_zfree(uma_zone_t zone, void *item) 25792654Sjeff{ 258100326Smarkm uma_zfree_arg(zone, item, NULL); 25992654Sjeff} 26092654Sjeff 26192654Sjeff/* 26292654Sjeff * XXX The rest of the prototypes in this header are h0h0 magic for the VM. 26392654Sjeff * If you think you need to use it for a normal zone you're probably incorrect. 26492654Sjeff */ 26592654Sjeff 26692654Sjeff/* 26792654Sjeff * Backend page supplier routines 26892654Sjeff * 26992654Sjeff * Arguments: 27092654Sjeff * zone The zone that is requesting pages 27192654Sjeff * size The number of bytes being requested 27292654Sjeff * pflag Flags for these memory pages, see below. 27392654Sjeff * wait Indicates our willingness to block. 27492654Sjeff * 27592654Sjeff * Returns: 27692654Sjeff * A pointer to the alloced memory or NULL on failure. 27792654Sjeff */ 27892654Sjeff 27992654Sjefftypedef void *(*uma_alloc)(uma_zone_t zone, int size, u_int8_t *pflag, int wait); 28092654Sjeff 28192654Sjeff/* 28292654Sjeff * Backend page free routines 28392654Sjeff * 28492654Sjeff * Arguments: 28592654Sjeff * item A pointer to the previously allocated pages 28692654Sjeff * size The original size of the allocation 28792654Sjeff * pflag The flags for the slab. See UMA_SLAB_* below 28892654Sjeff * 28992654Sjeff * Returns: 29092654Sjeff * None 29192654Sjeff */ 29292654Sjefftypedef void (*uma_free)(void *item, int size, u_int8_t pflag); 29392654Sjeff 29492654Sjeff 29592654Sjeff 29692654Sjeff/* 29792654Sjeff * Sets up the uma allocator. (Called by vm_mem_init) 29892654Sjeff * 29992654Sjeff * Arguments: 30092654Sjeff * bootmem A pointer to memory used to bootstrap the system. 30192654Sjeff * 30292654Sjeff * Returns: 30392654Sjeff * Nothing 30492654Sjeff * 30592654Sjeff * Discussion: 30692654Sjeff * This memory is used for zones which allocate things before the 30792654Sjeff * backend page supplier can give us pages. It should be 30892654Sjeff * UMA_SLAB_SIZE * UMA_BOOT_PAGES bytes. (see uma_int.h) 30992654Sjeff * 31092654Sjeff */ 31192654Sjeff 31292654Sjeffvoid uma_startup(void *bootmem); 31392654Sjeff 31492654Sjeff/* 31592654Sjeff * Finishes starting up the allocator. This should 31692654Sjeff * be called when kva is ready for normal allocs. 31792654Sjeff * 31892654Sjeff * Arguments: 319103531Sjeff * None 32092654Sjeff * 32192654Sjeff * Returns: 32292654Sjeff * Nothing 32392654Sjeff * 32492654Sjeff * Discussion: 325103531Sjeff * uma_startup2 is called by kmeminit() to enable us of uma for malloc. 32692654Sjeff */ 32792654Sjeff 328103531Sjeffvoid uma_startup2(void); 32992654Sjeff 33092654Sjeff/* 33192654Sjeff * Reclaims unused memory for all zones 33292654Sjeff * 33392654Sjeff * Arguments: 33492654Sjeff * None 33592654Sjeff * Returns: 33692654Sjeff * None 33792654Sjeff * 33892654Sjeff * This should only be called by the page out daemon. 33992654Sjeff */ 34092654Sjeff 34192654Sjeffvoid uma_reclaim(void); 34292654Sjeff 34392654Sjeff/* 34492654Sjeff * Switches the backing object of a zone 34592654Sjeff * 34692654Sjeff * Arguments: 34792654Sjeff * zone The zone to update 34892654Sjeff * obj The obj to use for future allocations 34992654Sjeff * size The size of the object to allocate 35092654Sjeff * 35192654Sjeff * Returns: 35292654Sjeff * 0 if kva space can not be allocated 35392654Sjeff * 1 if successful 35492654Sjeff * 35592654Sjeff * Discussion: 35692654Sjeff * A NULL object can be used and uma will allocate one for you. Setting 35792654Sjeff * the size will limit the amount of memory allocated to this zone. 35892654Sjeff * 35992654Sjeff */ 36092654Sjeffstruct vm_object; 36192654Sjeffint uma_zone_set_obj(uma_zone_t zone, struct vm_object *obj, int size); 36292654Sjeff 36392758Sjeff/* 36492758Sjeff * Sets a high limit on the number of items allowed in a zone 36592758Sjeff * 36692758Sjeff * Arguments: 36792758Sjeff * zone The zone to limit 36892758Sjeff * 36992758Sjeff * Returns: 37092758Sjeff * Nothing 37192758Sjeff */ 37292758Sjeffvoid uma_zone_set_max(uma_zone_t zone, int nitems); 37392654Sjeff 37492654Sjeff/* 37592654Sjeff * Replaces the standard page_alloc or obj_alloc functions for this zone 37692654Sjeff * 37792654Sjeff * Arguments: 37892654Sjeff * zone The zone whos back end allocator is being changed. 37992654Sjeff * allocf A pointer to the allocation function 38092654Sjeff * 38192654Sjeff * Returns: 38292654Sjeff * Nothing 38392654Sjeff * 38492654Sjeff * Discussion: 38592654Sjeff * This could be used to implement pageable allocation, or perhaps 38692654Sjeff * even DMA allocators if used in conjunction with the OFFPAGE 38792654Sjeff * zone flag. 38892654Sjeff */ 38992654Sjeff 39092654Sjeffvoid uma_zone_set_allocf(uma_zone_t zone, uma_alloc allocf); 39192654Sjeff 39292654Sjeff/* 39392654Sjeff * Used for freeing memory provided by the allocf above 39492654Sjeff * 39592654Sjeff * Arguments: 39692654Sjeff * zone The zone that intends to use this free routine. 39792654Sjeff * freef The page freeing routine. 39892654Sjeff * 39992654Sjeff * Returns: 40092654Sjeff * Nothing 40192654Sjeff */ 40292654Sjeff 40392654Sjeffvoid uma_zone_set_freef(uma_zone_t zone, uma_free freef); 40492654Sjeff 40592654Sjeff/* 40692654Sjeff * These flags are setable in the allocf and visable in the freef. 40792654Sjeff */ 40892654Sjeff#define UMA_SLAB_BOOT 0x01 /* Slab alloced from boot pages */ 40992654Sjeff#define UMA_SLAB_KMEM 0x02 /* Slab alloced from kmem_map */ 41092654Sjeff#define UMA_SLAB_PRIV 0x08 /* Slab alloced from priv allocator */ 41194157Sjeff#define UMA_SLAB_OFFP 0x10 /* Slab is managed separately */ 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