mtd: char: Get rid of Big MTD Lock
authorAlexander Sverdlin <alexander.sverdlin@nokia.com>
Wed, 17 Feb 2021 21:18:45 +0000 (22:18 +0100)
committerMiquel Raynal <miquel.raynal@bootlin.com>
Thu, 11 Mar 2021 08:37:49 +0000 (09:37 +0100)
Get rid of central chrdev MTD lock, which prevents simultaneous operations
on completely independent physical MTD chips. Replace it with newly
introduced per-master mutex.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20210217211845.43364-2-alexander.sverdlin@nokia.com
drivers/mtd/mtdchar.c
drivers/mtd/mtdcore.c
include/linux/mtd/mtd.h

index f31390d186ca521d50059f9b2ac6a1f77735b1de..57c4a2f0b703208d142b1568bc818d4946590f69 100644 (file)
@@ -27,8 +27,6 @@
 
 #include "mtdcore.h"
 
-static DEFINE_MUTEX(mtd_mutex);
-
 /*
  * Data structure to hold the pointer to the mtd device as well
  * as mode information of various use cases.
@@ -1020,11 +1018,14 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
 
 static long mtdchar_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
 {
+       struct mtd_file_info *mfi = file->private_data;
+       struct mtd_info *mtd = mfi->mtd;
+       struct mtd_info *master = mtd_get_master(mtd);
        int ret;
 
-       mutex_lock(&mtd_mutex);
+       mutex_lock(&master->master.chrdev_lock);
        ret = mtdchar_ioctl(file, cmd, arg);
-       mutex_unlock(&mtd_mutex);
+       mutex_unlock(&master->master.chrdev_lock);
 
        return ret;
 }
@@ -1045,10 +1046,11 @@ static long mtdchar_compat_ioctl(struct file *file, unsigned int cmd,
 {
        struct mtd_file_info *mfi = file->private_data;
        struct mtd_info *mtd = mfi->mtd;
+       struct mtd_info *master = mtd_get_master(mtd);
        void __user *argp = compat_ptr(arg);
        int ret = 0;
 
-       mutex_lock(&mtd_mutex);
+       mutex_lock(&master->master.chrdev_lock);
 
        switch (cmd) {
        case MEMWRITEOOB32:
@@ -1111,7 +1113,7 @@ static long mtdchar_compat_ioctl(struct file *file, unsigned int cmd,
                ret = mtdchar_ioctl(file, cmd, (unsigned long)argp);
        }
 
-       mutex_unlock(&mtd_mutex);
+       mutex_unlock(&master->master.chrdev_lock);
 
        return ret;
 }
index 2d6423d89a1759f182f083156fc87b38c8388ff6..0b095975895ed3cffc4da1e75cfac14b276b8eda 100644 (file)
@@ -773,6 +773,7 @@ static void mtd_set_dev_defaults(struct mtd_info *mtd)
 
        INIT_LIST_HEAD(&mtd->partitions);
        mutex_init(&mtd->master.partitions_lock);
+       mutex_init(&mtd->master.chrdev_lock);
 }
 
 /**
index 157357ec14419c56a2accbabf2cdf20f7b338fe4..ceabc2cae8a4de09abb04acdfb79ef8fdc302bb2 100644 (file)
@@ -229,6 +229,7 @@ struct mtd_part {
  */
 struct mtd_master {
        struct mutex partitions_lock;
+       struct mutex chrdev_lock;
        unsigned int suspended : 1;
 };