This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Pooled memory allocation for JFFS2


Another patch to JFFS2: Use a pool of struct jffs2_raw_node_ref
instead of dynamically allocating them using malloc(). Again, this
can save considerable amounts of RAM by avoiding the memory
overhead induced by malloc().

Note that this is a diff against current CVS and therefore contains
all the changes from my previous patch as well
(http://ecos.sourceware.org/ml/ecos-patches/2003-11/msg00039.html).

tk



diff -ru packages-orig/fs/jffs2/current/ChangeLog packages/fs/jffs2/current/ChangeLog
--- packages-orig/fs/jffs2/current/ChangeLog	2003-10-16 14:25:18.000000000 +0200
+++ packages/fs/jffs2/current/ChangeLog	2003-11-14 15:13:48.000000000 +0100
@@ -1,3 +1,17 @@
+2003-11-14  Thomas Koeller  <thomas.koeller@baslerweb.com>
+
+	* cdl/jffs2.cdl:
+	* src/nodelist.h:
+	* src/malloc-ecos.c:
+	* src/fs-ecos.c: Allocate jffs2_raw_node_ref structs
+	from pool.
+
+2003-11-12  Thomas Koeller  <thomas.koeller@baslerweb.com>
+
+	* cdl/jffs2.cdl:
+	* src/nodelist.h: Added CYGPKG_FS_JFFS2_COMPRESS to
+	disable compression.
+
 2003-10-14  Thomas Koeller  <thomas.koeller@baslerweb.com>
 
 	* src/os-ecos.h: Made definition of CONFIG_JFFS2_FS_DEBUG
diff -ru packages-orig/fs/jffs2/current/cdl/jffs2.cdl packages/fs/jffs2/current/cdl/jffs2.cdl
--- packages-orig/fs/jffs2/current/cdl/jffs2.cdl	2003-10-16 14:25:18.000000000 +0200
+++ packages/fs/jffs2/current/cdl/jffs2.cdl	2003-11-13 14:28:48.000000000 +0100
@@ -45,6 +45,7 @@
 # Author(s):      David Woodhouse, Dominic Ostrowski
 # Original data:  ported from JFFS2 by David Woodhouse
 # Contributors:   dominic.ostrowski@3glab.com
+#                 tkoeller <thomas.koeller@baslerweb.com>
 # Date:           2000-08-28
 #
 #####DESCRIPTIONEND####
@@ -75,6 +76,34 @@
     compile        -library=libextras.a fs-ecos.c
     compile        build.c scan.c malloc-ecos.c nodelist.c nodemgmt.c readinode.c erase.c dir-ecos.c write.c gc.c read.c compr.c compr_zlib.c compr_rtime.c compr_rubin.c file-ecos.c
 
+    cdl_option CYGPKG_FS_JFFS2_COMPRESS {
+        display         "Compress data"
+        flavor          bool
+        default_value   1
+        description     "
+            Use the ZLIB package and store data in compressed form.
+            Compression and decompression are entirely handled by the file
+            system and are fully transparent to applications. However,
+            selecting this option increases the amount of RAM required and
+            slows down read and write operations considerably if you have a
+            slow CPU."
+    }
+    
+    cdl_option CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE {
+        display         "Memory pool size"
+        flavor          data
+        default_value   0
+        description     "
+            In order to manage data stored in flash, the file system
+            needs to use data structures (jffs2_raw_node_ref) allocated
+            in RAM. You can specify here the maximum number of such
+            structures you expect to be used, which will then be allocated
+            statically. If this option is set to 0, the structures will
+            be allocated dynamically via malloc(), which may incur some
+            memory overhead depending on the particular malloc()
+            implementation used."
+    }
+
     cdl_option CYGPKG_FS_JFFS2_CFLAGS_ADD {
 	display "Additional compiler flags"
 	flavor  data
diff -ru packages-orig/fs/jffs2/current/src/compr.c packages/fs/jffs2/current/src/compr.c
--- packages-orig/fs/jffs2/current/src/compr.c	2003-02-05 01:00:40.000000000 +0100
+++ packages/fs/jffs2/current/src/compr.c	2003-11-12 18:28:56.000000000 +0100
@@ -88,7 +88,7 @@
 	memcpy(cpage_out,data_in,min(*datalen,*cdatalen));
 	if (*datalen > *cdatalen)
 		*datalen = *cdatalen;
-#endif		
+#endif
 	return JFFS2_COMPR_NONE; /* We failed to compress */
 
 }
diff -ru packages-orig/fs/jffs2/current/src/fs-ecos.c packages/fs/jffs2/current/src/fs-ecos.c
--- packages-orig/fs/jffs2/current/src/fs-ecos.c	2003-10-08 14:06:52.000000000 +0200
+++ packages/fs/jffs2/current/src/fs-ecos.c	2003-11-13 18:17:07.000000000 +0100
@@ -552,6 +552,7 @@
 			return ENOMEM;
 		}
 		memset(c->inocache_list, 0, sizeof(struct jffs2_inode_cache *) * INOCACHE_HASHSIZE);
+		jffs2_init_raw_node_ref_pool();
 
 		err = jffs2_read_super(jffs2_sb);
 
