Skip to content

Commit

Permalink
mtd: mtdpart: Make ECC stat handling consistent
Browse files Browse the repository at this point in the history
part_read() and part_read_oob() were counting ECC failures and
bitflips differently. Adjust part_read_oob() to mimic what is done in
part_read(). This is needed to use ->_read_oob() as a fallback when
when ->_read() is not implemented.

Note that bitflips and ECC failure accounting on MTD partitions is
broken by design, because nothing prevents concurrent accesses to the
underlying master MTD device between the moment we save the stats in a
local variable and the moment master->_read[_oob]() returns. It's not
something that can easily be fixed, so leave it like that for now.

Suggested-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Tested-by: Ladislav Michl <ladis@linux-mips.org>
  • Loading branch information
Boris Brezillon committed Jan 16, 2018
1 parent f72071b commit d020fc8
Showing 1 changed file with 8 additions and 6 deletions.
14 changes: 8 additions & 6 deletions drivers/mtd/mtdpart.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops)
{
struct mtd_part *part = mtd_to_part(mtd);
struct mtd_ecc_stats stats;
int res;

if (from >= mtd->size)
Expand All @@ -126,13 +127,14 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
return -EINVAL;
}

stats = part->parent->ecc_stats;
res = part->parent->_read_oob(part->parent, from + part->offset, ops);
if (unlikely(res)) {
if (mtd_is_bitflip(res))
mtd->ecc_stats.corrected++;
if (mtd_is_eccerr(res))
mtd->ecc_stats.failed++;
}
if (unlikely(mtd_is_eccerr(res)))
mtd->ecc_stats.failed +=
part->parent->ecc_stats.failed - stats.failed;
else
mtd->ecc_stats.corrected +=
part->parent->ecc_stats.corrected - stats.corrected;
return res;
}

Expand Down

0 comments on commit d020fc8

Please sign in to comment.