Skip to content

Commit 472f011

Browse files
author
Murali Palnati
committed
[ARM] 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. Signed-off-by: Murali Palnati <[email protected]>
1 parent ad97502 commit 472f011

File tree

4 files changed

+35
-9
lines changed

4 files changed

+35
-9
lines changed

drivers/mtd/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ config MTD_PARTITIONS
4545
devices. Partitioning on NFTL 'devices' is a different - that's the
4646
'normal' form of partitioning used on a block device.
4747

48+
config MTD_LAZYECCSTATS
49+
bool "MTD Lazy ECC Stats collection support"
50+
depends on MTD_PARTITIONS
51+
default n
52+
help
53+
Normally bad block counts for ECC stats are collected at boot time.
54+
This option delays the badblock stats collection until ECCGETSTATS
55+
ioctl is invoked on the partition.
56+
57+
This can significantly decrease boot times depending on the size of
58+
the partition. If unsure, say 'N'.
59+
4860
config MTD_TESTS
4961
tristate "MTD tests support"
5062
depends on m

drivers/mtd/mtdchar.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <linux/mtd/mtd.h>
1818
#include <linux/mtd/compatmac.h>
19+
#include <linux/mtd/partitions.h>
1920

2021
#include <asm/uaccess.h>
2122

@@ -744,6 +745,9 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
744745

745746
case ECCGETSTATS:
746747
{
748+
#ifdef CONFIG_MTD_LAZYECCSTATS
749+
part_fill_badblockstats(mtd);
750+
#endif
747751
if (copy_to_user(argp, &mtd->ecc_stats,
748752
sizeof(struct mtd_ecc_stats)))
749753
return -EFAULT;

drivers/mtd/mtdpart.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,21 @@ static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
294294
return res;
295295
}
296296

297+
void part_fill_badblockstats(struct mtd_info *mtd)
298+
{
299+
struct mtd_part *part = PART(mtd);
300+
if (part->master->block_isbad) {
301+
uint64_t offs = 0;
302+
mtd->ecc_stats.badblocks = 0;
303+
while (offs < mtd->size) {
304+
if (part->master->block_isbad(part->master,
305+
offs + part->offset))
306+
mtd->ecc_stats.badblocks++;
307+
offs += mtd->erasesize;
308+
}
309+
}
310+
}
311+
297312
/*
298313
* This function unregisters and destroy all slave MTD objects which are
299314
* attached to the given master MTD object.
@@ -465,16 +480,10 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
465480
}
466481

467482
slave->mtd.ecclayout = master->ecclayout;
468-
if (master->block_isbad) {
469-
uint64_t offs = 0;
470483

471-
while (offs < slave->mtd.size) {
472-
if (master->block_isbad(master,
473-
offs + slave->offset))
474-
slave->mtd.ecc_stats.badblocks++;
475-
offs += slave->mtd.erasesize;
476-
}
477-
}
484+
#ifndef CONFIG_MTD_LAZYECCSTATS
485+
part_fill_badblockstats(&(slave->mtd));
486+
#endif
478487

479488
out_register:
480489
if (part->mtdp) {

include/linux/mtd/partitions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct mtd_partition {
5050

5151
int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
5252
int del_mtd_partitions(struct mtd_info *);
53+
void part_fill_badblockstats(struct mtd_info *mtd);
5354

5455
/*
5556
* Functions dealing with the various ways of partitioning the space

0 commit comments

Comments
 (0)