[ovs-dev] [PATCH 1/3] [bug 2462] flex-array: Flex arrays-cleanup.

Pravin B Shelar pshelar at nicira.com
Thu Feb 2 14:58:11 UTC 2012


cleanups:
        - removes flex_array_shrink() as there is no caller.
        - add flex_array_init()
        - Add few 'const's.

Signed-off-by: Pravin B Shelar <pshelar at nicira.com>
---
 datapath/linux/compat/flex_array.c               |  114 ++++++++--------------
 datapath/linux/compat/include/linux/flex_array.h |   20 ++--
 2 files changed, 52 insertions(+), 82 deletions(-)

diff --git a/datapath/linux/compat/flex_array.c b/datapath/linux/compat/flex_array.c
index 1e6d9c1..f2d0cd2 100644
--- a/datapath/linux/compat/flex_array.c
+++ b/datapath/linux/compat/flex_array.c
@@ -1,7 +1,5 @@
 #include <linux/version.h>
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
-
 /*
  * Flexible array managed in PAGE_SIZE parts
  *
@@ -40,7 +38,7 @@ struct flex_array_part {
  * flex_array->parts[] array to store the user
  * data.
  */
-static inline int elements_fit_in_base(struct flex_array *fa)
+static inline int elements_fit_in_base(const struct flex_array *fa)
 {
 	int data_size = fa->element_size * fa->total_nr_elements;
 	if (data_size <= FLEX_ARRAY_BASE_BYTES_LEFT)
@@ -49,7 +47,8 @@ static inline int elements_fit_in_base(struct flex_array *fa)
 }
 
 /**
- * flex_array_alloc - allocate a new flexible array
+ * flex_array_init - initialize a new flexible array
+ * @array:		flex array to initiaize
  * @element_size:	the size of individual elements in the array
  * @total:		total number of elements that this should hold
  * @flags:		page allocation flags to use for base array
@@ -89,10 +88,9 @@ static inline int elements_fit_in_base(struct flex_array *fa)
  * capacity in the base structure.  Also note that no effort is made
  * to efficiently pack objects across page boundaries.
  */
-struct flex_array *flex_array_alloc(int element_size, unsigned int total,
-					gfp_t flags)
+int flex_array_init(struct flex_array *array, int element_size,
+		    unsigned int total, gfp_t flags)
 {
-	struct flex_array *ret;
 	int elems_per_part = 0;
 	int reciprocal_elems = 0;
 	int max_size = 0;
@@ -105,22 +103,38 @@ struct flex_array *flex_array_alloc(int element_size, unsigned int total,
 
 	/* max_size will end up 0 if element_size > PAGE_SIZE */
 	if (total > max_size)
-		return NULL;
+		return -EINVAL;
+
+	array->element_size = element_size;
+	array->total_nr_elements = total;
+	array->elems_per_part = elems_per_part;
+	array->reciprocal_elems = reciprocal_elems;
+	if (elements_fit_in_base(array) && !(flags & __GFP_ZERO))
+		memset(&array->parts[0], 0, FLEX_ARRAY_BASE_BYTES_LEFT);
+
+	return 0;
+}
+
+struct flex_array *flex_array_alloc(int element_size, unsigned int total,
+				    gfp_t flags)
+{
+	struct flex_array *ret;
+	int err;
+
 	ret = kzalloc(sizeof(struct flex_array), flags);
 	if (!ret)
 		return NULL;
-	ret->element_size = element_size;
-	ret->total_nr_elements = total;
-	ret->elems_per_part = elems_per_part;
-	ret->reciprocal_elems = reciprocal_elems;
-	if (elements_fit_in_base(ret) && !(flags & __GFP_ZERO))
-		memset(&ret->parts[0], FLEX_ARRAY_FREE,
-						FLEX_ARRAY_BASE_BYTES_LEFT);
+
+	err = flex_array_init(ret, element_size, total, flags);
+	if (err) {
+		kfree(ret);
+		ret = NULL;
+	}
 	return ret;
 }
 
-static int fa_element_to_part_nr(struct flex_array *fa,
-					unsigned int element_nr)
+static int fa_element_to_part_nr(const struct flex_array *fa,
+				 unsigned int element_nr)
 {
 	return reciprocal_divide(element_nr, fa->reciprocal_elems);
 }
@@ -132,7 +146,7 @@ static int fa_element_to_part_nr(struct flex_array *fa,
  * This is to be used in cases where the base 'struct flex_array'
  * has been statically allocated and should not be free.
  */
-void flex_array_free_parts(struct flex_array *fa)
+void flex_array_free_parts(const struct flex_array *fa)
 {
 	int part_nr;
 
@@ -142,15 +156,15 @@ void flex_array_free_parts(struct flex_array *fa)
 		kfree(fa->parts[part_nr]);
 }
 
-void flex_array_free(struct flex_array *fa)
+void flex_array_free(const struct flex_array *fa)
 {
 	flex_array_free_parts(fa);
 	kfree(fa);
 }
 
-static unsigned int index_inside_part(struct flex_array *fa,
-					unsigned int element_nr,
-					unsigned int part_nr)
+static unsigned int index_inside_part(const struct flex_array *fa,
+				      unsigned int element_nr,
+				      unsigned int part_nr)
 {
 	unsigned int part_offset;
 
@@ -167,8 +181,8 @@ __fa_get_part(struct flex_array *fa, int part_nr, gfp_t flags)
 		if (!part)
 			return NULL;
 		if (!(flags & __GFP_ZERO))
-			memset(part, FLEX_ARRAY_FREE,
-				sizeof(struct flex_array_part));
+			memset(part, 0, sizeof(struct flex_array_part));
+
 		fa->parts[part_nr] = part;
 	}
 	return part;
@@ -192,7 +206,7 @@ __fa_get_part(struct flex_array *fa, int part_nr, gfp_t flags)
  * Locking must be provided by the caller.
  */
 int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src,
-			gfp_t flags)
+		   gfp_t flags)
 {
 	int part_nr = 0;
 	struct flex_array_part *part;
@@ -241,7 +255,7 @@ int flex_array_clear(struct flex_array *fa, unsigned int element_nr)
 			return -EINVAL;
 	}
 	dst = &part->elements[index_inside_part(fa, element_nr, part_nr)];
