mtd: Collect bad block count for ecc stats lazily
Normally bad block counts for ECC stats are collected during boot time. This can be done lazily when the ECCGETSTATS ioctl is invoked on the partition. This can significantly decrease boot time, depending on the size of the partition. Also rescanning on every ioctl invocation helps in having the latest bad block count rather than depending on the count that is collected during boot. Change-Id: I43d7a769a1d4ef769823d0b5bbe132adb474f892 Signed-off-by: Murali Palnati <palnatim@codeaurora.org> Signed-off-by: Krishna Konda <kkonda@codeaurora.org> Signed-off-by: Nikhilesh Reddy <reddyn@codeaurora.org> Signed-off-by: Pradeep P V K <ppvk@codeaurora.org> Signed-off-by: Sarthak Garg <sartgarg@codeaurora.org> Signed-off-by: Sai Kannan <quic_csaikann@quicinc.com>
This commit is contained in:
parent
840e64a463
commit
0f5ad37363
4 changed files with 38 additions and 11 deletions
|
|
@ -206,6 +206,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"
|
||||
|
|
|
|||
|
|
@ -1174,6 +1174,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;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,26 @@ static inline void free_partition(struct mtd_info *mtd)
|
|||
kfree(mtd);
|
||||
}
|
||||
|
||||
void part_fill_badblockstats(struct mtd_info *mtd)
|
||||
{
|
||||
uint64_t offs = 0;
|
||||
struct mtd_info *parent = mtd->parent;
|
||||
struct mtd_info *master = mtd_get_master(parent);
|
||||
|
||||
if (master->_block_isbad) {
|
||||
mtd->ecc_stats.badblocks = 0;
|
||||
mtd->ecc_stats.bbtblocks = 0;
|
||||
|
||||
while (offs < mtd->part.size) {
|
||||
if (mtd_block_isreserved(mtd, offs))
|
||||
mtd->ecc_stats.bbtblocks++;
|
||||
else if (mtd_block_isbad(mtd, offs))
|
||||
mtd->ecc_stats.badblocks++;
|
||||
offs += mtd->erasesize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct mtd_info *allocate_partition(struct mtd_info *parent,
|
||||
const struct mtd_partition *part,
|
||||
int partno, uint64_t cur_offset)
|
||||
|
|
@ -197,17 +217,9 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent,
|
|||
child->ecc_strength = parent->ecc_strength;
|
||||
child->bitflip_threshold = parent->bitflip_threshold;
|
||||
|
||||
if (master->_block_isbad) {
|
||||
uint64_t offs = 0;
|
||||
|
||||
while (offs < child->part.size) {
|
||||
if (mtd_block_isreserved(child, offs))
|
||||
child->ecc_stats.bbtblocks++;
|
||||
else if (mtd_block_isbad(child, offs))
|
||||
child->ecc_stats.badblocks++;
|
||||
offs += child->erasesize;
|
||||
}
|
||||
}
|
||||
#ifndef CONFIG_MTD_LAZYECCSTATS
|
||||
part_fill_badblockstats(child);
|
||||
#endif
|
||||
|
||||
out_register:
|
||||
return child;
|
||||
|
|
|
|||
|
|
@ -70,6 +70,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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue