mtd: cfi: fix deadloop in cfi_cmdset_0002.c do_write_buffer [Linux 3.16.72]

This Linux kernel change "mtd: cfi: fix deadloop in cfi_cmdset_0002.c do_write_buffer" is included in the Linux 3.16.72 release. This change is authored by Liu Jian <liujian56 [at] huawei.com> on Sun Mar 3 15:04:18 2019 +0800. The commit for this change in Linux stable tree is f4ee482 (patch) which is from upstream commit d9b8a67. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream d9b8a67.

mtd: cfi: fix deadloop in cfi_cmdset_0002.c do_write_buffer

commit d9b8a67b3b95a5c5aae6422b8113adc1c2485f2b upstream.

In function do_write_buffer(), in the for loop, there is a case
chip_ready() returns 1 while chip_good() returns 0, so it never
break the loop.
To fix this, chip_good() is enough and it should timeout if it stay
bad for a while.

Fixes: dfeae1073583("mtd: cfi_cmdset_0002: Change write buffer to check correct value")
Signed-off-by: Yi Huaijie <yihuai[email protected]>
Signed-off-by: Liu Jian <[email protected]>
Reviewed-by: Tokunori Ikegami <[email protected]>
Signed-off-by: Richard Weinberger <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>

There are 6 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/mtd/chips/cfi_cmdset_0002.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 92303da..40047a2 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -1538,7 +1538,11 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
            continue;
        }

-       if (time_after(jiffies, timeo) && !chip_ready(map, adr))
+       /*
+        * We check "time_after" and "!chip_good" before checking "chip_good" to avoid
+        * the failure due to scheduling.
+        */
+       if (time_after(jiffies, timeo) && !chip_good(map, adr, datum))
            break;

        if (chip_good(map, adr, datum)) {

Leave a Reply

Your email address will not be published. Required fields are marked *