lkml.org 
[lkml]   [2009]   [Aug]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 4/4 -mm] flex_array: add flex_array_shrink function
    This patch adds 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.

    Cc: Dave Hansen <dave@linux.vnet.ibm.com>
    Signed-off-by: David Rientjes <rientjes@google.com>
    ---
    include/linux/flex_array.h | 1 +
    lib/flex_array.c | 40 ++++++++++++++++++++++++++++++++++++++++
    2 files changed, 41 insertions(+), 0 deletions(-)
    diff --git a/include/linux/flex_array.h b/include/linux/flex_array.h
    --- a/include/linux/flex_array.h
    +++ b/include/linux/flex_array.h
    @@ -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 */
    diff --git a/lib/flex_array.c b/lib/flex_array.c
    --- a/lib/flex_array.c
    +++ b/lib/flex_array.c
    @@ -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)
    + continue;
    + if (part_is_free(part)) {
    + fa->parts[part_nr] = NULL;
    + kfree(part);
    + ret++;
    + }
    + }
    + return ret;
    +}

    \
     
     \ /
      Last update: 2009-08-22 01:25    [from the cache]
    ©2003-2014 Jasper Spaans. Advertise on this site