UBI: fix mean EC calculation

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Wed Apr 23 05:59:02 EDT 2008


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=4bc1dca4b0eb4dfbf100895bfc1256f21e3c901a
Commit:     4bc1dca4b0eb4dfbf100895bfc1256f21e3c901a
Parent:     cbd8a9d2cd6f576ca41022599341bbd8be1b0b27
Author:     Artem Bityutskiy <Artem.Bityutskiy at nokia.com>
AuthorDate: Sat Apr 19 20:44:31 2008 +0300
Committer:  Artem Bityutskiy <Artem.Bityutskiy at nokia.com>
CommitDate: Sat Apr 19 20:49:41 2008 +0300

    UBI: fix mean EC calculation
    
    (a + b) / (c + d) != a / c + b / d. The old code errornously
    assumed this incorrect formuld. Instead, just sum all erase
    counters in a 64-bit variable and divide to the number of EBs
    at the end.
    
    Thanks to Adrian Hunter for pointing this out.
    
    Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy at nokia.com>
---
 drivers/mtd/ubi/scan.c |   41 ++++++++---------------------------------
 drivers/mtd/ubi/scan.h |    2 +-
 2 files changed, 9 insertions(+), 34 deletions(-)

diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index 05aa3e7..96d410e 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -42,6 +42,7 @@
 
 #include <linux/err.h>
 #include <linux/crc32.h>
+#include <asm/div64.h>
 #include "ubi.h"
 
 #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
@@ -92,27 +93,6 @@ static int add_to_list(struct ubi_scan_info *si, int pnum, int ec,
 }
 
 /**
- * commit_to_mean_value - commit intermediate results to the final mean erase
- * counter value.
- * @si: scanning information
- *
- * This is a helper function which calculates partial mean erase counter mean
- * value and adds it to the resulting mean value. As we can work only in
- * integer arithmetic and we want to calculate the mean value of erase counter
- * accurately, we first sum erase counter values in @si->ec_sum variable and
- * count these components in @si->ec_count. If this temporary @si->ec_sum is
- * going to overflow, we calculate the partial mean value
- * (@si->ec_sum/@si->ec_count) and add it to @si->mean_ec.
- */
-static void commit_to_mean_value(struct ubi_scan_info *si)
-{
-	si->ec_sum /= si->ec_count;
-	if (si->ec_sum % si->ec_count >= si->ec_count / 2)
-		si->mean_ec += 1;
-	si->mean_ec += si->ec_sum;
-}
-
-/**
  * validate_vid_hdr - check that volume identifier header is correct and
  * consistent.
  * @vid_hdr: the volume identifier header to check
@@ -901,15 +881,8 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum
 
 adjust_mean_ec:
 	if (!ec_corr) {
-		if (si->ec_sum + ec < ec) {
-			commit_to_mean_value(si);
-			si->ec_sum = 0;
-			si->ec_count = 0;
-		} else {
-			si->ec_sum += ec;
-			si->ec_count += 1;
-		}
-
+		si->ec_sum += ec;
+		si->ec_count += 1;
 		if (ec > si->max_ec)
 			si->max_ec = ec;
 		if (ec < si->min_ec)
@@ -965,9 +938,11 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi)
 
 	dbg_msg("scanning is finished");
 
-	/* Finish mean erase counter calculations */
-	if (si->ec_count)
-		commit_to_mean_value(si);
+	/* Calculate mean erase counter */
+	if (si->ec_count) {
+		do_div(si->ec_sum, si->ec_count);
+		si->mean_ec = si->ec_sum;
+	}
 
 	if (si->is_empty)
 		ubi_msg("empty MTD device detected");
diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h
index 46d444a..966b9b6 100644
--- a/drivers/mtd/ubi/scan.h
+++ b/drivers/mtd/ubi/scan.h
@@ -124,7 +124,7 @@ struct ubi_scan_info {
 	int max_ec;
 	unsigned long long max_sqnum;
 	int mean_ec;
-	int ec_sum;
+	uint64_t ec_sum;
 	int ec_count;
 };
 



More information about the linux-mtd-cvs mailing list