1.\" 2.\" Copyright (c) 2009 3.\" The DragonFly Project. All rights reserved. 4.\" 5.\" Redistribution and use in source and binary forms, with or without 6.\" modification, are permitted provided that the following conditions 7.\" are met: 8.\" 9.\" 1. Redistributions of source code must retain the above copyright 10.\" notice, this list of conditions and the following disclaimer. 11.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" notice, this list of conditions and the following disclaimer in 13.\" the documentation and/or other materials provided with the 14.\" distribution. 15.\" 3. Neither the name of The DragonFly Project nor the names of its 16.\" contributors may be used to endorse or promote products derived 17.\" from this software without specific, prior written permission. 18.\" 19.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 25.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 27.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 29.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30.\" SUCH DAMAGE. 31.\" 32.Dd January 25, 2024 33.Dt OBJCACHE 9 34.Os 35.Sh NAME 36.Nm objcache_create , 37.Nm objcache_create_mbacked , 38.Nm objcache_create_simple , 39.Nm objcache_destroy , 40.Nm objcache_dtor , 41.Nm objcache_get , 42.Nm objcache_malloc_alloc , 43.Nm objcache_malloc_free , 44.Nm objcache_nop_alloc , 45.Nm objcache_nop_free , 46.\" .Nm objcache_populate_linear , 47.Nm objcache_put , 48.Nm objcache_reclaimlist 49.Nd "object caching facility" 50.Sh SYNOPSIS 51.In sys/objcache.h 52.Bd -literal 53typedef boolean_t (objcache_ctor_fn)(void *obj, void *privdata, int ocflags); 54 55typedef void (objcache_dtor_fn)(void *obj, void *privdata); 56 57typedef void *(objcache_alloc_fn)(void *allocator_args, int ocflags); 58 59typedef void (objcache_free_fn)(void *obj, void *allocator_args); 60 61struct objcache_malloc_args { 62 size_t objsize; 63 malloc_type_t mtype; 64}; 65.Ed 66.Ft struct objcache * 67.Fo objcache_create 68.Fa "const char *name" 69.Fa "int cluster_limit" 70.Fa "int mag_capacity" 71.Fa "objcache_ctor_fn *ctor" 72.Fa "objcache_dtor_fn *dtor" 73.Fa "void *privdata" 74.Fa "objcache_alloc_fn *alloc" 75.Fa "objcache_free_fn *free" 76.Fa "void *allocator_args" 77.Fc 78.Ft struct objcache * 79.Fo objcache_create_mbacked 80.Fa "malloc_type_t mtype" 81.Fa "size_t objsize" 82.Fa "int cluster_limit" 83.Fa "int mag_capacity" 84.Fa "objcache_ctor_fn *ctor" 85.Fa "objcache_dtor_fn *dtor" 86.Fa "void *privdata" 87.Fc 88.Ft struct objcache * 89.Fn objcache_create_simple "malloc_type_t mtype" "size_t objsize" 90.Ft void 91.Fn objcache_destroy "struct objcache *oc" 92.Ft void 93.Fn objcache_dtor "struct objcache *oc" "void *obj" 94.Ft void * 95.Fn objcache_get "struct objcache *oc" "int ocflags" 96.Ft void * 97.Fn objcache_malloc_alloc "void *allocator_args" "int ocflags" 98.Ft void 99.Fn objcache_malloc_free "void *obj" "void *allocator_args" 100.Ft void * 101.Fn objcache_nop_alloc "void *allocator_args" "int ocflags" 102.Ft void 103.Fn objcache_nop_free "void *obj" "void *allocator_args" 104.\" .Ft void 105.\" .Fo objcache_populate_linear 106.\" .Fa "struct objcache *oc" 107.\" .Fa "void *elts" 108.\" .Fa "int nelts" 109.\" .Fa "int size" 110.\" .Fc 111.Ft void 112.Fn objcache_put "struct objcache *oc" "void *obj" 113.Ft boolean_t 114.Fn objcache_reclaimlist "struct objcache *oc[]" "int nlist" 115.Sh DESCRIPTION 116Object caching is a technique for manipulating objects that are frequently 117allocated and freed. 118The idea behind caching is to preserve the invariant portion of an object's 119initial state between uses, so it does not have to be destroyed and reborn 120every time the object is used. 121.Pp 122.Fn objcache_create 123creates a new object cache. 124It is identified by 125.Fa name , 126which is used to distinguish the object in diagnostic output. 127The 128.Fa cluster_limit 129determines the number of available magazines in the depot layer. 130It must be at least 131.Fa ( mag_capacity 132* ncpus * 8). 133If 0 is given, then there is no limit to the number of magazines the depot 134can have (aside from the inherent limitation imposed by the restricted nature 135of the back end allocator). 136The 137.Fa mag_capacity 138describes the capacity of the magazine, that is the largest number of objects 139it can hold. 140If set to 0, the default value is used as defined in 141.Pa sys/kern/kern_objcache.c . 142Currently, the default value is 64. 143The object caching system itself may adjust the cluster limit and/or 144magazines' capacity based on the number of available CPUs. 145.Fa ctor 146specifies a function that constructs (i.e., performs the one-time 147initialization of) an object in the cache. 148It is defined as: 149.Bd -literal 150boolean_t foo_ctor(void *obj, void *privdata, int ocflags); 151.Ed 152.Pp 153If no constructor is needed, it must be set to 154.Dv NULL . 155.Fa dtor 156specifies a destructor function that destroys the cached object, before it 157is released to the back end that manages the flow of real memory. 158It is defined as: 159.Bd -literal 160void foo_dtor(void *obj, void *privdata); 161.Ed 162.Pp 163If no destructor is needed, it must be set to 164.Dv NULL . 165The interface to underlying allocator is provided by 166.Fa alloc , 167.Fa free 168and 169.Fa allocator_args . 170It must adhere to the following form: 171.Bd -literal 172void *foo_alloc(void *allocator_args, int ocflags); 173void foo_free(void *obj, void *allocator_args); 174.Ed 175.Pp 176.Fn objcache_malloc_alloc 177and 178.Fn objcache_malloc_free 179are wrappers for 180.Xr kmalloc 9 181allocation functions. 182Whereas, 183.Fn objcache_nop_alloc 184and 185.Fn objcache_nop_free 186are wrappers for allocation policies that pre-allocate at initialization time 187instead of doing run-time allocation. 188.Pp 189.Fn objcache_create_mbacked 190creates a new object cache of size 191.Fa objsize , 192backed with a 193.Vt malloc_type_t 194argument. 195The latter is used to perform statistics in memory usage and for basic sanity 196checks. 197For the underlying allocator, 198.Xr kmalloc 9 199functions are employed. 200.Pp 201.Fn objcache_create_simple 202creates a new object cache of size 203.Fa objsize , 204backed with a 205.Vt malloc_type_t 206argument. 207The 208.Fa cluster_limit 209is set to 0 and the default value for magazines' capacity is used. 210.Fa ctor 211and 212.Fa dtor 213are set to 214.Dv NULL . 215.Fa privdata 216is set to 217.Dv NULL 218as well. 219For the underlying allocator, 220.Xr kmalloc 9 221functions are employed. 222.Pp 223.Fn objcache_get 224returns an object from the 225.Fa oc 226object cache. 227The object is in its initialized state. 228Newly allocated objects are subjected to the object cache's constructor 229function, if not 230.Dv NULL , 231prior to being returned. 232.Fa ocflags 233is only used when the depot does not have any non-empty magazines and a new 234object needs to be allocated using the back end allocator. 235In this case we cannot depend on flags such as 236.Dv M_ZERO . 237If the back end allocator fails, or if the depot's object limit has been 238reached and 239.Dv M_WAITOK 240is not specified, 241.Dv NULL 242is returned. 243.Pp 244.Fn objcache_put 245returns 246.Fa obj 247to the 248.Fa oc 249object cache. 250The object must be in its initialized state prior to this call. 251If there is no empty magazine, the object destructor is called and 252the object is freed. 253.Pp 254.Fn objcache_dtor 255puts 256.Fa obj 257back into the 258.Fa oc 259object cache, indicating that the object is not in any shape to be reused and 260should be destructed and freed immediately. 261.Pp 262.Fn objcache_reclaimlist 263iterates over the 264.Fa oclist[] 265list with 266.Fa nlist 267elements and tries to free up some memory. 268For each object cache in the reclaim list, the current per-CPU cache is tried 269first and then the full magazine depot. 270The function returns 271.Dv TRUE 272as soon as some free memory is found 273and 274.Dv FALSE 275otherwise. 276.Pp 277.Fn objcache_destroy 278destroys the 279.Fa oc 280object cache. 281The object must have no existing references. 282.\" .Pp 283.\" .Fn objcache_populate_linear 284.\" populates the per-cluster depot with elements from a linear block of memory. 285.\" Must be called for individually for each cluster. 286.\" Populated depots should not be destroyed. 287.\" Currently this function is unimplemented. 288.Sh IMPLEMENTATION NOTES 289.Ss Magazine 290A magazine is the very basic functional unit of the object caching scheme. 291The number of objects it can hold is fixed and determined by its capacity. 292The term magazine is used as an analogy with automatic weapon 293(a firearm that can fire several rounds without reloading). 294.Ss Per-CPU object cache 295The reasoning behind per-CPU caches is to allow CPUs to perform their 296transactions (i.e., allocations, frees) in a parallel, yet lockless manner. 297.Pp 298Each CPU is given two magazines, an active and a backup. 299This is done in order to avoid a situation where a tight loop of 300two allocations followed by two frees can cause thrashing at the 301magazine boundary. 302.Pp 303If we need to add an object to the cache and the active magazine is full, 304room is searched in the backup magazine. 305If the backup has room, we swap active with backup and add the object. 306If both magazines are full, we get an empty magazine from the depot 307and move a fully loaded magazine to the depot. 308.Ss Magazine depot 309Each object cache manages a global supply of magazines, the depot, that is 310available across all CPUs. 311The depot maintains two lists of magazines. 312One for completely full and one for completely free magazines. 313The per-CPU object caches only exchange completely full or 314completely empty magazines with the depot layer. 315.Sh EXAMPLES 316.Bd -literal 317/* This is the data structure we are going to cache. */ 318struct foo { 319 int x; 320 char str[32]; 321}; 322 323MALLOC_DEFINE(M_FOOBUF, "foobuf", "Buffer to my little precious data"); 324 325struct objcache_malloc_args foo_malloc_args = { 326 sizeof(struct foo), M_FOOBUF }; 327 328struct objcache *foo_cache; 329 330/* 331 * Object cache constructor. 332 */ 333static boolean_t 334foo_cache_ctor(void *obj, void *privdata, int ocflags) 335{ 336 struct foo *myfoo = obj; 337 338 /* 339 * Do any initialization of the object here. Let's just zero out 340 * the data structure for the fun of it. 341 */ 342 bzero(myfoo, sizeof(*myfoo)); 343 344 return (TRUE); 345} 346 347/* 348 * Object cache destructor. 349 */ 350static void 351foo_cache_dtor(void *obj, void *privdata) 352{ 353 struct foo *myfoo = obj; 354 355 /* 356 * Do any clean up here. E.g., if you have kmalloc'ed() inside 357 * the constructor, this is the right place and time to kfree(). 358 */ 359} 360 361/* 362 * Initialize our subsystem. 363 */ 364static void 365foo_init(void) 366{ 367 /* Create the object cache. */ 368 foo_cache = objcache_create("foo", 369 0, /* infinite depot's capacity */ 370 0, /* default magazine's capacity */ 371 foo_ctor, foo_dtor, NULL, 372 objcache_malloc_alloc, 373 objcache_malloc_free, 374 &foo_malloc_args); 375} 376 377/* 378 * Random function. 379 */ 380static void 381foo_random(...) 382{ 383 struct foo *myfoo; 384 385 /* Get a `foo' object from the object cache. */ 386 myfoo = objcache_get(foo_cache, M_WAITOK); 387 388 /* Do stuff with it. */ 389 /* ... */ 390 391 /* We don't need it anymore. Put it back in object cache. */ 392 objcache_put(foo_cache, myfoo); 393} 394 395/* 396 * Shutdown our subsystem. 397 */ 398static void 399foo_uninit(void) 400{ 401 /* Destroy the object cache. */ 402 objcache_destroy(foo_cache); 403} 404.Ed 405.Sh SEE ALSO 406.Xr memory 9 407.Rs 408.%A "Jeff Bonwick" 409.%T "The Slab Allocator: An Object-Caching Kernel Memory Allocator" 410.%R "USENIX Summer 1994 Technical Conference" 411.Re 412.Rs 413.%A "Jeff Bonwick" 414.%A "Jonathan Adams" 415.%T "Magazines and Vmem: Extending the Slab Allocator to Many CPUs and Arbitrary Resources" 416.%R "USENIX 2001 Technical Conference" 417.Re 418.Sh HISTORY 419The object caching system appeared in 420.Dx 1.3 . 421.Sh AUTHORS 422The object caching system was written by 423.An -nosplit 424.An Jeffrey M. Hsu Aq Mt hsu@freebsd.org . 425This manual page was written by 426.An Stathis Kamperis Aq Mt ekamperi@gmail.com . 427