Commit 4af5a2f7 authored by David Rientjes's avatar David Rientjes Committed by Linus Torvalds

flex_array: add flex_array_shrink function

Add a new function to the flex_array API:

	int flex_array_shrink(struct flex_array *fa)

This function will free all unused second-level pages.  Since elements are
now poisoned if they are not allocated with __GFP_ZERO, it's possible to
identify parts that consist solely of unused elements.

flex_array_shrink() returns the number of pages freed.
Signed-off-by: default avatarDavid Rientjes <>
Cc: Dave Hansen <>
Signed-off-by: default avatarAndrew Morton <>
Signed-off-by: default avatarLinus Torvalds <>
parent 19da3dd1
......@@ -46,5 +46,6 @@ int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src,
gfp_t flags);
int flex_array_clear(struct flex_array *fa, unsigned int element_nr);
void *flex_array_get(struct flex_array *fa, unsigned int element_nr);
int flex_array_shrink(struct flex_array *fa);
#endif /* _FLEX_ARRAY_H */
......@@ -291,3 +291,43 @@ void *flex_array_get(struct flex_array *fa, unsigned int element_nr)
return &part->elements[index_inside_part(fa, element_nr)];
static int part_is_free(struct flex_array_part *part)
int i;
for (i = 0; i < sizeof(struct flex_array_part); i++)
if (part->elements[i] != FLEX_ARRAY_FREE)
return 0;
return 1;
* flex_array_shrink - free unused second-level pages
* Frees all second-level pages that consist solely of unused
* elements. Returns the number of pages freed.
* Locking must be provided by the caller.
int flex_array_shrink(struct flex_array *fa)
struct flex_array_part *part;
int max_part = nr_base_part_ptrs();
int part_nr;
int ret = 0;
if (elements_fit_in_base(fa))
return ret;
for (part_nr = 0; part_nr < max_part; part_nr++) {
part = fa->parts[part_nr];
if (!part)
if (part_is_free(part)) {
fa->parts[part_nr] = NULL;
return ret;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment