mtd/fs/jffs2 build.c, 1.85, 1.86 fs.c, 1.68, 1.69 gc.c, 1.155, 1.156 malloc.c, 1.31, 1.32 nodelist.c, 1.115, 1.116 nodelist.h, 1.142, 1.143 nodemgmt.c, 1.129, 1.130 readinode.c, 1.143, 1.144 scan.c, 1.127, 1.128 summary.c, 1.6, 1.7 super-v24.c, 1.87, 1.88 super.c, 1.110, 1.111 wbuf.c, 1.103, 1.104 write.c, 1.97, 1.98

Forrest Zhao forrest.zhao at intel.com
Fri Nov 11 03:51:42 EST 2005


Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/tmp/cvs-serv13918/fs/jffs2

Modified Files:
	build.c fs.c gc.c malloc.c nodelist.c nodelist.h nodemgmt.c 
	readinode.c scan.c summary.c super-v24.c super.c wbuf.c 
	write.c 
Log Message:
This patch uses "slab cache + pointers" to replace the memory allocation mechanism for struct jffs2_eraseblock in JFFS2.
In particular, this patch reduce the continuous memory allocation pressure in kernel space.



Index: build.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/build.c,v
retrieving revision 1.85
retrieving revision 1.86
diff -u -r1.85 -r1.86
--- build.c	7 Nov 2005 11:14:38 -0000	1.85
+++ build.c	11 Nov 2005 08:51:38 -0000	1.86
@@ -308,27 +308,13 @@
 int jffs2_do_mount_fs(struct jffs2_sb_info *c)
 {
 	int ret;
-	int i;
-	int size;
 
 	c->free_size = c->flash_size;
 	c->nr_blocks = c->flash_size / c->sector_size;
-	size = sizeof(struct jffs2_eraseblock) * c->nr_blocks;
-#ifndef __ECOS
-	if (jffs2_blocks_use_vmalloc(c))
-		c->blocks = vmalloc(size);
-	else
-#endif
-		c->blocks = kmalloc(size, GFP_KERNEL);
-	if (!c->blocks)
-		return -ENOMEM;
-
-	memset(c->blocks, 0, size);
-	for (i=0; i<c->nr_blocks; i++) {
-		INIT_LIST_HEAD(&c->blocks[i].list);
-		c->blocks[i].offset = i * c->sector_size;
-		c->blocks[i].free_size = c->sector_size;
-	}
+
+	ret = jffs2_alloc_eraseblocks(c);
+	if (ret)
+		return ret;
 
 	INIT_LIST_HEAD(&c->clean_list);
 	INIT_LIST_HEAD(&c->very_dirty_list);
@@ -345,20 +331,17 @@
 	c->summary = NULL;
 
 	ret = jffs2_sum_init(c);
-	if (ret)
+	if (ret) {
+		jffs2_free_eraseblocks(c);
 		return ret;
 
+	}
+
 	if (jffs2_build_filesystem(c)) {
 		dbg_fsbuild("build_fs failed\n");
 		jffs2_free_ino_caches(c);
 		jffs2_free_raw_node_refs(c);
-#ifndef __ECOS
-		if (jffs2_blocks_use_vmalloc(c))
-			vfree(c->blocks);
-		else
-#endif
-			kfree(c->blocks);
-
+		jffs2_free_eraseblocks(c);
 		return -EIO;
 	}
 

Index: fs.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/fs.c,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -r1.68 -r1.69
--- fs.c	7 Nov 2005 11:14:39 -0000	1.68
+++ fs.c	11 Nov 2005 08:51:38 -0000	1.69
@@ -519,10 +519,7 @@
 	iput(root_i);
 	jffs2_free_ino_caches(c);
 	jffs2_free_raw_node_refs(c);
-	if (jffs2_blocks_use_vmalloc(c))
-		vfree(c->blocks);
-	else
-		kfree(c->blocks);
+	jffs2_free_eraseblocks(c);
  out_inohash:
 	kfree(c->inocache_list);
  out_wbuf:

Index: gc.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/gc.c,v
retrieving revision 1.155
retrieving revision 1.156
diff -u -r1.155 -r1.156
--- gc.c	7 Nov 2005 11:14:39 -0000	1.155
+++ gc.c	11 Nov 2005 08:51:38 -0000	1.156
@@ -616,7 +616,7 @@
 		if (!retried && (nraw = jffs2_alloc_raw_node_ref())) {
 			/* Try to reallocate space and retry */
 			uint32_t dummy;
-			struct jffs2_eraseblock *jeb = &c->blocks[phys_ofs / c->sector_size];
+			struct jffs2_eraseblock *jeb = c->blocks[phys_ofs / c->sector_size];
 
 			retried = 1;
 
@@ -1129,7 +1129,7 @@
 				struct jffs2_raw_node_ref *raw = frag->node->raw;
 				struct jffs2_eraseblock *jeb;
 
-				jeb = &c->blocks[raw->flash_offset / c->sector_size];
+				jeb = c->blocks[raw->flash_offset / c->sector_size];
 
 				if (jeb == c->gcblock) {
 					D1(printk(KERN_DEBUG "Expanding down to cover frag (0x%x-0x%x) in gcblock at %08x\n",
@@ -1179,7 +1179,7 @@
 				struct jffs2_raw_node_ref *raw = frag->node->raw;
 				struct jffs2_eraseblock *jeb;
 
-				jeb = &c->blocks[raw->flash_offset / c->sector_size];
+				jeb = c->blocks[raw->flash_offset / c->sector_size];
 
 				if (jeb == c->gcblock) {
 					D1(printk(KERN_DEBUG "Expanding up to cover frag (0x%x-0x%x) in gcblock at %08x\n",

Index: malloc.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/malloc.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- malloc.c	7 Nov 2005 11:14:40 -0000	1.31
+++ malloc.c	11 Nov 2005 08:51:38 -0000	1.32
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/init.h>
+#include <linux/vmalloc.h>
 #include <linux/jffs2.h>
 #include "nodelist.h"
 
@@ -26,6 +27,12 @@
 static kmem_cache_t *raw_node_ref_slab;
 static kmem_cache_t *node_frag_slab;
 static kmem_cache_t *inode_cache_slab;
+static kmem_cache_t *eraseblock_slab;
+
+static inline int jffs2_blocks_use_vmalloc(struct jffs2_sb_info *c)
+{
+	return ((c->flash_size / c->sector_size) * sizeof(void*)) > (128 * 1024);
+}
 
 int __init jffs2_create_slab_caches(void)
 {
@@ -65,6 +72,12 @@
 	if (!node_frag_slab)
 		goto err;
 
+	eraseblock_slab = kmem_cache_create("jffs2_eraseblock",
+					   sizeof(struct jffs2_eraseblock),
+					   0, 0, NULL, NULL);
+	if (!eraseblock_slab)
+		goto err;
+
 	inode_cache_slab = kmem_cache_create("jffs2_inode_cache",
 					     sizeof(struct jffs2_inode_cache),
 					     0, 0, NULL, NULL);
@@ -91,6 +104,8 @@
 		kmem_cache_destroy(node_frag_slab);
 	if(inode_cache_slab)
 		kmem_cache_destroy(inode_cache_slab);
+	if (eraseblock_slab)
+		kmem_cache_destroy(eraseblock_slab);
 }
 
 struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize)
@@ -205,3 +220,57 @@
 	dbg_memalloc("%p\n", x);
 	kmem_cache_free(inode_cache_slab, x);
 }
+
+int jffs2_alloc_eraseblocks(struct jffs2_sb_info *c)
+{
+	uint32_t i;
+#ifndef __ECOS
+	if (jffs2_blocks_use_vmalloc(c))
+		c->blocks = vmalloc(sizeof(void *) * c->nr_blocks);
+	else
+#endif
+		c->blocks = kmalloc(sizeof(void *) * c->nr_blocks, GFP_KERNEL);
+	if (!c->blocks)
+		return -ENOMEM;
+	memset(c->blocks, 0, sizeof(void *) * c->nr_blocks);
+
+	for (i=0; i<c->nr_blocks; i++) {
+		c->blocks[i] = kmem_cache_alloc(eraseblock_slab, GFP_KERNEL);
+		dbg_memalloc("%p\n", c->blocks[i]);
+		if (!c->blocks[i]) {
+			jffs2_free_eraseblocks(c);
+			return -ENOMEM;
+		}
+		memset(c->blocks[i], 0, sizeof(struct jffs2_eraseblock));
+	}
+
+	
+	for (i=0; i<c->nr_blocks; i++) {
+		INIT_LIST_HEAD(&c->blocks[i]->list);
+		c->blocks[i]->offset = i * c->sector_size;
+		c->blocks[i]->free_size = c->sector_size;
+		c->blocks[i]->first_node = NULL;
+		c->blocks[i]->last_node = NULL;
+	}
+
+	return 0;
+}
+
+void jffs2_free_eraseblocks(struct jffs2_sb_info *c)
+{
+	uint32_t i;
+
+	for (i=0; i<c->nr_blocks; i++) {
+		if (c->blocks[i]) {
+			dbg_memalloc("%p\n", c->blocks[i]);
+			kmem_cache_free(eraseblock_slab, c->blocks[i]);
+		}
+	}
+#ifndef __ECOS
+	if (jffs2_blocks_use_vmalloc(c))
+		vfree(c->blocks);
+	else
+#endif
+		kfree(c->blocks);
+}
+

Index: nodelist.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/nodelist.c,v
retrieving revision 1.115
retrieving revision 1.116
diff -u -r1.115 -r1.116
--- nodelist.c	7 Nov 2005 11:14:40 -0000	1.115
+++ nodelist.c	11 Nov 2005 08:51:38 -0000	1.116
@@ -482,7 +482,7 @@
 	}
 
 adj_acc:
-	jeb = &c->blocks[ref->flash_offset / c->sector_size];
+	jeb = c->blocks[ref->flash_offset / c->sector_size];
 	len = ref_totlen(c, jeb, ref);
 
 	/*
@@ -950,13 +950,13 @@
 	struct jffs2_raw_node_ref *this, *next;
 
 	for (i=0; i<c->nr_blocks; i++) {
-		this = c->blocks[i].first_node;
+		this = c->blocks[i]->first_node;
 		while(this) {
 			next = this->next_phys;
 			jffs2_free_raw_node_ref(this);
 			this = next;
 		}
-		c->blocks[i].first_node = c->blocks[i].last_node = NULL;
+		c->blocks[i]->first_node = c->blocks[i]->last_node = NULL;
 	}
 }
 

Index: nodelist.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/nodelist.h,v
retrieving revision 1.142
retrieving revision 1.143
diff -u -r1.142 -r1.143
--- nodelist.h	7 Nov 2005 11:14:41 -0000	1.142
+++ nodelist.h	11 Nov 2005 08:51:38 -0000	1.143
@@ -205,11 +205,6 @@
 #define EBFLAGS_CLR_EBH(jeb) (jeb->flags &= ~1)
 #define EBFLAGS_HAS_EBH(jeb) ((jeb->flags & 1) == 1)
 
-static inline int jffs2_blocks_use_vmalloc(struct jffs2_sb_info *c)
-{
-	return ((c->flash_size / c->sector_size) * sizeof (struct jffs2_eraseblock)) > (128 * 1024);
-}
-
 /* Calculate totlen from surrounding nodes or eraseblock */
 static inline uint32_t __ref_totlen(struct jffs2_sb_info *c,
 				    struct jffs2_eraseblock *jeb,
@@ -221,7 +216,7 @@
 		ref_end = ref_offset(ref->next_phys);
 	else {
 		if (!jeb)
-			jeb = &c->blocks[ref->flash_offset / c->sector_size];
+			jeb = c->blocks[ref->flash_offset / c->sector_size];
 
 		/* Last node in block. Use free_space */
 		BUG_ON(ref != jeb->last_node);
@@ -237,9 +232,9 @@
 	uint32_t ret;
 
 #if CONFIG_JFFS2_FS_DEBUG > 0
-	if (jeb && jeb != &c->blocks[ref->flash_offset / c->sector_size]) {
+	if (jeb && jeb != c->blocks[ref->flash_offset / c->sector_size]) {
 		printk(KERN_CRIT "ref_totlen called with wrong block -- at 0x%08x instead of 0x%08x; ref 0x%08x\n",
-		       jeb->offset, c->blocks[ref->flash_offset / c->sector_size].offset, ref_offset(ref));
+		       jeb->offset, c->blocks[ref->flash_offset / c->sector_size]->offset, ref_offset(ref));
 		BUG();
 	}
 #endif
@@ -254,7 +249,7 @@
 		       ref, ref_offset(ref), ref_offset(ref)+ref->__totlen,
 		       ret, ref->__totlen);
 		if (!jeb)
-			jeb = &c->blocks[ref->flash_offset / c->sector_size];
+			jeb = c->blocks[ref->flash_offset / c->sector_size];
 		jffs2_dbg_dump_node_refs_nolock(c, jeb);
 		BUG();
 	}
@@ -381,7 +376,8 @@
 void jffs2_free_node_frag(struct jffs2_node_frag *);
 struct jffs2_inode_cache *jffs2_alloc_inode_cache(void);
 void jffs2_free_inode_cache(struct jffs2_inode_cache *);
-
+int jffs2_alloc_eraseblocks(struct jffs2_sb_info *c);
+void jffs2_free_eraseblocks(struct jffs2_sb_info *c);
 /* gc.c */
 int jffs2_garbage_collect_pass(struct jffs2_sb_info *c);
 

Index: nodemgmt.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/nodemgmt.c,v
retrieving revision 1.129
retrieving revision 1.130
diff -u -r1.129 -r1.130
--- nodemgmt.c	7 Nov 2005 11:14:41 -0000	1.129
+++ nodemgmt.c	11 Nov 2005 08:51:38 -0000	1.130
@@ -411,7 +411,7 @@
 	struct jffs2_eraseblock *jeb;
 	uint32_t len;
 
-	jeb = &c->blocks[new->flash_offset / c->sector_size];
+	jeb = c->blocks[new->flash_offset / c->sector_size];
 	len = ref_totlen(c, jeb, new);
 
 	D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n", ref_offset(new), ref_flags(new), len));
@@ -508,7 +508,7 @@
 		printk(KERN_NOTICE "raw node at 0x%08x is off the end of device!\n", ref->flash_offset);
 		BUG();
 	}
-	jeb = &c->blocks[blocknr];
+	jeb = c->blocks[blocknr];
 
 	if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) &&
 	    !(c->flags & (JFFS2_SB_FLAG_SCANNING | JFFS2_SB_FLAG_BUILDING))) {

Index: readinode.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/readinode.c,v
retrieving revision 1.143
retrieving revision 1.144
diff -u -r1.143 -r1.144
--- readinode.c	7 Nov 2005 11:14:41 -0000	1.143
+++ readinode.c	11 Nov 2005 08:51:39 -0000	1.144
@@ -294,7 +294,7 @@
 			struct jffs2_eraseblock *jeb;
 
 			dbg_readinode("the node has no data.\n");
-			jeb = &c->blocks[ref->flash_offset / c->sector_size];
+			jeb = c->blocks[ref->flash_offset / c->sector_size];
 			len = ref_totlen(c, jeb, ref);
 
 			spin_lock(&c->erase_completion_lock);

Index: scan.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/scan.c,v
retrieving revision 1.127
retrieving revision 1.128
diff -u -r1.127 -r1.128
--- scan.c	7 Nov 2005 11:14:41 -0000	1.127
+++ scan.c	11 Nov 2005 08:51:39 -0000	1.128
@@ -117,7 +117,7 @@
 	}
 
 	for (i=0; i<c->nr_blocks; i++) {
-		struct jffs2_eraseblock *jeb = &c->blocks[i];
+		struct jffs2_eraseblock *jeb = c->blocks[i];
 
 		/* reset summary info for next eraseblock scan */
 		jffs2_sum_reset_collected(s);

Index: summary.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/summary.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- summary.c	7 Nov 2005 11:14:42 -0000	1.6
+++ summary.c	11 Nov 2005 08:51:39 -0000	1.7
@@ -234,7 +234,7 @@
 	struct jffs2_eraseblock *jeb;
 
 	node = invecs[0].iov_base;
-	jeb = &c->blocks[ofs / c->sector_size];
+	jeb = c->blocks[ofs / c->sector_size];
 	ofs -= jeb->offset;
 
 	switch (je16_to_cpu(node->u.nodetype)) {

Index: super-v24.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/super-v24.c,v
retrieving revision 1.87
retrieving revision 1.88
diff -u -r1.87 -r1.88
--- super-v24.c	7 Nov 2005 11:14:42 -0000	1.87
+++ super-v24.c	11 Nov 2005 08:51:39 -0000	1.88
@@ -103,10 +103,7 @@
 
 	jffs2_free_ino_caches(c);
 	jffs2_free_raw_node_refs(c);
-	if (jffs2_blocks_use_vmalloc(c))
-		vfree(c->blocks);
-	else
-		kfree(c->blocks);
+	jffs2_free_eraseblocks(c);
 	jffs2_flash_cleanup(c);
 	kfree(c->inocache_list);
 	if (c->mtd->sync)

Index: super.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/super.c,v
retrieving revision 1.110
retrieving revision 1.111
diff -u -r1.110 -r1.111
--- super.c	7 Nov 2005 11:14:42 -0000	1.110
+++ super.c	11 Nov 2005 08:51:39 -0000	1.111
@@ -287,10 +287,7 @@
 
 	jffs2_free_ino_caches(c);
 	jffs2_free_raw_node_refs(c);
-	if (jffs2_blocks_use_vmalloc(c))
-		vfree(c->blocks);
-	else
-		kfree(c->blocks);
+	jffs2_free_eraseblocks(c);
 	jffs2_flash_cleanup(c);
 	kfree(c->inocache_list);
 	if (c->mtd->sync)

Index: wbuf.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/wbuf.c,v
retrieving revision 1.103
retrieving revision 1.104
diff -u -r1.103 -r1.104
--- wbuf.c	7 Nov 2005 11:14:42 -0000	1.103
+++ wbuf.c	11 Nov 2005 08:51:39 -0000	1.104
@@ -181,7 +181,7 @@
 
 	spin_lock(&c->erase_completion_lock);
 
-	jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
+	jeb = c->blocks[c->wbuf_ofs / c->sector_size];
 
 	jffs2_block_refile(c, jeb, REFILE_NOTEMPTY);
 
@@ -341,7 +341,7 @@
 	}
 
 	/* Now sort out the jffs2_raw_node_refs, moving them from the old to the next block */
-	new_jeb = &c->blocks[ofs / c->sector_size];
+	new_jeb = c->blocks[ofs / c->sector_size];
 
 	spin_lock(&c->erase_completion_lock);
 	if (new_jeb->first_node) {
@@ -490,7 +490,7 @@
 	if (pad) {
 		struct jffs2_eraseblock *jeb;
 
-		jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
+		jeb = c->blocks[c->wbuf_ofs / c->sector_size];
 
 		D1(printk(KERN_DEBUG "jffs2_flush_wbuf() adjusting free_size of %sblock at %08x\n",
 			  (jeb==c->nextblock)?"next":"", jeb->offset));
@@ -786,7 +786,7 @@
 
 			spin_lock(&c->erase_completion_lock);
 
-			jeb = &c->blocks[outvec_to / c->sector_size];
+			jeb = c->blocks[outvec_to / c->sector_size];
 			jffs2_block_refile(c, jeb, REFILE_ANYWAY);
 
 			*retlen = 0;

Index: write.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/write.c,v
retrieving revision 1.97
retrieving revision 1.98
diff -u -r1.97 -r1.98
--- write.c	7 Nov 2005 11:14:42 -0000	1.97
+++ write.c	11 Nov 2005 08:51:39 -0000	1.98
@@ -143,7 +143,7 @@
 		if (!retried && alloc_mode != ALLOC_NORETRY && (raw = jffs2_alloc_raw_node_ref())) {
 			/* Try to reallocate space and retry */
 			uint32_t dummy;
-			struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size];
+			struct jffs2_eraseblock *jeb = c->blocks[flash_ofs / c->sector_size];
 
 			retried = 1;
 
@@ -291,7 +291,7 @@
 		if (!retried && (raw = jffs2_alloc_raw_node_ref())) {
 			/* Try to reallocate space and retry */
 			uint32_t dummy;
-			struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size];
+			struct jffs2_eraseblock *jeb = c->blocks[flash_ofs / c->sector_size];
 
 			retried = 1;
 





More information about the linux-mtd-cvs mailing list