1 /* $OpenBSD: pool.h,v 1.18 2004/07/29 09:18:17 mickey Exp $ */ 2 /* $NetBSD: pool.h,v 1.27 2001/06/06 22:00:17 rafal Exp $ */ 3 4 /*- 5 * Copyright (c) 1997, 1998, 1999, 2000 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Paul Kranenburg; by Jason R. Thorpe of the Numerical Aerospace 10 * Simulation Facility, NASA Ames Research Center. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the NetBSD 23 * Foundation, Inc. and its contributors. 24 * 4. Neither the name of The NetBSD Foundation nor the names of its 25 * contributors may be used to endorse or promote products derived 26 * from this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 */ 40 41 #ifndef _SYS_POOL_H_ 42 #define _SYS_POOL_H_ 43 44 /* 45 * sysctls. 46 * kern.pool.npools 47 * kern.pool.name.<number> 48 * kern.pool.pool.<number> 49 */ 50 #define KERN_POOL_NPOOLS 1 51 #define KERN_POOL_NAME 2 52 #define KERN_POOL_POOL 3 53 54 #include <sys/lock.h> 55 #include <sys/queue.h> 56 #include <sys/time.h> 57 #include <sys/tree.h> 58 59 struct pool_cache { 60 TAILQ_ENTRY(pool_cache) 61 pc_poollist; /* entry on pool's group list */ 62 TAILQ_HEAD(, pool_cache_group) 63 pc_grouplist; /* Cache group list */ 64 struct pool_cache_group 65 *pc_allocfrom; /* group to allocate from */ 66 struct pool_cache_group 67 *pc_freeto; /* grop to free to */ 68 struct pool *pc_pool; /* parent pool */ 69 struct simplelock pc_slock; /* mutex */ 70 71 int (*pc_ctor)(void *, void *, int); 72 void (*pc_dtor)(void *, void *); 73 void *pc_arg; 74 75 /* Statistics. */ 76 unsigned long pc_hits; /* cache hits */ 77 unsigned long pc_misses; /* cache misses */ 78 79 unsigned long pc_ngroups; /* # cache groups */ 80 81 unsigned long pc_nitems; /* # objects currently in cache */ 82 }; 83 84 struct pool_allocator { 85 void *(*pa_alloc)(struct pool *, int); 86 void (*pa_free)(struct pool *, void *); 87 int pa_pagesz; 88 89 /* The following fields are for internal use only */ 90 struct simplelock pa_slock; 91 TAILQ_HEAD(,pool) pa_list; 92 int pa_flags; 93 #define PA_INITIALIZED 0x01 94 #define PA_WANT 0x02 /* wakeup any sleeping pools on free */ 95 int pa_pagemask; 96 int pa_pageshift; 97 }; 98 99 LIST_HEAD(pool_pagelist,pool_item_header); 100 101 struct pool { 102 TAILQ_ENTRY(pool) 103 pr_poollist; 104 struct pool_pagelist 105 pr_emptypages; /* Empty pages */ 106 struct pool_pagelist 107 pr_fullpages; /* Full pages */ 108 struct pool_pagelist 109 pr_partpages; /* Partially-allocated pages */ 110 struct pool_item_header *pr_curpage; 111 TAILQ_HEAD(,pool_cache) 112 pr_cachelist; /* Caches for this pool */ 113 unsigned int pr_size; /* Size of item */ 114 unsigned int pr_align; /* Requested alignment, must be 2^n */ 115 unsigned int pr_itemoffset; /* Align this offset in item */ 116 unsigned int pr_minitems; /* minimum # of items to keep */ 117 unsigned int pr_minpages; /* same in page units */ 118 unsigned int pr_maxpages; /* maximum # of idle pages to keep */ 119 unsigned int pr_npages; /* # of pages allocated */ 120 unsigned int pr_itemsperpage;/* # items that fit in a page */ 121 unsigned int pr_slack; /* unused space in a page */ 122 unsigned int pr_nitems; /* number of available items in pool */ 123 unsigned int pr_nout; /* # items currently allocated */ 124 unsigned int pr_hardlimit; /* hard limit to number of allocated 125 items */ 126 unsigned int pr_serial; /* unique serial number of the pool */ 127 struct pool_allocator *pr_alloc;/* backend allocator */ 128 TAILQ_ENTRY(pool) pr_alloc_list;/* list of pools using this allocator */ 129 const char *pr_wchan; /* tsleep(9) identifier */ 130 unsigned int pr_flags; /* r/w flags */ 131 unsigned int pr_roflags; /* r/o flags */ 132 #define PR_MALLOCOK 0x01 133 #define PR_NOWAIT 0x00 /* for symmetry */ 134 #define PR_WAITOK 0x02 135 #define PR_WANTED 0x04 136 #define PR_PHINPAGE 0x08 137 #define PR_LOGGING 0x10 138 #define PR_LIMITFAIL 0x20 /* even if waiting, fail if we hit limit */ 139 #define PR_DEBUG 0x40 140 141 /* 142 * `pr_slock' protects the pool's data structures when removing 143 * items from or returning items to the pool, or when reading 144 * or updating read/write fields in the pool descriptor. 145 * 146 * We assume back-end page allocators provide their own locking 147 * scheme. They will be called with the pool descriptor _unlocked_, 148 * since the page allocators may block. 149 */ 150 struct simplelock pr_slock; 151 152 SPLAY_HEAD(phtree, pool_item_header) pr_phtree; 153 154 int pr_maxcolor; /* Cache colouring */ 155 int pr_curcolor; 156 int pr_phoffset; /* Offset in page of page header */ 157 158 /* 159 * Warning message to be issued, and a per-time-delta rate cap, 160 * if the hard limit is reached. 161 */ 162 const char *pr_hardlimit_warning; 163 struct timeval pr_hardlimit_ratecap; 164 struct timeval pr_hardlimit_warning_last; 165 166 /* 167 * Instrumentation 168 */ 169 unsigned long pr_nget; /* # of successful requests */ 170 unsigned long pr_nfail; /* # of unsuccessful requests */ 171 unsigned long pr_nput; /* # of releases */ 172 unsigned long pr_npagealloc; /* # of pages allocated */ 173 unsigned long pr_npagefree; /* # of pages released */ 174 unsigned int pr_hiwat; /* max # of pages in pool */ 175 unsigned long pr_nidle; /* # of idle pages */ 176 177 /* 178 * Diagnostic aides. 179 */ 180 struct pool_log *pr_log; 181 int pr_curlogentry; 182 int pr_logsize; 183 184 const char *pr_entered_file; /* reentrancy check */ 185 long pr_entered_line; 186 void (*pr_drain_hook)(void *, int); 187 void *pr_drain_hook_arg; 188 }; 189 190 #ifdef _KERNEL 191 /* old nointr allocator, still needed for large allocations */ 192 extern struct pool_allocator pool_allocator_oldnointr; 193 /* interrupt safe (name preserved for compat) new default allocator */ 194 extern struct pool_allocator pool_allocator_nointr; 195 /* previous interrupt safe allocator, allocates from kmem */ 196 extern struct pool_allocator pool_allocator_kmem; 197 198 int pool_allocator_drain(struct pool_allocator *, struct pool *, 199 int); 200 201 void pool_init(struct pool *, size_t, u_int, u_int, int, 202 const char *, struct pool_allocator *); 203 void pool_destroy(struct pool *); 204 205 void pool_set_drain_hook(struct pool *, void (*)(void *, int), 206 void *); 207 208 void *pool_get(struct pool *, int); 209 void pool_put(struct pool *, void *); 210 int pool_reclaim(struct pool *); 211 212 #ifdef POOL_DIAGNOSTIC 213 /* 214 * These versions do reentrancy checking. 215 */ 216 void *_pool_get(struct pool *, int, const char *, long); 217 void _pool_put(struct pool *, void *, const char *, long); 218 int _pool_reclaim(struct pool *, const char *, long); 219 #define pool_get(h, f) _pool_get((h), (f), __FILE__, __LINE__) 220 #define pool_put(h, v) _pool_put((h), (v), __FILE__, __LINE__) 221 #define pool_reclaim(h) _pool_reclaim((h), __FILE__, __LINE__) 222 #endif /* POOL_DIAGNOSTIC */ 223 224 int pool_prime(struct pool *, int); 225 void pool_setlowat(struct pool *, int); 226 void pool_sethiwat(struct pool *, int); 227 int pool_sethardlimit(struct pool *, unsigned, const char *, int); 228 void pool_drain(void *); 229 230 #ifdef DDB 231 /* 232 * Debugging and diagnostic aides. 233 */ 234 void pool_printit(struct pool *, const char *, 235 int (*)(const char *, ...)); 236 int pool_chk(struct pool *, const char *); 237 #endif 238 239 /* 240 * Pool cache routines. 241 */ 242 void pool_cache_init(struct pool_cache *, struct pool *, 243 int (*ctor)(void *, void *, int), 244 void (*dtor)(void *, void *), 245 void *); 246 void pool_cache_destroy(struct pool_cache *); 247 void *pool_cache_get(struct pool_cache *, int); 248 void pool_cache_put(struct pool_cache *, void *); 249 void pool_cache_destruct_object(struct pool_cache *, void *); 250 void pool_cache_invalidate(struct pool_cache *); 251 #endif /* _KERNEL */ 252 253 #endif /* _SYS_POOL_H_ */ 254