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]

Re: Pooled memory allocation for JFFS2


David Woodhouse wrote:
> On Fri, 2003-11-14 at 18:11 +0100, Thomas Koeller wrote:
> > --- 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 */
> >
> >  }
>
> You can omit that one :)
That was cause by trailing spaces in the original file.

>
> > 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_slab_caches();
> >
> >  		err = jffs2_read_super(jffs2_sb);
>
> Sorry, I lied. It's jffs2_create_slab_caches() which is already present
> in nodelist.h, not jffs2_init_slab_caches().
>
> Also, you're calling it once for every JFFS2 file system mounted. You
> should be doing it once precisely.
I had to use a static counter to achieve this, hope that's o.k.

>
> > --- 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"
>
> This could perhaps be added to os-ecos.h instead?
Done.

Here is the reworked patch:



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 19:34:42.000000000 +0100
@@ -1,3 +1,16 @@
+2003-11-14  Thomas Koeller  <thomas.koeller@baslerweb.com>
+
+	* cdl/jffs2.cdl:
+	* 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/os-ecos.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-14 19:25:10.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/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-14 19:36:43.000000000 +0100
@@ -142,6 +142,7 @@
 
 static char read_write_buffer[PAGE_CACHE_SIZE];	//avoids malloc when user may be under memory pressure
 static char gc_buffer[PAGE_CACHE_SIZE];	//avoids malloc when user may be under memory pressure
+static unsigned char n_fs_mounted = 0;	// a counter to track the number of jffs2 instances mounted
 
 //==========================================================================
 // Directory operations
@@ -552,10 +553,14 @@
 			return ENOMEM;
 		}
 		memset(c->inocache_list, 0, sizeof(struct jffs2_inode_cache *) * INOCACHE_HASHSIZE);
+		if (n_fs_mounted++ == 0)
+			jffs2_create_slab_caches(); // No error check, cannot fail
 
 		err = jffs2_read_super(jffs2_sb);
 
 		if (err) {
+			if (--n_fs_mounted == 0)
+				jffs2_destroy_slab_caches();
 			free(jffs2_sb);
 			free(c->inocache_list);
 			return err;
@@ -614,9 +619,11 @@
 		// That's all folks.
 		D2(printf("jffs2_umount No current mounts\n"));
 	} else {
-          jffs2_sb->s_mount_count--;
-        }
+		jffs2_sb->s_mount_count--;
+	}
         
+	if (--n_fs_mounted == 0)
+		jffs2_destroy_slab_caches();
 	return ENOERR;
 }
 
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 19:25:10.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,71 @@
 	free(x);
 }
 
+#if CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE == 0
+
+int jffs2_create_slab_caches(void)
+{
+	return 0;
+}
+
+void jffs2_destroy_slab_caches(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;
+
+int jffs2_create_slab_caches(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];
+	return 0;
+}
+
+void jffs2_destroy_slab_caches(void)
+{
+}
+
+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/os-ecos.h packages/fs/jffs2/current/src/os-ecos.h
--- packages-orig/fs/jffs2/current/src/os-ecos.h	2003-10-16 14:25:18.000000000 +0200
+++ packages/fs/jffs2/current/src/os-ecos.h	2003-11-14 19:25:10.000000000 +0100
@@ -14,6 +14,7 @@
 #ifndef __JFFS2_OS_ECOS_H__
 #define __JFFS2_OS_ECOS_H__
 
+#include <pkgconf/fs_jffs2.h>
 #include <cyg/io/io.h>
 #include <sys/types.h>
 #include <asm/atomic.h>
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-14 19:25:10.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]