diff -ru packages-orig/fs/jffs2/current/src/malloc-ecos.c packages/fs/jffs2/current/src/malloc-ecos.c
--- packages-orig/fs/jffs2/current/src/malloc-ecos.c	2003-02-05 01:00:40.000000000 +0100
+++ packages/fs/jffs2/current/src/malloc-ecos.c	2003-11-14 13:14:54.000000000 +0100
@@ -12,8 +12,13 @@
  */
 
 #include <linux/kernel.h>
+#include <cyg/hal/drv_api.h>
 #include "nodelist.h"
 
+#if !defined(CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE)
+# define CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE 0
+#endif
+
 struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize)
 {
 	return malloc(sizeof(struct jffs2_full_dirent) + namesize);
@@ -64,16 +69,6 @@
 	free(x);
 }
 
-struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void)
-{
-	return malloc(sizeof(struct jffs2_raw_node_ref));
-}
-
-void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x)
-{
-	free(x);
-}
-
 struct jffs2_node_frag *jffs2_alloc_node_frag(void)
 {
 	return malloc(sizeof(struct jffs2_node_frag));
@@ -97,3 +92,61 @@
 	free(x);
 }
 
+#if CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE == 0
+
+void jffs2_init_raw_node_ref_pool(void)
+{
+}
+
+struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void)
+{
+	return malloc(sizeof(struct jffs2_raw_node_ref));
+}
+
+void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x)
+{
+	free(x);
+}
+
+#else // CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE == 0
+
+static struct jffs2_raw_node_ref
+	rnr_pool[CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE] __attribute__ ((aligned (4))),
+	* first = NULL;
+static cyg_drv_mutex_t mutex;
+
+void jffs2_init_raw_node_ref_pool(void)
+{
+	struct jffs2_raw_node_ref * p;
+	cyg_drv_mutex_init(&mutex);
+	for (
+		p = rnr_pool;
+		p < rnr_pool + CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE - 1;
+		p++
+	)
+		p->next_phys = p + 1;
+	rnr_pool[CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE - 1].next_phys = NULL;
+	first = &rnr_pool[0];
+}
+
+struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void)
+{
+	struct jffs2_raw_node_ref * p;
+	
+	cyg_drv_mutex_lock(&mutex);
+	p = first;
+	if (p != NULL)
+		first = p->next_phys;
+	cyg_drv_mutex_unlock(&mutex);
+	return p;
+}
+
+void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x)
+{
+	cyg_drv_mutex_lock(&mutex);
+	x->next_phys = first;
+	first = x;
+	cyg_drv_mutex_unlock(&mutex);
+}
+
+#endif // CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE == 0
diff -ru packages-orig/fs/jffs2/current/src/nodelist.h packages/fs/jffs2/current/src/nodelist.h
--- packages-orig/fs/jffs2/current/src/nodelist.h	2003-08-05 17:25:26.000000000 +0200
+++ packages/fs/jffs2/current/src/nodelist.h	2003-11-13 13:19:10.000000000 +0100
@@ -23,6 +23,7 @@
 
 #ifdef __ECOS
 #include "os-ecos.h"
+#include <pkgconf/fs_jffs2.h>
 #else
 #include <linux/mtd/compatmac.h> /* For min/max in older kernels */
 #include "os-linux.h"
@@ -346,6 +347,7 @@
 void jffs2_free_raw_inode(struct jffs2_raw_inode *);
 struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void);
 void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *);
+void jffs2_init_raw_node_ref_pool(void);
 struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void);
 void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *);
 struct jffs2_node_frag *jffs2_alloc_node_frag(void);
diff -ru packages-orig/fs/jffs2/current/src/write.c packages/fs/jffs2/current/src/write.c
--- packages-orig/fs/jffs2/current/src/write.c	2003-02-05 01:00:40.000000000 +0100
+++ packages/fs/jffs2/current/src/write.c	2003-11-12 18:28:04.000000000 +0100
@@ -300,6 +300,10 @@
 		datalen = writelen;
 		cdatalen = min_t(uint32_t, alloclen - sizeof(*ri), writelen);
 
+#if defined(__ECOS) && !defined(CYGPKG_FS_JFFS2_COMPRESS)
+		comprbuf = buf;
+		datalen = cdatalen;
+#else
 		comprbuf = kmalloc(cdatalen, GFP_KERNEL);
 		if (comprbuf) {
 			comprtype = jffs2_compress(buf, comprbuf, &datalen, &cdatalen);
@@ -311,6 +315,7 @@
 			comprbuf = buf;
 			datalen = cdatalen;
 		}
+#endif
 		/* Now comprbuf points to the data to be written, be it compressed or not.
 		   comprtype holds the compression type, and comprtype == JFFS2_COMPR_NONE means
 		   that the comprbuf doesn't need to be kfree()d. 


-- 
--------------------------------------------------

Thomas Koeller, Software Development

Basler Vision Technologies
An der Strusbek 60-62
22926 Ahrensburg
Germany

Tel +49 (4102) 463-162
Fax +49 (4102) 463-239

mailto:thomas.koeller@baslerweb.com
http://www.baslerweb.com

==============================


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]