-	memset(dst, FLEX_ARRAY_FREE, fa->element_size);
+	memset(dst, 0, fa->element_size);
 	return 0;
 }
 
@@ -306,7 +320,7 @@ int flex_array_prealloc(struct flex_array *fa, unsigned int start,
  *
  * Locking must be provided by the caller.
  */
-void *flex_array_get(struct flex_array *fa, unsigned int element_nr)
+void *flex_array_get(const struct flex_array *fa, unsigned int element_nr)
 {
 	int part_nr = 0;
 	struct flex_array_part *part;
@@ -335,7 +349,7 @@ void *flex_array_get(struct flex_array *fa, unsigned int element_nr)
  * flex_array_put_ptr().  This function should not be called if the
  * element in question was not set using the _put_ptr() helper.
  */
-void *flex_array_get_ptr(struct flex_array *fa, unsigned int element_nr)
+void *flex_array_get_ptr(const struct flex_array *fa, unsigned int element_nr)
 {
 	void **tmp;
 
@@ -345,47 +359,3 @@ void *flex_array_get_ptr(struct flex_array *fa, unsigned int element_nr)
 
 	return *tmp;
 }
-
-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
- * @fa:		the flex array to shrink
- *
- * 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 part_nr;
-	int ret = 0;
-
-	if (!fa->total_nr_elements || !fa->element_size)
-		return 0;
-	if (elements_fit_in_base(fa))
-		return ret;
-	for (part_nr = 0; part_nr < FLEX_ARRAY_NR_BASE_PTRS; 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;
-}
-
-#endif /* Linux version < 3.0.0 */
diff --git a/datapath/linux/compat/include/linux/flex_array.h b/datapath/linux/compat/include/linux/flex_array.h
index 1cc6648..6fdaef7 100644
--- a/datapath/linux/compat/include/linux/flex_array.h
+++ b/datapath/linux/compat/include/linux/flex_array.h
@@ -2,10 +2,6 @@
 #define __LINUX_FLEX_ARRAY_WRAPPER_H
 
 #include <linux/version.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
-#include_next <linux/flex_array.h>
-#else
-
 #include <linux/types.h>
 #include <asm/page.h>
 
@@ -67,20 +63,24 @@ struct flex_array {
 
 struct flex_array *flex_array_alloc(int element_size, unsigned int total,
 		gfp_t flags);
+int flex_array_init(struct flex_array *array, int element_size,
+		    unsigned int total, gfp_t flags);
 int flex_array_prealloc(struct flex_array *fa, unsigned int start,
 		unsigned int nr_elements, gfp_t flags);
-void flex_array_free(struct flex_array *fa);
-void flex_array_free_parts(struct flex_array *fa);
+#define flex_array_free rpl_flex_array_free
+void flex_array_free(const struct flex_array *fa);
+#define flex_array_free_parts rpl_flex_array_free_parts
+void flex_array_free_parts(const struct flex_array *fa);
 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);
+#define flex_array_get rpl_flex_array_get
+void *flex_array_get(const struct flex_array *fa, unsigned int element_nr);
 
 #define flex_array_put_ptr(fa, nr, src, gfp) \
 	flex_array_put(fa, nr, (void *)&(src), gfp)
 
-void *flex_array_get_ptr(struct flex_array *fa, unsigned int element_nr);
+#define flex_array_get_ptr rpl_flex_array_get_ptr
+void *flex_array_get_ptr(const struct flex_array *fa, unsigned int element_nr);
 
-#endif /* Linux version < 3.0.0 */
 #endif /* __LINUX_FLEX_ARRAY_WRAPPER_H */
-- 
1.7.1




More information about the dev mailing list