On 16/08/18 18:50, Richard Weinberger wrote:
Mark,

Am Donnerstag, 12. Juli 2018, 16:03:43 CEST schrieb Mark Spieth:
Mark, can you please file a patch and send it to linux-mtd mailing
list?
Such a change needs to go through Linux and then to u-boot.
But first we need to think about and discuss it in detail.
Will do.
Did you find some time to do that?
I'd like to have this resolved in both Linux and u-boot.

Apologies Richard.
I went on to another task and forgot about his.

I have been trying in spare time to make a unit test to demonstrate this fault but have not completed that yet. There is no good unit test framework so have had to come up with one using techniques I already use for other non kernel C projects using googletest/mock. I will post this when it works.

The patch for HEAD is attached (I hope this is acceptable).

It is not a good solution but it does prevent the bitflip issue in the older uboot.

Mark
>From 0675154bd872e8b3b9406552792adb0e0713add1 Mon Sep 17 00:00:00 2001
From: Mark Spieth <mark.spi...@netcommwireless.com>
Date: Fri, 13 Jul 2018 12:10:20 +1000
Subject: [PATCH] wear leveling scrubbing fixable bit flip fix


diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index f66b3b22f328..a1cfadd3b395 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -736,7 +736,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
 		/* Perform scrubbing */
 		scrubbing = 1;
 		e1 = rb_entry(rb_first(&ubi->scrub), struct ubi_wl_entry, u.rb);
-		e2 = get_peb_for_wl(ubi);
+		e2 = get_peb_for_wl_scrubbing(ubi);
 		if (!e2)
 			goto out_cancel;
 
@@ -1878,6 +1878,19 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi)
 	return e;
 }
 
+static struct ubi_wl_entry *get_peb_for_wl_scrubbing(struct ubi_device *ubi)
+{
+	struct ubi_wl_entry *e;
+
+	e = find_wl_entry(ubi, &ubi->free, 0);
+	self_check_in_wl_tree(ubi, e, &ubi->free);
+	ubi->free_count--;
+	ubi_assert(ubi->free_count >= 0);
+	rb_erase(&e->u.rb, &ubi->free);
+
+	return e;
+}
+
 /**
  * produce_free_peb - produce a free physical eraseblock.
  * @ubi: UBI device description object
diff --git a/drivers/mtd/ubi/wl.h b/drivers/mtd/ubi/wl.h
index a9e2d669acd8..579f7c729b5d 100644
--- a/drivers/mtd/ubi/wl.h
+++ b/drivers/mtd/ubi/wl.h
@@ -6,6 +6,10 @@ static int anchor_pebs_available(struct rb_root *root);
 static void update_fastmap_work_fn(struct work_struct *wrk);
 static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root);
 static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi);
+static inline struct ubi_wl_entry *get_peb_for_wl_scrubbing(struct ubi_device *ubi)
+{
+	return get_peb_for_wl(ubi);
+}
 static void ubi_fastmap_close(struct ubi_device *ubi);
 static inline void ubi_fastmap_init(struct ubi_device *ubi, int *count)
 {
@@ -18,6 +22,7 @@ static struct ubi_wl_entry *may_reserve_for_fm(struct ubi_device *ubi,
 					       struct rb_root *root);
 #else /* !CONFIG_MTD_UBI_FASTMAP */
 static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi);
+static struct ubi_wl_entry *get_peb_for_wl_scrubbing(struct ubi_device *ubi);
 static inline void ubi_fastmap_close(struct ubi_device *ubi) { }
 static inline void ubi_fastmap_init(struct ubi_device *ubi, int *count) { }
 static struct ubi_wl_entry *may_reserve_for_fm(struct ubi_device *ubi,
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to