1*7ee8adcfSJonathan CorbetThe genalloc/genpool subsystem 2*7ee8adcfSJonathan Corbet============================== 3*7ee8adcfSJonathan Corbet 4*7ee8adcfSJonathan CorbetThere are a number of memory-allocation subsystems in the kernel, each 5*7ee8adcfSJonathan Corbetaimed at a specific need. Sometimes, however, a kernel developer needs to 6*7ee8adcfSJonathan Corbetimplement a new allocator for a specific range of special-purpose memory; 7*7ee8adcfSJonathan Corbetoften that memory is located on a device somewhere. The author of the 8*7ee8adcfSJonathan Corbetdriver for that device can certainly write a little allocator to get the 9*7ee8adcfSJonathan Corbetjob done, but that is the way to fill the kernel with dozens of poorly 10*7ee8adcfSJonathan Corbettested allocators. Back in 2005, Jes Sorensen lifted one of those 11*7ee8adcfSJonathan Corbetallocators from the sym53c8xx_2 driver and posted_ it as a generic module 12*7ee8adcfSJonathan Corbetfor the creation of ad hoc memory allocators. This code was merged 13*7ee8adcfSJonathan Corbetfor the 2.6.13 release; it has been modified considerably since then. 14*7ee8adcfSJonathan Corbet 15*7ee8adcfSJonathan Corbet.. _posted: https://lwn.net/Articles/125842/ 16*7ee8adcfSJonathan Corbet 17*7ee8adcfSJonathan CorbetCode using this allocator should include <linux/genalloc.h>. The action 18*7ee8adcfSJonathan Corbetbegins with the creation of a pool using one of: 19*7ee8adcfSJonathan Corbet 20*7ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 21*7ee8adcfSJonathan Corbet :functions: gen_pool_create 22*7ee8adcfSJonathan Corbet 23*7ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 24*7ee8adcfSJonathan Corbet :functions: devm_gen_pool_create 25*7ee8adcfSJonathan Corbet 26*7ee8adcfSJonathan CorbetA call to :c:func:`gen_pool_create` will create a pool. The granularity of 27*7ee8adcfSJonathan Corbetallocations is set with min_alloc_order; it is a log-base-2 number like 28*7ee8adcfSJonathan Corbetthose used by the page allocator, but it refers to bytes rather than pages. 29*7ee8adcfSJonathan CorbetSo, if min_alloc_order is passed as 3, then all allocations will be a 30*7ee8adcfSJonathan Corbetmultiple of eight bytes. Increasing min_alloc_order decreases the memory 31*7ee8adcfSJonathan Corbetrequired to track the memory in the pool. The nid parameter specifies 32*7ee8adcfSJonathan Corbetwhich NUMA node should be used for the allocation of the housekeeping 33*7ee8adcfSJonathan Corbetstructures; it can be -1 if the caller doesn't care. 34*7ee8adcfSJonathan Corbet 35*7ee8adcfSJonathan CorbetThe "managed" interface :c:func:`devm_gen_pool_create` ties the pool to a 36*7ee8adcfSJonathan Corbetspecific device. Among other things, it will automatically clean up the 37*7ee8adcfSJonathan Corbetpool when the given device is destroyed. 38*7ee8adcfSJonathan Corbet 39*7ee8adcfSJonathan CorbetA pool is shut down with: 40*7ee8adcfSJonathan Corbet 41*7ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 42*7ee8adcfSJonathan Corbet :functions: gen_pool_destroy 43*7ee8adcfSJonathan Corbet 44*7ee8adcfSJonathan CorbetIt's worth noting that, if there are still allocations outstanding from the 45*7ee8adcfSJonathan Corbetgiven pool, this function will take the rather extreme step of invoking 46*7ee8adcfSJonathan CorbetBUG(), crashing the entire system. You have been warned. 47*7ee8adcfSJonathan Corbet 48*7ee8adcfSJonathan CorbetA freshly created pool has no memory to allocate. It is fairly useless in 49*7ee8adcfSJonathan Corbetthat state, so one of the first orders of business is usually to add memory 50*7ee8adcfSJonathan Corbetto the pool. That can be done with one of: 51*7ee8adcfSJonathan Corbet 52*7ee8adcfSJonathan Corbet.. kernel-doc:: include/linux/genalloc.h 53*7ee8adcfSJonathan Corbet :functions: gen_pool_add 54*7ee8adcfSJonathan Corbet 55*7ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 56*7ee8adcfSJonathan Corbet :functions: gen_pool_add_virt 57*7ee8adcfSJonathan Corbet 58*7ee8adcfSJonathan CorbetA call to :c:func:`gen_pool_add` will place the size bytes of memory 59*7ee8adcfSJonathan Corbetstarting at addr (in the kernel's virtual address space) into the given 60*7ee8adcfSJonathan Corbetpool, once again using nid as the node ID for ancillary memory allocations. 61*7ee8adcfSJonathan CorbetThe :c:func:`gen_pool_add_virt` variant associates an explicit physical 62*7ee8adcfSJonathan Corbetaddress with the memory; this is only necessary if the pool will be used 63*7ee8adcfSJonathan Corbetfor DMA allocations. 64*7ee8adcfSJonathan Corbet 65*7ee8adcfSJonathan CorbetThe functions for allocating memory from the pool (and putting it back) 66*7ee8adcfSJonathan Corbetare: 67*7ee8adcfSJonathan Corbet 68*7ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 69*7ee8adcfSJonathan Corbet :functions: gen_pool_alloc 70*7ee8adcfSJonathan Corbet 71*7ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 72*7ee8adcfSJonathan Corbet :functions: gen_pool_dma_alloc 73*7ee8adcfSJonathan Corbet 74*7ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 75*7ee8adcfSJonathan Corbet :functions: gen_pool_free 76*7ee8adcfSJonathan Corbet 77*7ee8adcfSJonathan CorbetAs one would expect, :c:func:`gen_pool_alloc` will allocate size< bytes 78*7ee8adcfSJonathan Corbetfrom the given pool. The :c:func:`gen_pool_dma_alloc` variant allocates 79*7ee8adcfSJonathan Corbetmemory for use with DMA operations, returning the associated physical 80*7ee8adcfSJonathan Corbetaddress in the space pointed to by dma. This will only work if the memory 81*7ee8adcfSJonathan Corbetwas added with :c:func:`gen_pool_add_virt`. Note that this function 82*7ee8adcfSJonathan Corbetdeparts from the usual genpool pattern of using unsigned long values to 83*7ee8adcfSJonathan Corbetrepresent kernel addresses; it returns a void * instead. 84*7ee8adcfSJonathan Corbet 85*7ee8adcfSJonathan CorbetThat all seems relatively simple; indeed, some developers clearly found it 86*7ee8adcfSJonathan Corbetto be too simple. After all, the interface above provides no control over 87*7ee8adcfSJonathan Corbethow the allocation functions choose which specific piece of memory to 88*7ee8adcfSJonathan Corbetreturn. If that sort of control is needed, the following functions will be 89*7ee8adcfSJonathan Corbetof interest: 90*7ee8adcfSJonathan Corbet 91*7ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 92*7ee8adcfSJonathan Corbet :functions: gen_pool_alloc_algo 93*7ee8adcfSJonathan Corbet 94*7ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 95*7ee8adcfSJonathan Corbet :functions: gen_pool_set_algo 96*7ee8adcfSJonathan Corbet 97*7ee8adcfSJonathan CorbetAllocations with :c:func:`gen_pool_alloc_algo` specify an algorithm to be 98*7ee8adcfSJonathan Corbetused to choose the memory to be allocated; the default algorithm can be set 99*7ee8adcfSJonathan Corbetwith :c:func:`gen_pool_set_algo`. The data value is passed to the 100*7ee8adcfSJonathan Corbetalgorithm; most ignore it, but it is occasionally needed. One can, 101*7ee8adcfSJonathan Corbetnaturally, write a special-purpose algorithm, but there is a fair set 102*7ee8adcfSJonathan Corbetalready available: 103*7ee8adcfSJonathan Corbet 104*7ee8adcfSJonathan Corbet- gen_pool_first_fit is a simple first-fit allocator; this is the default 105*7ee8adcfSJonathan Corbet algorithm if none other has been specified. 106*7ee8adcfSJonathan Corbet 107*7ee8adcfSJonathan Corbet- gen_pool_first_fit_align forces the allocation to have a specific 108*7ee8adcfSJonathan Corbet alignment (passed via data in a genpool_data_align structure). 109*7ee8adcfSJonathan Corbet 110*7ee8adcfSJonathan Corbet- gen_pool_first_fit_order_align aligns the allocation to the order of the 111*7ee8adcfSJonathan Corbet size. A 60-byte allocation will thus be 64-byte aligned, for example. 112*7ee8adcfSJonathan Corbet 113*7ee8adcfSJonathan Corbet- gen_pool_best_fit, as one would expect, is a simple best-fit allocator. 114*7ee8adcfSJonathan Corbet 115*7ee8adcfSJonathan Corbet- gen_pool_fixed_alloc allocates at a specific offset (passed in a 116*7ee8adcfSJonathan Corbet genpool_data_fixed structure via the data parameter) within the pool. 117*7ee8adcfSJonathan Corbet If the indicated memory is not available the allocation fails. 118*7ee8adcfSJonathan Corbet 119*7ee8adcfSJonathan CorbetThere is a handful of other functions, mostly for purposes like querying 120*7ee8adcfSJonathan Corbetthe space available in the pool or iterating through chunks of memory. 121*7ee8adcfSJonathan CorbetMost users, however, should not need much beyond what has been described 122*7ee8adcfSJonathan Corbetabove. With luck, wider awareness of this module will help to prevent the 123*7ee8adcfSJonathan Corbetwriting of special-purpose memory allocators in the future. 124*7ee8adcfSJonathan Corbet 125*7ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 126*7ee8adcfSJonathan Corbet :functions: gen_pool_virt_to_phys 127*7ee8adcfSJonathan Corbet 128*7ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 129*7ee8adcfSJonathan Corbet :functions: gen_pool_for_each_chunk 130*7ee8adcfSJonathan Corbet 131*7ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 132*7ee8adcfSJonathan Corbet :functions: addr_in_gen_pool 133*7ee8adcfSJonathan Corbet 134*7ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 135*7ee8adcfSJonathan Corbet :functions: gen_pool_avail 136*7ee8adcfSJonathan Corbet 137*7ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 138*7ee8adcfSJonathan Corbet :functions: gen_pool_size 139*7ee8adcfSJonathan Corbet 140*7ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 141*7ee8adcfSJonathan Corbet :functions: gen_pool_get 142*7ee8adcfSJonathan Corbet 143*7ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 144*7ee8adcfSJonathan Corbet :functions: of_gen_pool_get 145