All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] mtd: use ONFI bad blocks per LUN to calculate UBIFS bad PEB limit
@ 2015-05-11 15:19 Ben Shelton
  2015-05-11 15:19 ` [PATCH 1/3] mtd: introduce function max_bad_blocks Ben Shelton
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Ben Shelton @ 2015-05-11 15:19 UTC (permalink / raw)
  To: dwmw2, computersforpeace, linux-mtd, linux-kernel, dedekind1, richard
  Cc: Ben Shelton

For ONFI-compliant NAND devices, the ONFI parameters report the maximum number
of bad blocks per LUN that will be encountered over the lifetime of the device,
so we can use that information to get a more accurate (and smaller) value for
the UBIFS bad PEB limit.

These patches are ordered in terms of their dependencies, but ideally, all 3
would need to be applied for this to work as intended.

Jeff Westfahl (3):
  mtd: introduce function max_bad_blocks
  mtd: nand: implement 'max_bad_blocks' mtd function
  mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit

 drivers/mtd/mtdpart.c        | 12 ++++++++++++
 drivers/mtd/nand/nand_base.c | 35 +++++++++++++++++++++++++++++++++++
 drivers/mtd/ubi/build.c      | 10 ++++++++++
 include/linux/mtd/mtd.h      |  1 +
 4 files changed, 58 insertions(+)

-- 
2.4.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] mtd: introduce function max_bad_blocks
  2015-05-11 15:19 [PATCH 0/3] mtd: use ONFI bad blocks per LUN to calculate UBIFS bad PEB limit Ben Shelton
@ 2015-05-11 15:19 ` Ben Shelton
  2015-05-11 15:19 ` [PATCH 2/3] mtd: nand: implement 'max_bad_blocks' mtd function Ben Shelton
  2015-05-11 15:19 ` [PATCH 3/3] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit Ben Shelton
  2 siblings, 0 replies; 5+ messages in thread
From: Ben Shelton @ 2015-05-11 15:19 UTC (permalink / raw)
  To: dwmw2, computersforpeace, linux-mtd, linux-kernel, dedekind1, richard
  Cc: Jeff Westfahl

From: Jeff Westfahl <jeff.westfahl@ni.com>

If implemented, 'max_bad_blocks' returns the maximum number of bad
blocks to reserve for an MTD.

Signed-off-by: Jeff Westfahl <jeff.westfahl@ni.com>
---
 drivers/mtd/mtdpart.c   | 12 ++++++++++++
 include/linux/mtd/mtd.h |  1 +
 2 files changed, 13 insertions(+)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index cafdb88..d252df9 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -317,6 +317,16 @@ static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
 	return res;
 }
 
