uma.h revision 105689
192654Sjeff/* 2103623Sjeff * Copyright (c) 2002, Jeffrey Roberson <jeff@freebsd.org> 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 105689 2002-10-22 12:10:27Z sheldonh $ 2792654Sjeff * 2892654Sjeff */ 2992654Sjeff 3092654Sjeff/* 3192654Sjeff * uma.h - External definitions for the Universal Memory Allocator 3292654Sjeff * 3392654Sjeff*/ 3492654Sjeff 3592654Sjeff#ifndef VM_UMA_H 3692654Sjeff#define VM_UMA_H 3792654Sjeff 3892654Sjeff#include <sys/param.h> /* For NULL */ 3992654Sjeff#include <sys/malloc.h> /* For M_* */ 4092654Sjeff 4192654Sjeff/* User visable parameters */ 4292654Sjeff#define UMA_SMALLEST_UNIT (PAGE_SIZE / 256) /* Smallest item allocated */ 4392654Sjeff 4492654Sjeff/* Types and type defs */ 4592654Sjeff 4692654Sjeffstruct uma_zone; 4792654Sjeff/* Opaque type used as a handle to the zone */ 4892654Sjefftypedef struct uma_zone * uma_zone_t; 4992654Sjeff 5092654Sjeff/* 5192654Sjeff * Item constructor 5292654Sjeff * 5392654Sjeff * Arguments: 5492654Sjeff * item A pointer to the memory which has been allocated. 5592654Sjeff * arg The arg field passed to uma_zalloc_arg 5692654Sjeff * size The size of the allocated item 5792654Sjeff * 5892654Sjeff * Returns: 5992654Sjeff * Nothing 6092654Sjeff * 6192654Sjeff * Discussion: 6292654Sjeff * The constructor is called just before the memory is returned 63105689Ssheldonh * to the user. It may block if necessary. 6492654Sjeff */ 6592654Sjefftypedef void (*uma_ctor)(void *mem, int size, void *arg); 6692654Sjeff 6792654Sjeff/* 6892654Sjeff * Item destructor 6992654Sjeff * 7092654Sjeff * Arguments: 7192654Sjeff * item A pointer to the memory which has been allocated. 7292654Sjeff * size The size of the item being destructed. 7392654Sjeff * arg Argument passed through uma_zfree_arg 7492654Sjeff * 7592654Sjeff * Returns: 7692654Sjeff * Nothing 7792654Sjeff * 7892654Sjeff * Discussion: 7992654Sjeff * The destructor may perform operations that differ from those performed 8092654Sjeff * by the initializer, but it must leave the object in the same state. 8192654Sjeff * This IS type stable storage. This is called after EVERY zfree call. 8292654Sjeff */ 8392654Sjefftypedef void (*uma_dtor)(void *mem, int size, void *arg); 8492654Sjeff 8592654Sjeff/* 8692654Sjeff * Item initializer 8792654Sjeff * 8892654Sjeff * Arguments: 8992654Sjeff * item A pointer to the memory which has been allocated. 9092654Sjeff * size The size of the item being initialized. 9192654Sjeff * 9292654Sjeff * Returns: 9392654Sjeff * Nothing 9492654Sjeff * 9592654Sjeff * Discussion: 9692654Sjeff * The initializer is called when the memory is cached in the uma zone. 9792654Sjeff * this should be the same state that the destructor leaves the object in. 9892654Sjeff */ 9992654Sjefftypedef void (*uma_init)(void *mem, int size); 10092654Sjeff 10192654Sjeff/* 10292654Sjeff * Item discard function 10392654Sjeff * 10492654Sjeff * Arguments: 10592654Sjeff * item A pointer to memory which has been 'freed' but has not left the 10692654Sjeff * zone's cache. 10792654Sjeff * size The size of the item being discarded. 10892654Sjeff * 10992654Sjeff * Returns: 11092654Sjeff * Nothing 11192654Sjeff * 11292654Sjeff * Discussion: 11392654Sjeff * This routine is called when memory leaves a zone and is returned to the 11492654Sjeff * system for other uses. It is the counter part to the init function. 11592654Sjeff */ 11692654Sjefftypedef void (*uma_fini)(void *mem, int size); 11792654Sjeff 11892654Sjeff/* 11992654Sjeff * What's the difference between initializing and constructing? 12092654Sjeff * 12192654Sjeff * The item is initialized when it is cached, and this is the state that the 12292654Sjeff * object should be in when returned to the allocator. The purpose of this is 12392654Sjeff * to remove some code which would otherwise be called on each allocation by 12492654Sjeff * utilizing a known, stable state. This differs from the constructor which 12592654Sjeff * will be called on EVERY allocation. 12692654Sjeff * 12792654Sjeff * For example, in the initializer you may want to initialize embeded locks, 12892654Sjeff * NULL list pointers, set up initial states, magic numbers, etc. This way if 129105689Ssheldonh * the object is held in the allocator and re-used it won't be necessary to 13092654Sjeff * re-initialize it. 13192654Sjeff * 13292654Sjeff * The constructor may be used to lock a data structure, link it on to lists, 13392654Sjeff * bump reference counts or total counts of outstanding structures, etc. 13492654Sjeff * 13592654Sjeff */ 13692654Sjeff 13792654Sjeff 13892654Sjeff/* Function proto types */ 13992654Sjeff 14092654Sjeff/* 14192654Sjeff * Create a new uma zone 14292654Sjeff * 14392654Sjeff * Arguments: 14492654Sjeff * name The text name of the zone for debugging and stats, this memory 14592654Sjeff * should not be freed until the zone has been deallocated. 14692654Sjeff * size The size of the object that is being created. 14792654Sjeff * ctor The constructor that is called when the object is allocated 14892654Sjeff * dtor The destructor that is called when the object is freed. 14992654Sjeff * init An initializer that sets up the initial state of the memory. 15092654Sjeff * fini A discard function that undoes initialization done by init. 15192654Sjeff * ctor/dtor/init/fini may all be null, see notes above. 15292654Sjeff * align A bitmask that corisponds to the requested alignment 15392654Sjeff * eg 4 would be 0x3 15492654Sjeff * flags A set of parameters that control the behavior of the zone 15592654Sjeff * 15692654Sjeff * Returns: 15792654Sjeff * A pointer to a structure which is intended to be opaque to users of 15892654Sjeff * the interface. The value may be null if the wait flag is not set. 15992654Sjeff */ 16092654Sjeff 16195925Sarruma_zone_t uma_zcreate(char *name, size_t size, uma_ctor ctor, uma_dtor dtor, 16292654Sjeff uma_init uminit, uma_fini fini, int align, 16392654Sjeff u_int16_t flags); 16492654Sjeff 16592654Sjeff/* Definitions for uma_zcreate flags */ 16692654Sjeff#define UMA_ZONE_PAGEABLE 0x0001 /* Return items not fully backed by 16792654Sjeff physical memory XXX Not yet */ 16892654Sjeff#define UMA_ZONE_ZINIT 0x0002 /* Initialize with zeros */ 16992654Sjeff#define UMA_ZONE_STATIC 0x0004 /* Staticly sized zone */ 17092654Sjeff#define UMA_ZONE_OFFPAGE 0x0008 /* Force the slab structure allocation 17192654Sjeff off of the real memory */ 17292654Sjeff#define UMA_ZONE_MALLOC 0x0010 /* For use by malloc(9) only! */ 17392654Sjeff#define UMA_ZONE_NOFREE 0x0020 /* Do not free slabs of this type! */ 17495758Sjeff#define UMA_ZONE_MTXCLASS 0x0040 /* Create a new lock class */ 175103531Sjeff#define UMA_ZONE_VM 0x0080 /* 176103531Sjeff * Used for internal vm datastructures 177103531Sjeff * only. 178103531Sjeff */ 179103531Sjeff#define UMA_ZONE_HASH 0x0100 /* 180103531Sjeff * Use a hash table instead of caching 181103531Sjeff * information in the vm_page. 182103531Sjeff */ 18392654Sjeff 18492654Sjeff/* Definitions for align */ 18592654Sjeff#define UMA_ALIGN_PTR (sizeof(void *) - 1) /* Alignment fit for ptr */ 18692654Sjeff#define UMA_ALIGN_LONG (sizeof(long) - 1) /* "" long */ 18792654Sjeff#define UMA_ALIGN_INT (sizeof(int) - 1) /* "" int */ 18892654Sjeff#define UMA_ALIGN_SHORT (sizeof(short) - 1) /* "" short */ 18992654Sjeff#define UMA_ALIGN_CHAR (sizeof(char) - 1) /* "" char */ 19092654Sjeff#define UMA_ALIGN_CACHE (16 - 1) /* Cache line size align */ 19192654Sjeff 19292654Sjeff/* 19394161Sjeff * Destroys an empty uma zone. If the zone is not empty uma complains loudly. 19492654Sjeff * 19592654Sjeff * Arguments: 19692654Sjeff * zone The zone we want to destroy. 19792654Sjeff * 19892654Sjeff */ 19992654Sjeff 20094161Sjeffvoid uma_zdestroy(uma_zone_t zone); 20192654Sjeff 20292654Sjeff/* 20392654Sjeff * Allocates an item out of a zone 20492654Sjeff * 20592654Sjeff * Arguments: 20692654Sjeff * zone The zone we are allocating from 20792654Sjeff * arg This data is passed to the ctor function 20895766Sjeff * flags See sys/malloc.h for available flags. 20992654Sjeff * 21092654Sjeff * Returns: 21192654Sjeff * A non null pointer to an initialized element from the zone is 21292654Sjeff * garanteed if the wait flag is M_WAITOK, otherwise a null pointer may be 21392654Sjeff * returned if the zone is empty or the ctor failed. 21492654Sjeff */ 21592654Sjeff 21695766Sjeffvoid *uma_zalloc_arg(uma_zone_t zone, void *arg, int flags); 21792654Sjeff 21892654Sjeff/* 21992654Sjeff * Allocates an item out of a zone without supplying an argument 22092654Sjeff * 22192654Sjeff * This is just a wrapper for uma_zalloc_arg for convenience. 22292654Sjeff * 22392654Sjeff */ 22495766Sjeffstatic __inline void *uma_zalloc(uma_zone_t zone, int flags); 22592654Sjeff 22692654Sjeffstatic __inline void * 22795766Sjeffuma_zalloc(uma_zone_t zone, int flags) 22892654Sjeff{ 22995766Sjeff return uma_zalloc_arg(zone, NULL, flags); 23092654Sjeff} 23192654Sjeff 23292654Sjeff/* 23392654Sjeff * Frees an item back into the specified zone. 23492654Sjeff * 23592654Sjeff * Arguments: 23692654Sjeff * zone The zone the item was originally allocated out of. 23792654Sjeff * item The memory to be freed. 23892654Sjeff * arg Argument passed to the destructor 23992654Sjeff * 24092654Sjeff * Returns: 24192654Sjeff * Nothing. 24292654Sjeff */ 24392654Sjeff 24492654Sjeffvoid uma_zfree_arg(uma_zone_t zone, void *item, void *arg); 24592654Sjeff 24692654Sjeff/* 24792654Sjeff * Frees an item back to a zone without supplying an argument 24892654Sjeff * 24992654Sjeff * This is just a wrapper for uma_zfree_arg for convenience. 25092654Sjeff * 25192654Sjeff */ 25292654Sjeffstatic __inline void uma_zfree(uma_zone_t zone, void *item); 25392654Sjeff 25492654Sjeffstatic __inline void 25592654Sjeffuma_zfree(uma_zone_t zone, void *item) 25692654Sjeff{ 257100326Smarkm uma_zfree_arg(zone, item, NULL); 25892654Sjeff} 25992654Sjeff 26092654Sjeff/* 26192654Sjeff * XXX The rest of the prototypes in this header are h0h0 magic for the VM. 26292654Sjeff * If you think you need to use it for a normal zone you're probably incorrect. 26392654Sjeff */ 26492654Sjeff 26592654Sjeff/* 26692654Sjeff * Backend page supplier routines 26792654Sjeff * 26892654Sjeff * Arguments: 26992654Sjeff * zone The zone that is requesting pages 27092654Sjeff * size The number of bytes being requested 27192654Sjeff * pflag Flags for these memory pages, see below. 27292654Sjeff * wait Indicates our willingness to block. 27392654Sjeff * 27492654Sjeff * Returns: 27592654Sjeff * A pointer to the alloced memory or NULL on failure. 27692654Sjeff */ 27792654Sjeff 27892654Sjefftypedef void *(*uma_alloc)(uma_zone_t zone, int size, u_int8_t *pflag, int wait); 27992654Sjeff 28092654Sjeff/* 28192654Sjeff * Backend page free routines 28292654Sjeff * 28392654Sjeff * Arguments: 28492654Sjeff * item A pointer to the previously allocated pages 28592654Sjeff * size The original size of the allocation 28692654Sjeff * pflag The flags for the slab. See UMA_SLAB_* below 28792654Sjeff * 28892654Sjeff * Returns: 28992654Sjeff * None 29092654Sjeff */ 29192654Sjefftypedef void (*uma_free)(void *item, int size, u_int8_t pflag); 29292654Sjeff 29392654Sjeff 29492654Sjeff 29592654Sjeff/* 29692654Sjeff * Sets up the uma allocator. (Called by vm_mem_init) 29792654Sjeff * 29892654Sjeff * Arguments: 29992654Sjeff * bootmem A pointer to memory used to bootstrap the system. 30092654Sjeff * 30192654Sjeff * Returns: 30292654Sjeff * Nothing 30392654Sjeff * 30492654Sjeff * Discussion: 30592654Sjeff * This memory is used for zones which allocate things before the 30692654Sjeff * backend page supplier can give us pages. It should be 30792654Sjeff * UMA_SLAB_SIZE * UMA_BOOT_PAGES bytes. (see uma_int.h) 30892654Sjeff * 30992654Sjeff */ 31092654Sjeff 31192654Sjeffvoid uma_startup(void *bootmem); 31292654Sjeff 31392654Sjeff/* 31492654Sjeff * Finishes starting up the allocator. This should 31592654Sjeff * be called when kva is ready for normal allocs. 31692654Sjeff * 31792654Sjeff * Arguments: 318103531Sjeff * None 31992654Sjeff * 32092654Sjeff * Returns: 32192654Sjeff * Nothing 32292654Sjeff * 32392654Sjeff * Discussion: 324103531Sjeff * uma_startup2 is called by kmeminit() to enable us of uma for malloc. 32592654Sjeff */ 32692654Sjeff 327103531Sjeffvoid uma_startup2(void); 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_PRIV 0x08 /* Slab alloced from priv allocator */ 41094157Sjeff#define UMA_SLAB_OFFP 0x10 /* Slab is managed separately */ 41192654Sjeff#define UMA_SLAB_MALLOC 0x20 /* Slab is a large malloc slab */ 41292654Sjeff/* 0x40 and 0x80 are available */ 41392654Sjeff 41492654Sjeff/* 41592654Sjeff * Used to pre-fill a zone with some number of items 41692654Sjeff * 41792654Sjeff * Arguments: 41892654Sjeff * zone The zone to fill 41992654Sjeff * itemcnt The number of items to reserve 42092654Sjeff * 42192654Sjeff * Returns: 42292654Sjeff * Nothing 42392654Sjeff * 42492654Sjeff * NOTE: This is blocking and should only be done at startup 42592654Sjeff */ 42692654Sjeffvoid uma_prealloc(uma_zone_t zone, int itemcnt); 42792654Sjeff 42892654Sjeff 42992654Sjeff#endif 430