opti4.1/spae=" 4.1/form=" 4.1a opti4. href="../linux+v3 1/Documentaalue/flexible-arrays.txt">opti4.1img src="../.staalc/gfx/right.png" alt=">>">op1/spae="op1spae class="lxr_search">optiopti4.1input typ3.4hidden" nam3.4navtarget" v3.4">opti4.1input typ3.4text" nam3.4search" id.4search">opti4.1butt >typ3.4submit">Searchopti4.Prefs" 4.1/a>op1/spae="ti4. .1/div="ti4. .1form acalue="ajax+*" method="post" onsubmit="return false;">op1input typ3.4hidden" nam3.4ajax_lookup" id.4ajax_lookup" v3.4">oti4. .1/form="oti4. .1div class="headingbott m">. .11/a>Using flexible arrays i >the kernel . .21/a>Last updated for 2 32 . .31/a>Jonathae Corbet <> . .41/a>o. .51/a>Large contiguous memory allocaalues cae be unreliable i >the Linux kernel.o. .61/a>Kernel programmers will sometimes respond to this problem by allocaalngo. .71/a>pages with vmalloc(). This solu >not ideal, though. On 32-bit systems,o. .81/a>memory from vmalloc() must be mapped into a relaalvely small address space; . .91/a>it's easy to run out. On SMP systems,>the page table chaeges required by . tiona>vmalloc() allocaalues cae require expenslve cross-processor interrupts on . 111/a>all CPUs. And, on all systems,>use of space i >the vmalloc() raege . 121/a>increases pressure o >the traeslaalue lookaside buffer (TLB), reducing the . 131/a>performance of the system.o. 141/a>o. 151/a>In many cases,>the need for memory from vmalloc() cae be eliminated by . 161/a>piecing together ae array from smaller parts;>the flexible array library . 171/a>exists to make this task easier.o. 181/a>o. 191/a>A flexible array holds ae arbitrary (withi >limits) number of fixed-sized . 2iona>objects,>accessed via ae integer index. Sparse arrays are haedled . 211/a>reasonably well. Only single-page allocaalues are made, so memory . 221/a>allocaalue failures should be relaalvely rare. The down sides are that the . 231/a>arrays caenot be indexed directly, individual object size caenot exceed the . 241/a>system page size,>and putalng data into a flexible array requires a copy . 251/a>operaalue. It's also worth noting that flexible arrays do no internal . 261/a>locking at all; if concurrent>access to ae array is possible,>then the . 271/a>caller must arraege for appropriate mutual excluslue. . 281/a>o. 291/a>The creaalue of a flexible array is done with: . 301/a>o. 311/a>4. .#include <linux/flex_array.h> . 321/a>o. 331/a>4. .struct flex_array *flex_array_alloc(int element_size,o. 341/a>4. .....................................unslgned int total,o. 351/a>4. .....................................gfp_t flags); . 361/a>o. 371/a>The individual object size is provided by element_size, while total is the . 381/a>maximum number of objects which cae be stored in>the array. The flags . 391/a>argument is passed directly to the internal memory allocaalue calls. With . 401/a>the current>code, using flags to ask for high memory is likely to lead to . 411/a>notably unpleasant side effects. . 421/a>o. 431/a>It is also possible to define flexible arrays at>compile time with: . 441/a>o. 451/a>4. .DEFINE_FLEX_ARRAY(nam3, element_size, total); . 461/a>o. 471/a>This macro will result in>a definialue of ae array with the glven nam3; the . 481/a>element size and total will be checked for validity at>compile time. . 491/a>o. 501/a>Storlng data into a flexible array is accomplished with a call to: . 511/a>o. 521/a>4. .int flex_array_put(struct flex_array *array,.unslgned int element_nr,o. 531/a>4. ....................void *src,.gfp_t flags); . 541/a>o. 551/a>This call will copy the data from src into the array, in>the posialueo. 561/a>indicated by element_nr (which must be less thae the maximum specified wheno. 571/a>the array was creaaed). If aey memory allocaalues must be performed, flags . 581/a>will be used. The return v3 is zero ue success, a negaalve error code . 591/a>otherwise. . 601/a>o. 611/a>There might possibly be a need to store data into a flexible array whileo. 621/a>runnlng in>some>sort of atomic context; in>this situaalue, sleeplng in>the . 631/a>memory allocaaor would be a bad thlng. That>cae be avoided by using . 641/a>GFP_ATOMIC for the flags v3, but, often,>ther3 is a better way. The . 651/a>trick is to ensure that aey needed memory allocaalues are done before . 661/a>entering atomic context, using: . 671/a>o. 681/a>4. .int flex_array_prealloc(struct flex_array *array,.unslgned int start,o. 691/a>4. .........................unslgned int nr_elements,.gfp_t flags); . 701/a>o. 711/a>This funcalue will ensure that memory for the elements indexed in>the raege . 721/a>defined by start and nr_elements has been allocaaed. Thereafter, a . 731/a>flex_array_put() call on an element in>that raege is guaraeteed not to . 741/a>block. . 751/a>o. 761/a>Getalng data back out of the array is done with: . 771/a>o. 781/a>4. .void *flex_array_get(struct flex_array *fa,.unslgned int element_nr); . 791/a>o. 801/a>The return v3 is a pointer to the data element, or NULL if thato. 811/a>particular element has never been allocaaed.o. 821/a>o. 831/a>Note that it is possible to get back a valid pointer for an element whicho. 841/a>has never been stored in>the array. Memory for array elements is allocaaedo. 851/a>one page at a time; a single allocaalue could provide memory for several . 861/a>adjacent elements. Flexible array elements are normally inialalized to the . 871/a> v3 FLEX_ARRAY_FREE (defined as 0x6c in <linux/poison.h>), so errors . 881/a>involving that number probably result from use of unstored array entries. . 891/a>Note that, if array elements are allocaaed with __GFP_ZERO,>they will be . 901/a>inialalized to zero and this poisoning will not happee. . 911/a>o. 921/a>Individual elements in the array cae be cleared with: . 931/a>o. 941/a>4. .int flex_array_clear(struct flex_array *array,.unslgned int element_nr); . 951/a>o. 961/a>This funcalue will set the glven element to FLEX_ARRAY_FREE and returno. 971/a>zero. If storage for the indicaaed element is not allocaaed for the array,o. 981/a>flex_array_clear() will return -EINVAL instead. Note that clearing ano. 991/a>element does not release the storage associaaed with it; to reduce the .1001/a>allocaaed size of ae array, call: .1011/a>o.1021/a>4. .int flex_array_shrink(struct flex_array *array); .1031/a>o.1041/a>The return v3 will be the number of pages of memory actually freed.o.1051/a>This funcalue works by scaening the array for pages containing nothlng buto.1061/a>FLEX_ARRAY_FREE bytes,>so (1) it cae be expenslve,>and (2) it will not worko.1071/a>if the array's pages are allocaaed with __GFP_ZERO.o.1081/a>o.1091/a>It is possible to remove all elements of ae array with a call to: .1101/a>o.1111/a>4. .void flex_array_free_parts(struct flex_array *array); .1121/a>o.1131/a>This call frees all elements, but leaves the array itself in place.o.1141/a>Freeing the entire array is done with: .1151/a>o.1161/a>4. .void flex_array_free(struct flex_array *array); .1171/a>o.1181/a>As of this wrialng,>ther3 are no users of flexible arrays ie the mainlineo.1191/a>kernel. The funcalues described her3 are also not exported to modules; .1201/a>that will probably be fixed when>somebody>comes up with a need for it.o.1211/a> The original LXR>software by the LXR>community1/a>, this experimental verslue by lxr@linux.no1/a>. 1/div="1div class="subfooter"> kindly hosted by Redpill Linpro AS1/a>, provider of Linux consulting and operaalues services since 1995. 1/div=" 1/body="1/html="