Due to the recursive ubi_thread implementation in the barebox, a large
amount of wear-leveling can lead to a stack overflow.

This was observed during extensive ubi stress tests with the linux
kernel and periodic power cycles. We found that if the wear-leveling
threshold is exceeded and a large amount of erase blocks need
wear-leveling the stack can overflow.

The hardware used to observe this was a phyCORE-i.MX 6 with 1GB NAND flash.

As the kernel is perfectly capable of handling wear-leveling we can
disable wear-leveling in the barebox by maxing out the threshold and
removing its Kconfig option.

Signed-off-by: Stefan Riedmueller <s.riedmuel...@phytec.de>
---
Changes in v2:
 - Remove threshold config completely instead of just maxing out the default
---
 drivers/mtd/ubi/Kconfig | 17 -----------------
 drivers/mtd/ubi/build.c |  2 +-
 drivers/mtd/ubi/ubi.h   | 11 +++++++++++
 drivers/mtd/ubi/wl.c    |  8 --------
 4 files changed, 12 insertions(+), 26 deletions(-)

diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig
index 9a344082b7bb..ed2f13d14c30 100644
--- a/drivers/mtd/ubi/Kconfig
+++ b/drivers/mtd/ubi/Kconfig
@@ -10,23 +10,6 @@ menuconfig MTD_UBI
 
 if MTD_UBI
 
-config MTD_UBI_WL_THRESHOLD
-       int "UBI wear-leveling threshold"
-       default 4096
-       range 2 65536
-       help
-         This parameter defines the maximum difference between the highest
-         erase counter value and the lowest erase counter value of eraseblocks
-         of UBI devices. When this threshold is exceeded, UBI starts performing
-         wear leveling by means of moving data from eraseblock with low erase
-         counter to eraseblocks with high erase counter.
-
-         The default value should be OK for SLC NAND flashes, NOR flashes and
-         other flashes which have eraseblock life-cycle 100000 or more.
-         However, in case of MLC NAND flashes which typically have eraseblock
-         life-cycle less than 10000, the threshold should be lessened (e.g.,
-         to 128 or 256, although it does not have to be power of 2).
-
 config MTD_UBI_BEB_LIMIT
        int "Maximum expected bad eraseblock count per 1024 eraseblocks"
        default 20
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 493c778c3fdb..604fe87e53b6 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -655,7 +655,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
                ubi->vol_count - UBI_INT_VOL_COUNT, UBI_INT_VOL_COUNT,
                ubi->vtbl_slots);
        ubi_msg(ubi, "max/mean erase counter: %d/%d, WL threshold: %d, image 
sequence number: %u",
-               ubi->max_ec, ubi->mean_ec, CONFIG_MTD_UBI_WL_THRESHOLD,
+               ubi->max_ec, ubi->mean_ec, UBI_WL_THRESHOLD,
                ubi->image_seq);
        ubi_msg(ubi, "available PEBs: %d, total reserved PEBs: %d, PEBs 
reserved for bad PEB handling: %d",
                ubi->avail_pebs, ubi->rsvd_pebs, ubi->beb_rsvd_pebs);
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 922c1a3c8b49..7d07bbf19720 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -69,6 +69,17 @@
  */
 #define UBI_PROT_QUEUE_LEN 10
 
+/*
+ * Maximum difference between two erase counters. If this threshold is
+ * exceeded, the WL sub-system starts moving data from used physical
+ * eraseblocks with low erase counter to free physical eraseblocks with high
+ * erase counter.
+ * Extensive wear-leveling in the barebox can lead to stack overflows. Thus
+ * disable it by setting the threshold to the OS's max configurable value and
+ * leave wear-leveling to the OS.
+ */
+#define UBI_WL_THRESHOLD 65536
+
 /* The volume ID/LEB number/erase counter is unknown */
 #define UBI_UNKNOWN -1
 
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index cf90ecfb2385..013ba3e1ffc7 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -101,14 +101,6 @@
 #define WL_RESERVED_PEBS 1
 
 /*
- * Maximum difference between two erase counters. If this threshold is
- * exceeded, the WL sub-system starts moving data from used physical
- * eraseblocks with low erase counter to free physical eraseblocks with high
- * erase counter.
- */
-#define UBI_WL_THRESHOLD CONFIG_MTD_UBI_WL_THRESHOLD
-
-/*
  * When a physical eraseblock is moved, the WL sub-system has to pick the 
target
  * physical eraseblock to move to. The simplest way would be just to pick the
  * one with the highest erase counter. But in certain workloads this could lead
-- 
2.7.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

Reply via email to