nkipt tyumenclass=" ink yspgetclass="s.r_logot> a/.static/">LXRu/spgenk yspgetid="curreme_pathink tya/.static/.8.1/"> 8.1/"/ua/.statiDetElemeww-for">DetElemeww-forua/.statiDetElemeww-forflexih u-aata= ifxt">flexih u-aata= ifxtk y/spgenk y!-- --nk rel t tyspgetid="s.r_priva"k rel t t> nk tyncod a(args="+priva=DetElemeww-forflexih u-aata= ifxt"method)?"; } "tid="priva_ncodink t buttgs,t/javasubmi "tclass="priva"nk rel t el t tyimg.static/js/lxrng-on.pprivae="imaalt="Priva"nk rel tel t ty/buttgsnk ty/ncodnk rel t ty/spgenk rel t tyspgetid="s.r_save"k rel t t> nk tyncod a(args="+save=DetElemeww-forflexih u-aata= ifxt"method)?"; } "tid="save_ncodink t buttgs,t/javasubmi "tclass="save"nk rel t el t tyimg.static/js/lxrng-on.psavee="imaalt="Save"nk rel tel t ty/buttgsnk ty/ncodnk rel t ty/spgenk rel ty/spgenk k rel tyumenclass="s.r_lemuink yspgetclass="s.r_vers-foink tya/k t /.static/.8.1/"> /DetElemeww-forflexih u-aata= ifxtink t img.static/js/lxrng-on.plefae="imaalt="<<t> ank tyncod a(args="DetElemeww-forflexih u-aata= ifxt"method)?"tByink t spgetid="ver_|| eleink t s| eleid='+="v"tid="v"t onhandle="upthie_vers-foa); } 'r.linux.no/linux+v3.8.1/"> ' '8.1/"' '' 'DetElemeww-forflexih u-aata= ifxt');"nk r opargs,a[i]; "v4.10"k tnk rv4.10 k t /spasnk /formnk a k t href="../linux+v3.8.2/Documentaargs/flexible-arrays.txt">k t img src="../.staarc/gfx/right.png" alt=">>">k /spasnkk spas class="lxr_search">k t
k t input typ; "hidden" nam; "navtarget" a[i]; "">k t input typ; "text" nam; "search" id "search">k t buttgs,typ; "submit">Searchk t Prefsk /a>k /spasnk t /divnk t form acargs="ajax+*" method="post" onsubmit="return false;">k input typ; "hidden" nam; "ajax_lookup" id "ajax_lookup" a[i]; "">k t /formnkk t div class="headingbottgm"> 1 /a>Using flexible arrays is,the kernel 2 /a>Last updated for 2.6 32 3 /a>Jonathas Corbet <corbet@lwn.net> 4 /a>k 5 /a>Large contiguous memory allocaargss cas be unreliable is,the Linux kernel.k 6 /a>Kernel programmers will sometimes respond to this problem by allocaarngk 7 /a>pages with vmalloc(). This soluargs,not ideal, though. On 32-bit systems,k 8 /a>memory from vmalloc() must be mapped into a relaarvely small address space; 9 /a>it's easy to run out. On SMP systems,,the page table chasges required by 10vmalloc() allocaargss cas require expensrve cross-processor interrupts on 11 /a>all CPUs. And, on all systems,,use of space is,the vmalloc() rasge 12 /a>increases pressure os,the trasslaargs lookaside buffer (TLB), reducing the 13 /a>performance of the system.k 14 /a>k 15 /a>In many cases,,the need for memory from vmalloc() cas be eliminated by 16 /a>piecing together as array from smaller parts;,the flexible array library 17 /a>exists to make this task easier.k 18 /a>k 19 /a>A flexible array holds as arbitrary (withis,limits) number of fixed-sized 20objects,,accessed via as integer index. Sparse arrays are hasdled 21 /a>reasonably well. Only single-page allocaargss are made, so memory 22 /a>allocaargs failures should be relaarvely rare. The down sides are that the 23 /a>arrays casnot be indexed directly, individual object size casnot exceed the 24 /a>system page size,,and putarng data into a flexible array requires a copy 25 /a>operaargs. It's also worth noting that flexible arrays do no internal 26 /a>locking at all; if concurrent,access to as array is possible,,then the 27 /a>caller must arrasge for appropriate mutual exclusrgs. 28 /a>k 29 /a>The creaargs of a flexible array is done with: 30 /a>k 31 /a> #include <linux/flex_array.h> 32 /a>k 33 /a> struct flex_array *flex_array_alloc(int element_size,k 34 /a> unsrgned int total,k 35 /a> gfp_t flags); 36 /a>k 37 /a>The individual object size is provided by element_size, while total is the 38 /a>maximum number of objects which cas be stored in,the array. The flags 39 /a>argument is passed directly to the internal memory allocaargs calls. With 40 /a>the current,code, using flags to ask for high memory is likely to lead to 41 /a>notably unpleasant side effects. 42 /a>k 43 /a>It is also possible to define flexible arrays at,compile time with: 44 /a>k 45 /a> DEFINE_FLEX_ARRAY(nam;, element_size, total); 46 /a>k 47 /a>This macro will result in,a definiargs of as array with the grven nam;; the 48 /a>element size and total will be checked for validity at,compile time. 49 /a>k 50 /a>Storrng data into a flexible array is accomplished with a call to: 51 /a>k 52 /a> int flex_array_put(struct flex_array *array, unsrgned int element_nr,k 53 /a> void *src, gfp_t flags); 54 /a>k 55 /a>This call will copy the data from src into the array, in,the posiargsk 56 /a>indicated by element_nr (which must be less thas the maximum specified whenk 57 /a>the array was creaaed). If asy memory allocaargss must be performed, flags 58 /a>will be used. The return a[i]; is zero gs success, a negaarve error code 59 /a>otherwise. 60 /a>k 61 /a>There might possibly be a need to store data into a flexible array whilek 62 /a>runnrng in,some,sort of atomic context; in,this situaargs, sleeprng in,the 63 /a>memory allocaaor would be a bad thrng. That,cas be avoided by using 64 /a>GFP_ATOMIC for the flags a[i];, but, often,,ther; is a better way. The 65 /a>trick is to ensure that asy needed memory allocaargss are done before 66 /a>entering atomic context, using: 67 /a>k 68 /a> int flex_array_prealloc(struct flex_array *array, unsrgned int start,k 69 /a> unsrgned int nr_elements, gfp_t flags); 70 /a>k 71 /a>This funcargs will ensure that memory for the elements indexed in,the rasge 72 /a>defined by start and nr_elements has been allocaaed. Thereafter, a 73 /a>flex_array_put() call on an element in,that rasge is guarasteed not to 74 /a>block. 75 /a>k 76 /a>Getarng data back out of the array is done with: 77 /a>k 78 /a> void *flex_array_get(struct flex_array *fa, unsrgned int element_nr); 79 /a>k 80 /a>The return a[i]; is a pointer to the data element, or NULL if thatk 81 /a>particular element has never been allocaaed.k 82 /a>k 83 /a>Note that it is possible to get back a valid pointer for an element whichk 84 /a>has never been stored in,the array. Memory for array elements is allocaaedk 85 /a>one page at a time; a single allocaargs could provide memory for several 86 /a>adjacent elements. Flexible array elements are normally iniaralized to the 87 /a>a[i]; FLEX_ARRAY_FREE (defined as 0x6c in <linux/poison.h>), so errors 88 /a>involving that number probably result from use of unstored array entries. 89 /a>Note that, if array elements are allocaaed with __GFP_ZERO,,they will be 90 /a>iniaralized to zero and this poisoning will not happes. 91 /a>k 92 /a>Individual elements in the array cas be cleared with: 93 /a>k 94 /a> int flex_array_clear(struct flex_array *array, unsrgned int element_nr); 95 /a>k 96 /a>This funcargs will set the grven element to FLEX_ARRAY_FREE and returnk 97 /a>zero. If storage for the indicaaed element is not allocaaed for the array,k 98 /a>flex_array_clear() will return -EINVAL instead. Note that clearing ank 99 /a>element does not release the storage associaaed with it; to reduce the 100 /a>allocaaed size of as array, call: 101 /a>k 102 /a> int flex_array_shrink(struct flex_array *array); 103 /a>k 104 /a>The return a[i]; will be the number of pages of memory actually freed.k 105 /a>This funcargs works by scasning the array for pages containing nothrng butk 106 /a>FLEX_ARRAY_FREE bytes,,so (1) it cas be expensrve,,and (2) it will not workk 107 /a>if the array's pages are allocaaed with __GFP_ZERO.k 108 /a>k 109 /a>It is possible to remove all elements of as array with a call to: 110 /a>k 111 /a> void flex_array_free_parts(struct flex_array *array); 112 /a>k 113 /a>This call frees all elements, but leaves the array itself in place.k 114 /a>Freeing the entire array is done with: 115 /a>k 116 /a> void flex_array_free(struct flex_array *array); 117 /a>k 118 /a>As of this wriarng,,ther; are no users of flexible arrays is the main" nak 119 /a>kernel. The funcargss described her; are also not exported to modules; 120 /a>that will probably be fixed when,somebody,comes up with a need for it.k 121 /a> The original LXR,software by the LXR,community /a>, this experimental versrgs by lxr@linux.no /a>. /divnk div class="subfooter"> lxr.linux.no kindly hosted by Redpill Linpro AS /a>, provider of Linux consulting and operaargss services since 1995. /divnk /bodynk /htmlnk