[RFC][PATCH] mtd: cfi_cmdset_0001.c: Take lock when determining block lock status.
Ronald Wahl
ronald.wahl at raritan.com
Wed Apr 22 05:37:04 PDT 2015
Determining block lock status modifies chip status without taking lock.
This can lead to hanging flash operations
Signed-off-by: Ronald Wahl <ronald.wahl at raritan.com>
---
Not sure is this patch is efficient in the suspend/resume path since the lock
is then taken and released for every flash block. This is also the reason why
I split out a separate do_getlockstatus_oneblock_unlocked() routine. Maybe we
need to take the lock separately in the suspend/resume path and then call this
_unlocked variant for each flash block.
In my own use case I do not use suspend resume so I just ignored this. So the
question is: Is the patch usable in it's current form respective what needs to
change.
drivers/mtd/chips/cfi_cmdset_0001.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 286b97a..cad687f 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -2044,10 +2044,10 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
}
}
-static int __xipram do_getlockstatus_oneblock(struct map_info *map,
- struct flchip *chip,
- unsigned long adr,
- int len, void *thunk)
+static int __xipram do_getlockstatus_oneblock_unlocked(struct map_info *map,
+ struct flchip *chip,
+ unsigned long adr,
+ int len, void *thunk)
{
struct cfi_private *cfi = map->fldrv_priv;
int status, ofs_factor = cfi->interleave * cfi->device_type;
@@ -2061,6 +2061,27 @@ static int __xipram do_getlockstatus_oneblock(struct map_info *map,
return status;
}
+static int __xipram do_getlockstatus_oneblock(struct map_info *map,
+ struct flchip *chip,
+ unsigned long adr,
+ int len, void *thunk)
+{
+ int ret;
+
+ mutex_lock(&chip->mutex);
+ ret = get_chip(map, chip, adr + chip->start, FL_JEDEC_QUERY);
+ if (ret) {
+ mutex_unlock(&chip->mutex);
+ return ret;
+ }
+
+ ret = do_getlockstatus_oneblock_unlocked(map, chip, adr, len, thunk);
+
+ put_chip(map, chip, adr);
+ mutex_unlock(&chip->mutex);
+ return ret;
+}
+
#ifdef DEBUG_LOCK_BITS
static int __xipram do_printlockstatus_oneblock(struct map_info *map,
struct flchip *chip,
--
2.1.0
More information about the linux-mtd
mailing list