17ee8adcfSJonathan CorbetThe genalloc/genpool subsystem 27ee8adcfSJonathan Corbet============================== 37ee8adcfSJonathan Corbet 47ee8adcfSJonathan CorbetThere are a number of memory-allocation subsystems in the kernel, each 57ee8adcfSJonathan Corbetaimed at a specific need. Sometimes, however, a kernel developer needs to 67ee8adcfSJonathan Corbetimplement a new allocator for a specific range of special-purpose memory; 77ee8adcfSJonathan Corbetoften that memory is located on a device somewhere. The author of the 87ee8adcfSJonathan Corbetdriver for that device can certainly write a little allocator to get the 97ee8adcfSJonathan Corbetjob done, but that is the way to fill the kernel with dozens of poorly 107ee8adcfSJonathan Corbettested allocators. Back in 2005, Jes Sorensen lifted one of those 117ee8adcfSJonathan Corbetallocators from the sym53c8xx_2 driver and posted_ it as a generic module 127ee8adcfSJonathan Corbetfor the creation of ad hoc memory allocators. This code was merged 137ee8adcfSJonathan Corbetfor the 2.6.13 release; it has been modified considerably since then. 147ee8adcfSJonathan Corbet 157ee8adcfSJonathan Corbet.. _posted: https://lwn.net/Articles/125842/ 167ee8adcfSJonathan Corbet 177ee8adcfSJonathan CorbetCode using this allocator should include <linux/genalloc.h>. The action 187ee8adcfSJonathan Corbetbegins with the creation of a pool using one of: 197ee8adcfSJonathan Corbet 207ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 217ee8adcfSJonathan Corbet :functions: gen_pool_create 227ee8adcfSJonathan Corbet 237ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 247ee8adcfSJonathan Corbet :functions: devm_gen_pool_create 257ee8adcfSJonathan Corbet 26*f11b46f3SJonathan CorbetA call to gen_pool_create() will create a pool. The granularity of 277ee8adcfSJonathan Corbetallocations is set with min_alloc_order; it is a log-base-2 number like 287ee8adcfSJonathan Corbetthose used by the page allocator, but it refers to bytes rather than pages. 297ee8adcfSJonathan CorbetSo, if min_alloc_order is passed as 3, then all allocations will be a 307ee8adcfSJonathan Corbetmultiple of eight bytes. Increasing min_alloc_order decreases the memory 317ee8adcfSJonathan Corbetrequired to track the memory in the pool. The nid parameter specifies 327ee8adcfSJonathan Corbetwhich NUMA node should be used for the allocation of the housekeeping 337ee8adcfSJonathan Corbetstructures; it can be -1 if the caller doesn't care. 347ee8adcfSJonathan Corbet 35*f11b46f3SJonathan CorbetThe "managed" interface devm_gen_pool_create() ties the pool to a 367ee8adcfSJonathan Corbetspecific device. Among other things, it will automatically clean up the 377ee8adcfSJonathan Corbetpool when the given device is destroyed. 387ee8adcfSJonathan Corbet 397ee8adcfSJonathan CorbetA pool is shut down with: 407ee8adcfSJonathan Corbet 417ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 427ee8adcfSJonathan Corbet :functions: gen_pool_destroy 437ee8adcfSJonathan Corbet 447ee8adcfSJonathan CorbetIt's worth noting that, if there are still allocations outstanding from the 457ee8adcfSJonathan Corbetgiven pool, this function will take the rather extreme step of invoking 467ee8adcfSJonathan CorbetBUG(), crashing the entire system. You have been warned. 477ee8adcfSJonathan Corbet 487ee8adcfSJonathan CorbetA freshly created pool has no memory to allocate. It is fairly useless in 497ee8adcfSJonathan Corbetthat state, so one of the first orders of business is usually to add memory 507ee8adcfSJonathan Corbetto the pool. That can be done with one of: 517ee8adcfSJonathan Corbet 527ee8adcfSJonathan Corbet.. kernel-doc:: include/linux/genalloc.h 537ee8adcfSJonathan Corbet :functions: gen_pool_add 547ee8adcfSJonathan Corbet 557ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 56ea83df73SJonathan Corbet :functions: gen_pool_add_owner 577ee8adcfSJonathan Corbet 58*f11b46f3SJonathan CorbetA call to gen_pool_add() will place the size bytes of memory 597ee8adcfSJonathan Corbetstarting at addr (in the kernel's virtual address space) into the given 607ee8adcfSJonathan Corbetpool, once again using nid as the node ID for ancillary memory allocations. 61*f11b46f3SJonathan CorbetThe gen_pool_add_virt() variant associates an explicit physical 627ee8adcfSJonathan Corbetaddress with the memory; this is only necessary if the pool will be used 637ee8adcfSJonathan Corbetfor DMA allocations. 647ee8adcfSJonathan Corbet 657ee8adcfSJonathan CorbetThe functions for allocating memory from the pool (and putting it back) 667ee8adcfSJonathan Corbetare: 677ee8adcfSJonathan Corbet 68ea83df73SJonathan Corbet.. kernel-doc:: include/linux/genalloc.h 697ee8adcfSJonathan Corbet :functions: gen_pool_alloc 707ee8adcfSJonathan Corbet 717ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 727ee8adcfSJonathan Corbet :functions: gen_pool_dma_alloc 737ee8adcfSJonathan Corbet 747ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 75ea83df73SJonathan Corbet :functions: gen_pool_free_owner 767ee8adcfSJonathan Corbet 77*f11b46f3SJonathan CorbetAs one would expect, gen_pool_alloc() will allocate size< bytes 78*f11b46f3SJonathan Corbetfrom the given pool. The gen_pool_dma_alloc() variant allocates 797ee8adcfSJonathan Corbetmemory for use with DMA operations, returning the associated physical 807ee8adcfSJonathan Corbetaddress in the space pointed to by dma. This will only work if the memory 81*f11b46f3SJonathan Corbetwas added with gen_pool_add_virt(). Note that this function 827ee8adcfSJonathan Corbetdeparts from the usual genpool pattern of using unsigned long values to 837ee8adcfSJonathan Corbetrepresent kernel addresses; it returns a void * instead. 847ee8adcfSJonathan Corbet 857ee8adcfSJonathan CorbetThat all seems relatively simple; indeed, some developers clearly found it 867ee8adcfSJonathan Corbetto be too simple. After all, the interface above provides no control over 877ee8adcfSJonathan Corbethow the allocation functions choose which specific piece of memory to 887ee8adcfSJonathan Corbetreturn. If that sort of control is needed, the following functions will be 897ee8adcfSJonathan Corbetof interest: 907ee8adcfSJonathan Corbet 917ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 92ea83df73SJonathan Corbet :functions: gen_pool_alloc_algo_owner 937ee8adcfSJonathan Corbet 947ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 957ee8adcfSJonathan Corbet :functions: gen_pool_set_algo 967ee8adcfSJonathan Corbet 97*f11b46f3SJonathan CorbetAllocations with gen_pool_alloc_algo() specify an algorithm to be 987ee8adcfSJonathan Corbetused to choose the memory to be allocated; the default algorithm can be set 99*f11b46f3SJonathan Corbetwith gen_pool_set_algo(). The data value is passed to the 1007ee8adcfSJonathan Corbetalgorithm; most ignore it, but it is occasionally needed. One can, 1017ee8adcfSJonathan Corbetnaturally, write a special-purpose algorithm, but there is a fair set 1027ee8adcfSJonathan Corbetalready available: 1037ee8adcfSJonathan Corbet 1047ee8adcfSJonathan Corbet- gen_pool_first_fit is a simple first-fit allocator; this is the default 1057ee8adcfSJonathan Corbet algorithm if none other has been specified. 1067ee8adcfSJonathan Corbet 1077ee8adcfSJonathan Corbet- gen_pool_first_fit_align forces the allocation to have a specific 1087ee8adcfSJonathan Corbet alignment (passed via data in a genpool_data_align structure). 1097ee8adcfSJonathan Corbet 1107ee8adcfSJonathan Corbet- gen_pool_first_fit_order_align aligns the allocation to the order of the 1117ee8adcfSJonathan Corbet size. A 60-byte allocation will thus be 64-byte aligned, for example. 1127ee8adcfSJonathan Corbet 1137ee8adcfSJonathan Corbet- gen_pool_best_fit, as one would expect, is a simple best-fit allocator. 1147ee8adcfSJonathan Corbet 1157ee8adcfSJonathan Corbet- gen_pool_fixed_alloc allocates at a specific offset (passed in a 1167ee8adcfSJonathan Corbet genpool_data_fixed structure via the data parameter) within the pool. 1177ee8adcfSJonathan Corbet If the indicated memory is not available the allocation fails. 1187ee8adcfSJonathan Corbet 1197ee8adcfSJonathan CorbetThere is a handful of other functions, mostly for purposes like querying 1207ee8adcfSJonathan Corbetthe space available in the pool or iterating through chunks of memory. 1217ee8adcfSJonathan CorbetMost users, however, should not need much beyond what has been described 1227ee8adcfSJonathan Corbetabove. With luck, wider awareness of this module will help to prevent the 1237ee8adcfSJonathan Corbetwriting of special-purpose memory allocators in the future. 1247ee8adcfSJonathan Corbet 1257ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 1267ee8adcfSJonathan Corbet :functions: gen_pool_virt_to_phys 1277ee8adcfSJonathan Corbet 1287ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 1297ee8adcfSJonathan Corbet :functions: gen_pool_for_each_chunk 1307ee8adcfSJonathan Corbet 1317ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 1327ee8adcfSJonathan Corbet :functions: addr_in_gen_pool 1337ee8adcfSJonathan Corbet 1347ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 1357ee8adcfSJonathan Corbet :functions: gen_pool_avail 1367ee8adcfSJonathan Corbet 1377ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 1387ee8adcfSJonathan Corbet :functions: gen_pool_size 1397ee8adcfSJonathan Corbet 1407ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 1417ee8adcfSJonathan Corbet :functions: gen_pool_get 1427ee8adcfSJonathan Corbet 1437ee8adcfSJonathan Corbet.. kernel-doc:: lib/genalloc.c 1447ee8adcfSJonathan Corbet :functions: of_gen_pool_get 145