mtd: Allocate bdi objects dynamically

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Fri Dec 16 11:59:15 PST 2016


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=445caaa20c4d6da74f426464f90513b81157ad77
Commit:     445caaa20c4d6da74f426464f90513b81157ad77
Parent:     59dbc86cdc42b6d8766218066429f00186b021c2
Author:     Steve Longerbeam <steve_longerbeam at mentor.com>
AuthorDate: Thu Aug 4 19:31:15 2016 +0530
Committer:  Brian Norris <computersforpeace at gmail.com>
CommitDate: Thu Dec 1 10:03:17 2016 -0800

    mtd: Allocate bdi objects dynamically
    
    The MTD backing dev info objects mtd_bdi was statically allocated.
    So when MTD is built as a loadable module, this object fall in the
    vmalloc address space.
    
    The problem with that, is that the BDI APIs use wake_up_bit(), which calls
    virt_to_page() to retrieve the memory zone of the page containing the
    wait_queue to wake up, and virt_to_page() is not valid for vmalloc or
    highmem addresses.
    
    Fix this by allocating the BDI objects dynamically with kmalloc. The
    objects now fall in the logical address space so that BDI APIs will
    work in all cases (mtd builtin or module).
    
    Signed-off-by: Steve Longerbeam <steve_longerbeam at mentor.com>
    Signed-off-by: Jim Baxter <jim_baxter at mentor.com>
    Signed-off-by: Sandeep Jain <Sandeep_Jain at mentor.com>
    Reviewed-by: Richard Weinberger <richard at nod.at>
    Reviewed-by: Marek Vasut <marek.vasut at gmail.com>
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/mtdcore.c | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index ca661ce..052772f 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -46,8 +46,7 @@
 
 #include "mtdcore.h"
 
-static struct backing_dev_info mtd_bdi = {
-};
+static struct backing_dev_info *mtd_bdi;
 
 #ifdef CONFIG_PM_SLEEP
 
@@ -500,7 +499,7 @@ int add_mtd_device(struct mtd_info *mtd)
 	if (WARN_ONCE(mtd->backing_dev_info, "MTD already registered\n"))
 		return -EEXIST;
 
-	mtd->backing_dev_info = &mtd_bdi;
+	mtd->backing_dev_info = mtd_bdi;
 
 	BUG_ON(mtd->writesize == 0);
 	mutex_lock(&mtd_table_mutex);
@@ -1771,18 +1770,20 @@ static const struct file_operations mtd_proc_ops = {
 /*====================================================================*/
 /* Init code */
 
-static int __init mtd_bdi_init(struct backing_dev_info *bdi, const char *name)
+static struct backing_dev_info * __init mtd_bdi_init(char *name)
 {
+	struct backing_dev_info *bdi;
 	int ret;
 
-	ret = bdi_init(bdi);
-	if (!ret)
-		ret = bdi_register(bdi, NULL, "%s", name);
+	bdi = kzalloc(sizeof(*bdi), GFP_KERNEL);
+	if (!bdi)
+		return ERR_PTR(-ENOMEM);
 
+	ret = bdi_setup_and_register(bdi, name);
 	if (ret)
-		bdi_destroy(bdi);
+		kfree(bdi);
 
-	return ret;
+	return ret ? ERR_PTR(ret) : bdi;
 }
 
 static struct proc_dir_entry *proc_mtd;
@@ -1795,9 +1796,11 @@ static int __init init_mtd(void)
 	if (ret)
 		goto err_reg;
 
-	ret = mtd_bdi_init(&mtd_bdi, "mtd");
-	if (ret)
+	mtd_bdi = mtd_bdi_init("mtd");
+	if (IS_ERR(mtd_bdi)) {
+		ret = PTR_ERR(mtd_bdi);
 		goto err_bdi;
+	}
 
 	proc_mtd = proc_create("mtd", 0, NULL, &mtd_proc_ops);
 
@@ -1810,6 +1813,8 @@ static int __init init_mtd(void)
 out_procfs:
 	if (proc_mtd)
 		remove_proc_entry("mtd", NULL);
+	bdi_destroy(mtd_bdi);
+	kfree(mtd_bdi);
 err_bdi:
 	class_unregister(&mtd_class);
 err_reg:
@@ -1823,7 +1828,8 @@ static void __exit cleanup_mtd(void)
 	if (proc_mtd)
 		remove_proc_entry("mtd", NULL);
 	class_unregister(&mtd_class);
-	bdi_destroy(&mtd_bdi);
+	bdi_destroy(mtd_bdi);
+	kfree(mtd_bdi);
 	idr_destroy(&mtd_idr);
 }
 



More information about the linux-mtd-cvs mailing list