This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
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
==============================