+static int part_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+	struct mtd_part *part = PART(mtd);
+
+	if ((len + ofs) > mtd->size)
+		return -EINVAL;
+	return part->master->_max_bad_blocks(part->master,
+					     ofs + part->offset, len);
+}
+
 static inline void free_partition(struct mtd_part *p)
 {
 	kfree(p->mtd.name);
@@ -442,6 +452,8 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
 		slave->mtd._block_isbad = part_block_isbad;
 	if (master->_block_markbad)
 		slave->mtd._block_markbad = part_block_markbad;
+	if (master->_max_bad_blocks)
+		slave->mtd._max_bad_blocks = part_max_bad_blocks;
 	slave->mtd._erase = part_erase;
 	slave->master = master;
 	slave->offset = part->offset;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index f17fa75..ba607c2 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -225,6 +225,7 @@ struct mtd_info {
 	int (*_block_isreserved) (struct mtd_info *mtd, loff_t ofs);
 	int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
 	int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
+	int (*_max_bad_blocks) (struct mtd_info *mtd, loff_t ofs, size_t len);
 	int (*_suspend) (struct mtd_info *mtd);
 	void (*_resume) (struct mtd_info *mtd);
 	void (*_reboot) (struct mtd_info *mtd);
-- 
2.4.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] mtd: nand: implement 'max_bad_blocks' mtd function
  2015-05-11 15:19 [PATCH 0/3] mtd: use ONFI bad blocks per LUN to calculate UBIFS bad PEB limit Ben Shelton
  2015-05-11 15:19 ` [PATCH 1/3] mtd: introduce function max_bad_blocks Ben Shelton
@ 2015-05-11 15:19 ` Ben Shelton
  2015-05-14  9:43   ` Richard Weinberger
  2015-05-11 15:19 ` [PATCH 3/3] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit Ben Shelton
  2 siblings, 1 reply; 5+ messages in thread
From: Ben Shelton @ 2015-05-11 15:19 UTC (permalink / raw)
  To: dwmw2, computersforpeace, linux-mtd, linux-kernel, dedekind1, richard
  Cc: Jeff Westfahl

From: Jeff Westfahl <jeff.westfahl@ni.com>

Implement the new mtd function 'max_bad_blocks'. Use the "bad blocks
maximum per LUN" field in the ONFI parameter page to find the maximum
number of bad blocks to reserve for an MTD, taking into account the
number of LUNs in the NAND device and how many LUNs the MTD spans.

>From the ONFI 1.0 spec: "This field contains the maximum number of
blocks that may be defective at manufacture and over the life of the
device per LUN. The maximum rating assumes that the host is following
the block endurance requirements and the ECC requirements reported in
the parameter page."

Signed-off-by: Jeff Westfahl <jeff.westfahl@ni.com>
---
 drivers/mtd/nand/nand_base.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index c2e1232..a97d08e 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2884,6 +2884,40 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 }
 
 /**
+ * nand_max_bad_blocks - [MTD Interface] Max number of bad blocks for an mtd
+ * @mtd: MTD device structure
+ * @ofs: offset relative to mtd start
+ * @len: length of mtd
+ */
+static int nand_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+	struct nand_chip *chip = mtd->priv;
+	uint32_t part_start_block;
+	uint32_t part_end_block;
+	uint32_t part_start_lun;
+	uint32_t part_end_lun;
+
+	/* ONFI is used to determine the maximum bad block count. */
+	if (!chip->onfi_version)
+		return -ENOTSUPP;
+
+	/* Get the start and end of the partition in erase blocks. */
+	part_start_block = mtd_div_by_eb(ofs, mtd);
+	part_end_block = mtd_div_by_eb(len, mtd) + part_start_block - 1;
+
+	/* Get the start and end LUNs of the partition. */
+	part_start_lun = part_start_block / chip->onfi_params.blocks_per_lun;
+	part_end_lun = part_end_block / chip->onfi_params.blocks_per_lun;
+
+	/*
+	 * Look up the bad blocks per unit and multiply by the number of units
+	 * that the partition spans.
+	 */
+	return chip->onfi_params.bb_per_lun *
+		(part_end_lun - part_start_lun + 1);
+}
+
+/**
  * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
  * @mtd: MTD device structure
  * @chip: nand chip info structure
@@ -4179,6 +4213,7 @@ int nand_scan_tail(struct mtd_info *mtd)
 	mtd->_block_isreserved = nand_block_isreserved;
 	mtd->_block_isbad = nand_block_isbad;
 	mtd->_block_markbad = nand_block_markbad;
+	mtd->_max_bad_blocks = nand_max_bad_blocks;
 	mtd->writebufsize = mtd->writesize;
 
 	/* propagate ecc info to mtd_info */
-- 
2.4.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit
  2015-05-11 15:19 [PATCH 0/3] mtd: use ONFI bad blocks per LUN to calculate UBIFS bad PEB limit Ben Shelton
  2015-05-11 15:19 ` [PATCH 1/3] mtd: introduce function max_bad_blocks Ben Shelton
  2015-05-11 15:19 ` [PATCH 2/3] mtd: nand: implement 'max_bad_blocks' mtd function Ben Shelton
@ 2015-05-11 15:19 ` Ben Shelton
  2 siblings, 0 replies; 5+ messages in thread
From: Ben Shelton @ 2015-05-11 15:19 UTC (permalink / raw)
  To: dwmw2, computersforpeace, linux-mtd, linux-kernel, dedekind1, richard
  Cc: Jeff Westfahl

From: Jeff Westfahl <jeff.westfahl@ni.com>

Use the MTD function 'max_bad_blocks' to compute the UBI bad_peb_limit,
if the function is implemented for an MTD and doesn't return an error.

Currently, the UBIFS code computes the bad PEB limit based on the
worst-case assumption that all the bad blocks could be in a single
partition.  However, there are cases in which this is too pessimistic,
such as the case of an ONFI-compliant NAND device that specifies the
maximum number of bad blocks per LUN.

Signed-off-by: Jeff Westfahl <jeff.westfahl@ni.com>
---
 drivers/mtd/ubi/build.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index b7f824d..eca8ca6 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -597,6 +597,16 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, int max_beb_per1024)
 	int limit, device_pebs;
 	uint64_t device_size;
 
+	/*
+	 * If the MTD provides a max_bad_blocks function, use that value. Fall
+	 * back to max_beb_per1024 if that function returns an error.
+	 */
+	if (ubi->mtd->_max_bad_blocks) {
+		limit = ubi->mtd->_max_bad_blocks(ubi->mtd, 0, ubi->mtd->size);
+		if (limit > 0)
+			return limit;
+	}
+
 	if (!max_beb_per1024)
 		return 0;
 
-- 
2.4.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/3] mtd: nand: implement 'max_bad_blocks' mtd function
  2015-05-11 15:19 ` [PATCH 2/3] mtd: nand: implement 'max_bad_blocks' mtd function Ben Shelton
