mtd/drivers/mtd/devices ramtd.c,1.6,1.7

joern at infradead.org joern at infradead.org
Wed Mar 8 12:48:32 EST 2006


Update of /home/cvs/mtd/drivers/mtd/devices
In directory phoenix.infradead.org:/home/joern/mtd/drivers/mtd/devices

Modified Files:
	ramtd.c 
Log Message:
More changes from iSteve:
o Plugged a memory leak.
o Added option to pre-allocate all memory during startup.



Index: ramtd.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/devices/ramtd.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- ramtd.c	7 Mar 2006 14:40:31 -0000	1.6
+++ ramtd.c	8 Mar 2006 17:48:28 -0000	1.7
@@ -4,6 +4,8 @@
  * $Id$
  *
  * Copyright (c) 2005 Joern Engel <joern at wh.fh-wedel.de>
+ * Copyright (c) 2006 iSteve <isteve at bofh.cz>
+ *  - Added module parameters, immediate allocation and fixed few leaks.
  */
 #include <linux/kernel.h>
 #include <linux/list.h>
@@ -22,10 +24,14 @@
 static DECLARE_MUTEX(ramtd_mutex);
 
 static unsigned long ramtd_size = 4*1024*1024;
+static int ramtd_now = 0;
 
 module_param(ramtd_size, ulong, 0);
 MODULE_PARM_DESC(ramtd_size, "Total device size in bytes");
 
+module_param(ramtd_now, bool, 0);
+MODULE_PARM_DESC(ramtd_now, "Allocate all memory when loaded");
+
 
 static void *get_pool_page(void)
 {
@@ -39,6 +45,37 @@
 	free_page((unsigned long)page);
 }
 
+static void free_all_pages(struct ramtd *this)
+{
+	u32 page;
+	
+	for (page = 0; page < this->mtd.size / PAGE_SIZE; page++) {
+		if (this->page[page])
+			free_pool_page(this->page[page]);
+	}
+}
+
+static int alloc_all_pages(struct ramtd *this)
+{
+	u32 page;
+	
+	if (!ramtd_now)
+		return 0;
+	
+	for (page = 0; page < this->mtd.size / PAGE_SIZE; page++) {
+		if (this->page[page])
+			continue;
+		
+            	this->page[page] = get_pool_page();
+		if (!this->page[page])
+			return -ENOMEM;
+		
+		memset(this->page[page], 0xff, PAGE_SIZE);
+	}
+	
+	return 0;
+}
+
 
 static int ramtd_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
@@ -145,6 +182,7 @@
 {
 	struct ramtd *new;
 	u32 pages_size;
+	int err;
 
 	size = PAGE_ALIGN(size);
 	pages_size = size / PAGE_SIZE * sizeof(void*);
@@ -167,6 +205,13 @@
 		free_pool_page(new);
 		return -EAGAIN;
 	}
+	
+	err = alloc_all_pages(new);
+	if (err) {
+		free_all_pages(new);
+		vfree(new);
+		return err;
+	}
 
 	down_interruptible(&ramtd_mutex);
 	list_add(&new->list, &ramtd_list);
@@ -177,7 +222,7 @@
 
 static int __init ramtd_init(void)
 {
-	return register_device("ramtd", ramtd_size);
+	return register_device("ramtd", ramtd_size); /* FIXME */
 }
 
 static void __exit ramtd_exit(void)
@@ -186,6 +231,7 @@
 
 	down_interruptible(&ramtd_mutex);
 	list_for_each_entry_safe(this, next, &ramtd_list, list) {
+		free_all_pages(this);
 		del_mtd_device(&this->mtd);
 		vfree(this);
 	}
@@ -199,4 +245,5 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Joern Engel <joern at wh.fh-wedel.de>");
+MODULE_AUTHOR("iSteve <isteve at bofh.cz>");
 MODULE_DESCRIPTION("MTD using dynamic memory allocation");





More information about the linux-mtd-cvs mailing list