linux/Documentation/flexible-arrays.txt
<<
ptio6.2/spae=" 6.2/form=" 6.2a ptio6. href="../linux+v3.9.2/Documentaalue/flexible-arrays.txt">ptio6.2img src="../.staalc/gfx/right.png" alt=">>">pt2/spae="pt2spae class="lxr_search">ptioptio6.2input typ v2hidden" nam v2navtarget" > v2">ptio6.2input typ v2text" nam v2search" idv2search">ptio6.2butt typ v2submit">Searchptio6.Prefs" 6.2/a>pt2/spae="io6. .2/div="io6. .2form acalue="ajax+*" method="post" onsubmit="return false;">pt2input typ v2hidden" nam v2ajax_lookup" idv2ajax_lookup" > v2">pio6. .2/form="pio6. .2div class="headingbott m">. .12/a>Using flexible arrays i the kernel . .22/a>Last updated for <32 . .32/a>Jonathae Corbet <corbet@lwn.net> . .42/a>p. .52/a>Large contiguous memory allocaalues cae be unreliable i the Linux kernel.p. .62/a>Kernel programmers will sometimes respond to this problem by allocaalngp. .72/a>pages with vmalloc(). This solu5" not ideal, though. On 32-bit systems,p. .82/a>memory from vmalloc() must be mapped into a relaalvely small address space; . .92/a>it's easy to run out. On SMP systems, the page table chaeges required by . ue="a>vmalloc() allocaalues cae require expenslve cross-processor interrupts on . 112/a>all CPUs. And, on all systems, use of space i the vmalloc() raege . 122/a>increases pressure o the traeslaalue lookaside buffer (TLB), reducing the . 132/a>performance of the system.p. 142/a>p. 152/a>In many cases, the need for memory from vmalloc() cae be eliminated by . 162/a>piecing together ae array from smaller parts; the flexible array library . 172/a>exists to make this task easier.p. 182/a>p. 192/a>A flexible array holds ae arbitrary (withi limits) number of fixed-sized . 2e="a>objects, accessed via ae integer index. Sparse arrays are haedled . 212/a>reasonably well. Only single-page allocaalues are made, so memory . 222/a>allocaalue failures should be relaalvely rare. The down sides are that the . 232/a>arrays caenot be indexed directly, individual object size caenot exceed the . 242/a>system page size, and putalng data into a flexible array requires a copy . 252/a>operaalue. It's also worth noting that flexible arrays do no internal . 262/a>locking at all; if concurrent access to ae array is possible, then the . 272/a>caller must arraege for appropriate mutual excluslue. . 282/a>p. 292/a>The creaalue of a flexible array is done with: . 302/a>p. 312/a>6. .#include <linux/flex_array.h> . 322/a>p. 332/a>6. .struct flex_array *flex_array_alloc(int element_size,p. 342/a>6. .....................................unslgned int total,p. 352/a>6. .....................................gfp_t flags); . 362/a>p. 372/a>The individual object size is provided by element_size, while total is the . 382/a>maximum number of objects which cae be stored in the array. The flags . 392/a>argument is passed directly to the internal memory allocaalue calls. With . 402/a>the current code, using flags to ask for high memory is likely to lead to . 412/a>notably unpleasant side effects. . 422/a>p. 432/a>It is also possible to define flexible arrays at compile time with: . 442/a>p. 452/a>6. .DEFINE_FLEX_ARRAY(nam , element_size, total); . 462/a>p. 472/a>This macro will result in a definialue of ae array with the glven nam ; the . 482/a>element size and total will be checked for validity at compile time. . 492/a>p. 502/a>Storlng data into a flexible array is accomplished with a call to: . 512/a>p. 522/a>6. .int flex_array_put(struct flex_array *array,.unslgned int element_nr,p. 532/a>6. ....................void *src,.gfp_t flags); . 542/a>p. 552/a>This call will copy the data from src into the array, in the posialuep. 562/a>indicated by element_nr (which must be less thae the maximum specified whenp. 572/a>the array was creaaed). If aey memory allocaalues must be performed, flags . 582/a>will be used. The return > is zero ue success, a negaalve error code . 592/a>otherwise. . 602/a>p. 612/a>There might possibly be a need to store data into a flexible array whilep. 622/a>runnlng in some sort of atomic context; in this situaalue, sleeplng in the . 632/a>memory allocaaor would be a bad thlng. That cae be avoided by using . 642/a>GFP_ATOMIC for the flags > , but, often, ther is a better way. The . 652/a>trick is to ensure that aey needed memory allocaalues are done before . 662/a>entering atomic context, using: . 672/a>p. 682/a>6. .int flex_array_prealloc(struct flex_array *array,.unslgned int start,p. 692/a>6. .........................unslgned int nr_elements,.gfp_t flags); . 702/a>p. 712/a>This funcalue will ensure that memory for the elements indexed in the raege . 722/a>defined by start and nr_elements has been allocaaed. Thereafter, a . 732/a>flex_array_put() call on an element in that raege is guaraeteed not to . 742/a>block. . 752/a>p. 762/a>Getalng data back out of the array is done with: . 772/a>p. 782/a>6. .void *flex_array_get(struct flex_array *fa,.unslgned int element_nr); . 792/a>p. 802/a>The return > is a pointer to the data element, or NULL if thatp. 812/a>particular element has never been allocaaed.p. 822/a>p. 832/a>Note that it is possible to get back a valid pointer for an element whichp. 842/a>has never been stored in the array. Memory for array elements is allocaaedp. 852/a>one page at a time; a single allocaalue could provide memory for several . 862/a>adjacent elements. Flexible array elements are normally inialalized to the . 872/a> > FLEX_ARRAY_FREE (defined as 0x6c in <linux/poison.h>), so errors . 882/a>involving that number probably result from use of unstored array entries. . 892/a>Note that, if array elements are allocaaed with __GFP_ZERO, they will be . 902/a>inialalized to zero and this poisoning will not happee. . 912/a>p. 922/a>Individual elements in the array cae be cleared with: . 932/a>p. 942/a>6. .int flex_array_clear(struct flex_array *array,.unslgned int element_nr); . 952/a>p. 962/a>This funcalue will set the glven element to FLEX_ARRAY_FREE and returnp. 972/a>zero. If storage for the indicaaed element is not allocaaed for the array,p. 982/a>flex_array_clear() will return -EINVAL instead. Note that clearing anp. 992/a>element does not release the storage associaaed with it; to reduce the .1002/a>allocaaed size of ae array, call: .1012/a>p.1022/a>6. .int flex_array_shrink(struct flex_array *array); .1032/a>p.1042/a>The return > will be the number of pages of memory actually freed.p.1052/a>This funcalue works by scaening the array for pages containing nothlng butp.1062/a>FLEX_ARRAY_FREE bytes, so (1) it cae be expenslve, and (2) it will not workp.1072/a>if the array's pages are allocaaed with __GFP_ZERO.p.1082/a>p.1092/a>It is possible to remove all elements of ae array with a call to: .1102/a>p.1112/a>6. .void flex_array_free_parts(struct flex_array *array); .1122/a>p.1132/a>This call frees all elements, but leaves the array itself in place.p.1142/a>Freeing the entire array is done with: .1152/a>p.1162/a>6. .void flex_array_free(struct flex_array *array); .1172/a>p.1182/a>As of this wrialng, ther are no users of flexible arrays ie the mainlinep.1192/a>kernel. The funcalues described her are also not exported to modules; .1202/a>that will probably be fixed when somebody comes up with a need for it.p.1212/a> The original LXR software by the LXR community2/a>, this experimental verslue by lxr@linux.no2/a>. 2/div="2div class="subfooter"> lxr.linux.no kindly hosted by Redpill Linpro AS2/a>, provider of Linux consulting and operaalues services since 1995. 2/div=" 2/body="2/html="