History

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.

David Rientjes committed 17 years ago

Commit 4af5a2f1 parent 19da3dd2 files · +41 −0Browse files

Unified · Split

2 files
  1. include/linux/flex_array.h +1 −0
  2. lib/flex_array.c +40 −0
include/linux/flex_array.h+1−0
@@ -46,5 +46,6 @@ int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src, · 45 unmodified lines
4646 gfp_t flags);
4747 int flex_array_clear(struct flex_array *fa, unsigned int element_nr);
4848 void *flex_array_get(struct flex_array *fa, unsigned int element_nr);
49+int flex_array_shrink(struct flex_array *fa);
4950
5051 #endif /* _FLEX_ARRAY_H */
lib/flex_array.c+40−0
@@ -291,3 +291,43 @@ void *flex_array_get(struct flex_array *fa, unsigned int element_nr) · 290 unmodified lines
291291 }
292292 return &part->elements[index_inside_part(fa, element_nr)];
293293 }
294+
295+static int part_is_free(struct flex_array_part *part)
296+{
297+ int i;
298+
299+ for (i = 0; i < sizeof(struct flex_array_part); i++)
300+ if (part->elements[i] != FLEX_ARRAY_FREE)
301+ return 0;
302+ return 1;
303+}
304+
305+/**
306+ * flex_array_shrink - free unused second-level pages
307+ *
308+ * Frees all second-level pages that consist solely of unused
309+ * elements. Returns the number of pages freed.
310+ *
311+ * Locking must be provided by the caller.
312+ */
313+int flex_array_shrink(struct flex_array *fa)
314+{
315+ struct flex_array_part *part;
316+ int max_part = nr_base_part_ptrs();
317+ int part_nr;
318+ int ret = 0;
319+
320+ if (elements_fit_in_base(fa))
321+ return ret;
322+ for (part_nr = 0; part_nr < max_part; part_nr++) {
323+ part = fa->parts[part_nr];
324+ if (!part)
325+ continue;
326+ if (part_is_free(part)) {
327+ fa->parts[part_nr] = NULL;
328+ kfree(part);
329+ ret++;
330+ }
331+ }
332+ return ret;
333+}