@ 2015-05-14  9:43   ` Richard Weinberger
  0 siblings, 0 replies; 5+ messages in thread
From: Richard Weinberger @ 2015-05-14  9:43 UTC (permalink / raw)
  To: Ben Shelton, dwmw2, computersforpeace, linux-mtd, linux-kernel,
	dedekind1
  Cc: Jeff Westfahl

Am 11.05.2015 um 17:19 schrieb Ben Shelton:
> From: Jeff Westfahl <jeff.westfahl@ni.com>
> 
> Implement the new mtd function 'max_bad_blocks'. Use the "bad blocks
> maximum per LUN" field in the ONFI parameter page to find the maximum
> number of bad blocks to reserve for an MTD, taking into account the
> number of LUNs in the NAND device and how many LUNs the MTD spans.
> 
> From the ONFI 1.0 spec: "This field contains the maximum number of
> blocks that may be defective at manufacture and over the life of the
> device per LUN. The maximum rating assumes that the host is following
> the block endurance requirements and the ECC requirements reported in
> the parameter page."
> 
> Signed-off-by: Jeff Westfahl <jeff.westfahl@ni.com>
> ---
>  drivers/mtd/nand/nand_base.c | 35 +++++++++++++++++++++++++++++++++++
>  1 file changed, 35 insertions(+)
> 
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index c2e1232..a97d08e 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -2884,6 +2884,40 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
>  }
>  
>  /**
> + * nand_max_bad_blocks - [MTD Interface] Max number of bad blocks for an mtd
> + * @mtd: MTD device structure
> + * @ofs: offset relative to mtd start
> + * @len: length of mtd
> + */
> +static int nand_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
> +{
> +	struct nand_chip *chip = mtd->priv;
> +	uint32_t part_start_block;
> +	uint32_t part_end_block;
> +	uint32_t part_start_lun;
> +	uint32_t part_end_lun;
> +
> +	/* ONFI is used to determine the maximum bad block count. */
> +	if (!chip->onfi_version)
> +		return -ENOTSUPP;
> +
> +	/* Get the start and end of the partition in erase blocks. */
> +	part_start_block = mtd_div_by_eb(ofs, mtd);
> +	part_end_block = mtd_div_by_eb(len, mtd) + part_start_block - 1;
> +
> +	/* Get the start and end LUNs of the partition. */
> +	part_start_lun = part_start_block / chip->onfi_params.blocks_per_lun;
> +	part_end_lun = part_end_block / chip->onfi_params.blocks_per_lun;
> +
> +	/*
> +	 * Look up the bad blocks per unit and multiply by the number of units
> +	 * that the partition spans.
> +	 */
> +	return chip->onfi_params.bb_per_lun *
> +		(part_end_lun - part_start_lun + 1);

Hmm, doesn't that calculation assume that all bad blocks are uniformly distributed across
the whole chip?
Not sure if is a good idea to focus on the best case. Currently UBI assumes the worst case.

Thanks,
//richard

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-05-14  9:43 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-11 15:19 [PATCH 0/3] mtd: use ONFI bad blocks per LUN to calculate UBIFS bad PEB limit Ben Shelton
2015-05-11 15:19 ` [PATCH 1/3] mtd: introduce function max_bad_blocks Ben Shelton
2015-05-11 15:19 ` [PATCH 2/3] mtd: nand: implement 'max_bad_blocks' mtd function Ben Shelton
2015-05-14  9:43   ` Richard Weinberger
2015-05-11 15:19 ` [PATCH 3/3] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit Ben Shelton

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.