Merge "mtd: Collect bad block count for ecc stats lazily"

This commit is contained in:
qctecmdr 2020-12-21 16:11:24 -08:00 • committed by Gerrit - the friendly Code Review server
commit 5328bcf5f4
4 changed files with 40 additions and 11 deletions

View file

@ -193,6 +193,17 @@ config MTD_PARTITIONED_MASTER
the parent of the partition device be the master device, rather than
what lies behind the master.
config MTD_LAZYECCSTATS
bool "MTD Lazy ECC Stats collection support"
default y
help
Normally bad block counts for ECC stats are collected at boot time.
This option delays the badblock stats collection until ECCGETSTATS
ioctl is invoked on the partition.
This can significantly decrease boot times depending on the size of
the partition. If unsure, say 'N'.
source "drivers/mtd/chips/Kconfig"
source "drivers/mtd/maps/Kconfig"

View file

@ -971,6 +971,9 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
case ECCGETSTATS:
{
#ifdef CONFIG_MTD_LAZYECCSTATS
part_fill_badblockstats(mtd);
#endif
if (copy_to_user(argp, &mtd->ecc_stats,
sizeof(struct mtd_ecc_stats)))
return -EFAULT;

View file

@ -317,6 +317,28 @@ static inline void free_partition(struct mtd_part *p)
kfree(p);
}
void part_fill_badblockstats(struct mtd_info *mtd)
{
uint64_t offs = 0;
struct mtd_info *parent;
struct mtd_part *part = mtd_to_part(mtd);
parent = part->parent;
if (parent->_block_isbad) {
mtd->ecc_stats.badblocks = 0;
mtd->ecc_stats.bbtblocks = 0;
while (offs < mtd->size) {
if (mtd_block_isreserved(parent, offs + part->offset))
mtd->ecc_stats.bbtblocks++;
else if (mtd_block_isbad(parent, offs + part->offset))
mtd->ecc_stats.badblocks++;
offs += mtd->erasesize;
}
}
}
static struct mtd_part *allocate_partition(struct mtd_info *parent,
const struct mtd_partition *part, int partno,
uint64_t cur_offset)
@ -537,17 +559,9 @@ static struct mtd_part *allocate_partition(struct mtd_info *parent,
slave->mtd.ecc_strength = parent->ecc_strength;
slave->mtd.bitflip_threshold = parent->bitflip_threshold;
if (parent->_block_isbad) {
uint64_t offs = 0;
while (offs < slave->mtd.size) {
if (mtd_block_isreserved(parent, offs + slave->offset))
slave->mtd.ecc_stats.bbtblocks++;
else if (mtd_block_isbad(parent, offs + slave->offset))
slave->mtd.ecc_stats.badblocks++;
offs += slave->mtd.erasesize;
}
}
#ifndef CONFIG_MTD_LAZYECCSTATS
part_fill_badblockstats(&(slave->mtd));
#endif
out_register:
return slave;

View file

@ -68,6 +68,7 @@ struct mtd_part_parser_data {
unsigned long origin;
};
void part_fill_badblockstats(struct mtd_info *mtd);
/*
* Functions dealing with the various ways of partitioning the space