linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit
@ 2016-11-21 19:51 Zach Brown
  2016-11-21 19:51 ` [RESEND PATCH v5 1/5] mtd: introduce function max_bad_blocks Zach Brown
                   ` (6 more replies)
  0 siblings, 7 replies; 15+ messages in thread
From: Zach Brown @ 2016-11-21 19:51 UTC (permalink / raw)
  To: dwmw2
  Cc: computersforpeace, boris.brezillon, richard, dedekind1,
	linux-mtd, linux-kernel

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 UBI bad PEB limit.

The ONFI parameter "maxiumum number of bad blocks per LUN" is the max number of
bad blocks that each individual LUN will ever ecounter. It is not the number of
bad blocks to reserve for the nand device per LUN in the device.

This means that in the worst case a UBI device spanning X LUNs will encounter
"maximum number of bad blocks per LUN" * X bad blocks. The implementation in
this patch assumes this worst case and allocates bad block accordingly.

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

v2:
 * Changed commit message to address concerns from v1[1] about this patch set
   making best case assumptions.
v3:
 * Provided helper function for _max_bad_blocks
 * Two new patches
 * First new patch adds bb_per_lun and blocks_per_lun to nand_chip struct
 * Second new patch sets the new fields during nand_flash_detect_onfi
 * Max bad blocks calculation now uses the new nand_chip fields
v4:
 * Changed bb_per_lun and blocks_per_lun to bb_per_die and blocks_per_die
 * Corrected type of bb_per_die and blocks_per_die from little endian to host
   unsigned int
v5:
 * Changed bb_per_die to max_bb_per_die
 * Fixed spacing style issue

[1]
http://lkml.iu.edu/hypermail/linux/kernel/1505.1/04822.html

Jeff Westfahl (2):
  mtd: introduce function max_bad_blocks
  mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available

Zach Brown (3):
  mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip
  mtd: nand: implement 'max_bad_blocks' mtd function
  mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant
    chips

 drivers/mtd/mtdpart.c        | 12 ++++++++++++
 drivers/mtd/nand/nand_base.c | 38 ++++++++++++++++++++++++++++++++++++++
 drivers/mtd/ubi/build.c      |  4 ++++
 include/linux/mtd/mtd.h      | 11 +++++++++++
 include/linux/mtd/nand.h     |  5 +++++
 5 files changed, 70 insertions(+)

-- 
2.7.4

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

* [RESEND PATCH v5 1/5] mtd: introduce function max_bad_blocks
  2016-11-21 19:51 [RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit Zach Brown
@ 2016-11-21 19:51 ` Zach Brown
  2016-11-22 18:48   ` Brian Norris
  2016-11-21 19:51 ` [RESEND PATCH v5 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available Zach Brown
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Zach Brown @ 2016-11-21 19:51 UTC (permalink / raw)
  To: dwmw2
  Cc: computersforpeace, boris.brezillon, richard, dedekind1,
	linux-mtd, linux-kernel

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

If implemented, 'max_bad_blocks' returns the maximum number of bad
blocks to reserve for an MTD. An implementation for NAND is coming soon.

Signed-off-by: Jeff Westfahl <jeff.westfahl@ni.com>
Signed-off-by: Zach Brown <zach.brown@ni.com>
Acked-by: Boris Brezillon <boris.brezillon@free-electron.com>
---
 drivers/mtd/mtdpart.c   | 12 ++++++++++++
 include/linux/mtd/mtd.h | 11 +++++++++++
 2 files changed, 23 insertions(+)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index fccdd49..565f0dd 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -349,6 +349,16 @@ static const struct mtd_ooblayout_ops part_ooblayout_ops = {
 	.free = part_ooblayout_free,
 };
 
+static int part_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+	struct mtd_part *part = mtd_to_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);
@@ -481,6 +491,8 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
 	if (master->_put_device)
 		slave->mtd._put_device = part_put_device;
 
+	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 13f8052..c02d3c2 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -322,6 +322,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);
@@ -402,6 +403,16 @@ int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int wunit,
 int mtd_pairing_info_to_wunit(struct mtd_info *mtd,
 			      const struct mtd_pairing_info *info);
 int mtd_pairing_groups(struct mtd_info *mtd);
+
+static inline int mtd_max_bad_blocks(struct mtd_info *mtd,
+				     loff_t ofs, size_t len)
+{
+	if (mtd->_max_bad_blocks)
+		return mtd->_max_bad_blocks(mtd, ofs, len);
+
+	return -ENOTSUPP;
+}
+
 int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
 int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
 	      void **virt, resource_size_t *phys);
-- 
2.7.4

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

* [RESEND PATCH v5 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available
  2016-11-21 19:51 [RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit Zach Brown
  2016-11-21 19:51 ` [RESEND PATCH v5 1/5] mtd: introduce function max_bad_blocks Zach Brown
@ 2016-11-21 19:51 ` Zach Brown
  2016-11-22 18:42   ` Brian Norris
  2016-11-22 18:50   ` Brian Norris
  2016-11-21 19:51 ` [RESEND PATCH v5 3/5] mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip Zach Brown
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 15+ messages in thread
From: Zach Brown @ 2016-11-21 19:51 UTC (permalink / raw)
  To: dwmw2
  Cc: computersforpeace, boris.brezillon, richard, dedekind1,
	linux-mtd, linux-kernel

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.

Signed-off-by: Jeff Westfahl <jeff.westfahl@ni.com>
Signed-off-by: Zach Brown <zach.brown@ni.com>
Acked-by: Boris Brezillon <boris.brezillon@free-electron.com>
---
 drivers/mtd/ubi/build.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 85d54f3..e9940a9 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -584,6 +584,10 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, int max_beb_per1024)
 	int limit, device_pebs;
 	uint64_t device_size;
 
+	limit = mtd_max_bad_blocks(ubi->mtd, 0, ubi->mtd->size);
+	if (limit > 0)
+		return limit;
+
 	if (!max_beb_per1024)
 		return 0;
 
-- 
2.7.4

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

* [RESEND PATCH v5 3/5] mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip
  2016-11-21 19:51 [RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit Zach Brown
  2016-11-21 19:51 ` [RESEND PATCH v5 1/5] mtd: introduce function max_bad_blocks Zach Brown
  2016-11-21 19:51 ` [RESEND PATCH v5 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available Zach Brown
@ 2016-11-21 19:51 ` Zach Brown
  2016-11-21 19:51 ` [RESEND PATCH v5 4/5] mtd: nand: implement 'max_bad_blocks' mtd function Zach Brown
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Zach Brown @ 2016-11-21 19:51 UTC (permalink / raw)
  To: dwmw2
  Cc: computersforpeace, boris.brezillon, richard, dedekind1,
	linux-mtd, linux-kernel

The fields max_bb_per_die and blocks_per_die are useful determining the
number of bad blocks a MTD needs to allocate. How they are set will
depend on if the chip is ONFI, JEDEC or a full-id entry in the nand_ids
table.

Signed-off-by: Zach Brown <zach.brown@ni.com>
Acked-by: Boris Brezillon <boris.brezillon@free-electron.com>
---
 include/linux/mtd/nand.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index d8905a2..8e9dce1 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -771,6 +771,9 @@ nand_get_sdr_timings(const struct nand_data_interface *conf)
  *			supported, 0 otherwise.
  * @jedec_params:	[INTERN] holds the JEDEC parameter page when JEDEC is
  *			supported, 0 otherwise.
+ * @max_bb_per_die:	[INTERN] the max number of bad blocks each die of a
+ *			this nand device will encounter their life times.
+ * @blocks_per_die:	[INTERN] The number of PEBs in a die
  * @read_retries:	[INTERN] the number of read retry modes supported
  * @onfi_set_features:	[REPLACEABLE] set the features for ONFI nand
  * @onfi_get_features:	[REPLACEABLE] get the features for ONFI nand
@@ -853,6 +856,8 @@ struct nand_chip {
 		struct nand_onfi_params	onfi_params;
 		struct nand_jedec_params jedec_params;
 	};
+	u16 max_bb_per_die;
+	u32 blocks_per_die;
 
 	struct nand_data_interface *data_interface;
 
-- 
2.7.4

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

* [RESEND PATCH v5 4/5] mtd: nand: implement 'max_bad_blocks' mtd function
  2016-11-21 19:51 [RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit Zach Brown
                   ` (2 preceding siblings ...)
  2016-11-21 19:51 ` [RESEND PATCH v5 3/5] mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip Zach Brown
@ 2016-11-21 19:51 ` Zach Brown
  2016-11-22 18:55   ` Brian Norris
  2016-11-21 19:51 ` [RESEND PATCH v5 5/5] mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant chips Zach Brown
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Zach Brown @ 2016-11-21 19:51 UTC (permalink / raw)
  To: dwmw2
  Cc: computersforpeace, boris.brezillon, richard, dedekind1,
	linux-mtd, linux-kernel

Implement the new mtd function 'max_bad_blocks'. Using the chip's
max_bb_per_die and blocks_per_die fields to determine the maximum bad
blocks to reserve for an MTD.

Signed-off-by: Jeff Westfahl <jeff.westfahl@ni.com>
Signed-off-by: Zach Brown <zach.brown@ni.com>
Acked-by: Boris Brezillon <boris.brezillon@free-electron.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 3bde96a..193a6b7 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3236,6 +3236,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_to_nand(mtd);
+	uint32_t part_start_block;
+	uint32_t part_end_block;
+	uint32_t part_start_lun;
+	uint32_t part_end_lun;
+
+	/* max_bb_per_lun and blocks_per_lun used to determine
+	 * the maximum bad block count.
+	 */
+	if (!chip->max_bb_per_die || !chip->blocks_per_die)
+		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->blocks_per_die;
+	part_end_lun = part_end_block / chip->blocks_per_die;
+
+	/* Look up the bad blocks per unit and multiply by the number of units
+	 * that the partition spans.
+	 */
+	return chip->max_bb_per_die * (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
@@ -4767,6 +4801,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;
 
 	/*
-- 
2.7.4

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

* [RESEND PATCH v5 5/5] mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant chips
  2016-11-21 19:51 [RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit Zach Brown
                   ` (3 preceding siblings ...)
  2016-11-21 19:51 ` [RESEND PATCH v5 4/5] mtd: nand: implement 'max_bad_blocks' mtd function Zach Brown
@ 2016-11-21 19:51 ` Zach Brown
  2016-11-22  9:37 ` [RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit Boris Brezillon
  2016-11-22 18:58 ` Brian Norris
  6 siblings, 0 replies; 15+ messages in thread
From: Zach Brown @ 2016-11-21 19:51 UTC (permalink / raw)
  To: dwmw2
  Cc: computersforpeace, boris.brezillon, richard, dedekind1,
	linux-mtd, linux-kernel

ONFI compliant chips contain the values for the max_bb_per_die and
blocks_per_die fields in the parameter page. When the ONFI paged is
retrieved/parsed the chip's fields are set by the corresponding fields
in the param page.

Signed-off-by: Zach Brown <zach.brown@ni.com>
Acked-by: Boris Brezillon <boris.brezillon@free-electron.com>
---
 drivers/mtd/nand/nand_base.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 193a6b7..fb5b585 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3599,6 +3599,9 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
 	chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
 	chip->bits_per_cell = p->bits_per_cell;
 
+	chip->max_bb_per_die = le16_to_cpu(p->bb_per_lun);
+	chip->blocks_per_die = le32_to_cpu(p->blocks_per_lun);
+
 	if (onfi_feature(chip) & ONFI_FEATURE_16_BIT_BUS)
 		*busw = NAND_BUSWIDTH_16;
 	else
-- 
2.7.4

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

* Re: [RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit
  2016-11-21 19:51 [RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit Zach Brown
                   ` (4 preceding siblings ...)
  2016-11-21 19:51 ` [RESEND PATCH v5 5/5] mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant chips Zach Brown
@ 2016-11-22  9:37 ` Boris Brezillon
  2016-11-22  9:53   ` Richard Weinberger
  2016-11-22 18:58 ` Brian Norris
  6 siblings, 1 reply; 15+ messages in thread
From: Boris Brezillon @ 2016-11-22  9:37 UTC (permalink / raw)
  To: Zach Brown
  Cc: dwmw2, dedekind1, richard, linux-kernel, linux-mtd, computersforpeace

Hi Zach,

Please do not resend a patch series so quickly (a simple ping is
enough).
BTW, I already asked Richard and Brian to have a look, let's wait a bit.

On Mon, 21 Nov 2016 13:51:34 -0600
Zach Brown <zach.brown@ni.com> wrote:

> 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 UBI bad PEB limit.
> 
> The ONFI parameter "maxiumum number of bad blocks per LUN" is the max number of
> bad blocks that each individual LUN will ever ecounter. It is not the number of
> bad blocks to reserve for the nand device per LUN in the device.
> 
> This means that in the worst case a UBI device spanning X LUNs will encounter
> "maximum number of bad blocks per LUN" * X bad blocks. The implementation in
> this patch assumes this worst case and allocates bad block accordingly.
> 
> These patches are ordered in terms of their dependencies, but ideally, all 5
> would need to be applied for this to work as intended.
> 
> v2:
>  * Changed commit message to address concerns from v1[1] about this patch set
>    making best case assumptions.
> v3:
>  * Provided helper function for _max_bad_blocks
>  * Two new patches
>  * First new patch adds bb_per_lun and blocks_per_lun to nand_chip struct
>  * Second new patch sets the new fields during nand_flash_detect_onfi
>  * Max bad blocks calculation now uses the new nand_chip fields
> v4:
>  * Changed bb_per_lun and blocks_per_lun to bb_per_die and blocks_per_die
>  * Corrected type of bb_per_die and blocks_per_die from little endian to host
>    unsigned int
> v5:
>  * Changed bb_per_die to max_bb_per_die
>  * Fixed spacing style issue
> 
> [1]
> http://lkml.iu.edu/hypermail/linux/kernel/1505.1/04822.html
> 
> Jeff Westfahl (2):
>   mtd: introduce function max_bad_blocks
>   mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available
> 
> Zach Brown (3):
>   mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip
>   mtd: nand: implement 'max_bad_blocks' mtd function
>   mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant
>     chips
> 
>  drivers/mtd/mtdpart.c        | 12 ++++++++++++
>  drivers/mtd/nand/nand_base.c | 38 ++++++++++++++++++++++++++++++++++++++
>  drivers/mtd/ubi/build.c      |  4 ++++
>  include/linux/mtd/mtd.h      | 11 +++++++++++
>  include/linux/mtd/nand.h     |  5 +++++
>  5 files changed, 70 insertions(+)
> 

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

* Re: [RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit
  2016-11-22  9:37 ` [RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit Boris Brezillon
@ 2016-11-22  9:53   ` Richard Weinberger
  0 siblings, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2016-11-22  9:53 UTC (permalink / raw)
  To: Boris Brezillon, Zach Brown
  Cc: dwmw2, dedekind1, linux-kernel, linux-mtd, computersforpeace

Hi!

On 22.11.2016 10:37, Boris Brezillon wrote:
> Hi Zach,
> 
> Please do not resend a patch series so quickly (a simple ping is
> enough).
> BTW, I already asked Richard and Brian to have a look, let's wait a bit.

It is on my TODO. Since I'm travelling I'm slow with reviewing.

Thanks,
//richard

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

* Re: [RESEND PATCH v5 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available
  2016-11-21 19:51 ` [RESEND PATCH v5 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available Zach Brown
@ 2016-11-22 18:42   ` Brian Norris
  2016-11-25 13:37     ` Richard Weinberger
  2016-11-22 18:50   ` Brian Norris
  1 sibling, 1 reply; 15+ messages in thread
From: Brian Norris @ 2016-11-22 18:42 UTC (permalink / raw)
  To: Zach Brown
  Cc: dwmw2, boris.brezillon, richard, dedekind1, linux-mtd, linux-kernel

On Mon, Nov 21, 2016 at 01:51:36PM -0600, Zach Brown wrote:
> 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.

I'm not exactly a UBI expert here, but it seems reasonable that we
should adjust the Kconfig documentation for MTD_UBI_BEB_LIMIT to further
emphasize that it's a default, if the value can't be determined by other
means.

> Signed-off-by: Jeff Westfahl <jeff.westfahl@ni.com>
> Signed-off-by: Zach Brown <zach.brown@ni.com>
> Acked-by: Boris Brezillon <boris.brezillon@free-electron.com>
> ---
>  drivers/mtd/ubi/build.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
> index 85d54f3..e9940a9 100644
> --- a/drivers/mtd/ubi/build.c
> +++ b/drivers/mtd/ubi/build.c
> @@ -584,6 +584,10 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, int max_beb_per1024)
>  	int limit, device_pebs;
>  	uint64_t device_size;
>  
> +	limit = mtd_max_bad_blocks(ubi->mtd, 0, ubi->mtd->size);
> +	if (limit > 0)
> +		return limit;

Are you sure you want to even override the user-provided
max_beb_per1024 value taken from the mtd= line? I'd think if someone
went as far as to specify this in the kernel command line, they don't
expect it to get overridden. Just my two cents.

Brian

> +
>  	if (!max_beb_per1024)
>  		return 0;
>  
> -- 
> 2.7.4
> 

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

* Re: [RESEND PATCH v5 1/5] mtd: introduce function max_bad_blocks
  2016-11-21 19:51 ` [RESEND PATCH v5 1/5] mtd: introduce function max_bad_blocks Zach Brown
@ 2016-11-22 18:48   ` Brian Norris
  0 siblings, 0 replies; 15+ messages in thread
From: Brian Norris @ 2016-11-22 18:48 UTC (permalink / raw)
  To: Zach Brown
  Cc: dwmw2, boris.brezillon, richard, dedekind1, linux-mtd, linux-kernel

A few small comments.

On Mon, Nov 21, 2016 at 01:51:35PM -0600, Zach Brown wrote:
> From: Jeff Westfahl <jeff.westfahl@ni.com>
> 
> If implemented, 'max_bad_blocks' returns the maximum number of bad
> blocks to reserve for an MTD. An implementation for NAND is coming soon.
> 
> Signed-off-by: Jeff Westfahl <jeff.westfahl@ni.com>
> Signed-off-by: Zach Brown <zach.brown@ni.com>
> Acked-by: Boris Brezillon <boris.brezillon@free-electron.com>
> ---
>  drivers/mtd/mtdpart.c   | 12 ++++++++++++
>  include/linux/mtd/mtd.h | 11 +++++++++++
>  2 files changed, 23 insertions(+)
> 
> diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
> index fccdd49..565f0dd 100644
> --- a/drivers/mtd/mtdpart.c
> +++ b/drivers/mtd/mtdpart.c
> @@ -349,6 +349,16 @@ static const struct mtd_ooblayout_ops part_ooblayout_ops = {
>  	.free = part_ooblayout_free,
>  };
>  
> +static int part_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
> +{
> +	struct mtd_part *part = mtd_to_part(mtd);
> +
> +	if ((len + ofs) > mtd->size)
> +		return -EINVAL;

Normally you want the bounds checking in the top-level API, and that
should be enough for the partitions as well. Also, what about 'ofs < 0'?

> +	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);
> @@ -481,6 +491,8 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
>  	if (master->_put_device)
>  		slave->mtd._put_device = part_put_device;
>  
> +	if (master->_max_bad_blocks)
> +		slave->mtd._max_bad_blocks = part_max_bad_blocks;

Nit: add an extra blank line after? Also might make sense to stick this
up with the other bad-block-related assignments (after _block_markbad =
...).

>  	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 13f8052..c02d3c2 100644
> --- a/include/linux/mtd/mtd.h
> +++ b/include/linux/mtd/mtd.h
> @@ -322,6 +322,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);
> @@ -402,6 +403,16 @@ int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int wunit,
>  int mtd_pairing_info_to_wunit(struct mtd_info *mtd,
>  			      const struct mtd_pairing_info *info);
>  int mtd_pairing_groups(struct mtd_info *mtd);
> +
> +static inline int mtd_max_bad_blocks(struct mtd_info *mtd,
> +				     loff_t ofs, size_t len)
> +{

Bounds checks here?

Brian

> +	if (mtd->_max_bad_blocks)
> +		return mtd->_max_bad_blocks(mtd, ofs, len);
> +
> +	return -ENOTSUPP;
> +}
> +
>  int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
>  int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
>  	      void **virt, resource_size_t *phys);
> -- 
> 2.7.4
> 

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

* Re: [RESEND PATCH v5 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available
  2016-11-21 19:51 ` [RESEND PATCH v5 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available Zach Brown
  2016-11-22 18:42   ` Brian Norris
@ 2016-11-22 18:50   ` Brian Norris
  1 sibling, 0 replies; 15+ messages in thread
From: Brian Norris @ 2016-11-22 18:50 UTC (permalink / raw)
  To: Zach Brown
  Cc: dwmw2, boris.brezillon, richard, dedekind1, linux-mtd, linux-kernel

On Mon, Nov 21, 2016 at 01:51:36PM -0600, Zach Brown wrote:
> 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.
> 
> Signed-off-by: Jeff Westfahl <jeff.westfahl@ni.com>
> Signed-off-by: Zach Brown <zach.brown@ni.com>
> Acked-by: Boris Brezillon <boris.brezillon@free-electron.com>
> ---
>  drivers/mtd/ubi/build.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
> index 85d54f3..e9940a9 100644
> --- a/drivers/mtd/ubi/build.c
> +++ b/drivers/mtd/ubi/build.c
> @@ -584,6 +584,10 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, int max_beb_per1024)
>  	int limit, device_pebs;
>  	uint64_t device_size;
>  
> +	limit = mtd_max_bad_blocks(ubi->mtd, 0, ubi->mtd->size);
> +	if (limit > 0)

I guess we're assuming 0 is an erroneous value? Otherwise, why would
mtd_can_have_bb() be true?

Brian

> +		return limit;
> +
>  	if (!max_beb_per1024)
>  		return 0;
>  
> -- 
> 2.7.4
> 

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

* Re: [RESEND PATCH v5 4/5] mtd: nand: implement 'max_bad_blocks' mtd function
  2016-11-21 19:51 ` [RESEND PATCH v5 4/5] mtd: nand: implement 'max_bad_blocks' mtd function Zach Brown
@ 2016-11-22 18:55   ` Brian Norris
  0 siblings, 0 replies; 15+ messages in thread
From: Brian Norris @ 2016-11-22 18:55 UTC (permalink / raw)
  To: Zach Brown
  Cc: dwmw2, boris.brezillon, richard, dedekind1, linux-mtd, linux-kernel

On Mon, Nov 21, 2016 at 01:51:38PM -0600, Zach Brown wrote:
> Implement the new mtd function 'max_bad_blocks'. Using the chip's
> max_bb_per_die and blocks_per_die fields to determine the maximum bad
> blocks to reserve for an MTD.
> 
> Signed-off-by: Jeff Westfahl <jeff.westfahl@ni.com>
> Signed-off-by: Zach Brown <zach.brown@ni.com>
> Acked-by: Boris Brezillon <boris.brezillon@free-electron.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 3bde96a..193a6b7 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -3236,6 +3236,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_to_nand(mtd);
> +	uint32_t part_start_block;
> +	uint32_t part_end_block;
> +	uint32_t part_start_lun;
> +	uint32_t part_end_lun;
> +
> +	/* max_bb_per_lun and blocks_per_lun used to determine
> +	 * the maximum bad block count.
> +	 */

This is not the right multi-line comment style.

/*
 * Use something more like this, where the first line has only the
 * comment opening.
 */

> +	if (!chip->max_bb_per_die || !chip->blocks_per_die)
> +		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->blocks_per_die;
> +	part_end_lun = part_end_block / chip->blocks_per_die;
> +
> +	/* Look up the bad blocks per unit and multiply by the number of units
> +	 * that the partition spans.
> +	 */

Same.

Brian

> +	return chip->max_bb_per_die * (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
> @@ -4767,6 +4801,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;
>  
>  	/*
> -- 
> 2.7.4
> 

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

* Re: [RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit
  2016-11-21 19:51 [RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit Zach Brown
                   ` (5 preceding siblings ...)
  2016-11-22  9:37 ` [RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit Boris Brezillon
@ 2016-11-22 18:58 ` Brian Norris
  6 siblings, 0 replies; 15+ messages in thread
From: Brian Norris @ 2016-11-22 18:58 UTC (permalink / raw)
  To: Zach Brown
  Cc: dwmw2, boris.brezillon, richard, dedekind1, linux-mtd, linux-kernel

On Mon, Nov 21, 2016 at 01:51:34PM -0600, Zach Brown wrote:
> 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 UBI bad PEB limit.
> 
> The ONFI parameter "maxiumum number of bad blocks per LUN" is the max number of
> bad blocks that each individual LUN will ever ecounter. It is not the number of
> bad blocks to reserve for the nand device per LUN in the device.
> 
> This means that in the worst case a UBI device spanning X LUNs will encounter
> "maximum number of bad blocks per LUN" * X bad blocks. The implementation in
> this patch assumes this worst case and allocates bad block accordingly.
> 
> These patches are ordered in terms of their dependencies, but ideally, all 5
> would need to be applied for this to work as intended.

Other than some small comments, the MTD parts look fine to me. For
patches 1, 3, 4, and 5 with my comments fixed:

Acked-by: Brian Norris <computersforpeace@gmail.com>

For the UBI part, I wasn't quite sure about the precedence among the 3
possible ways to determine the appropriate value. I'll leave that up to
Richard, et al, though.

Brian

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

* Re: [RESEND PATCH v5 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available
  2016-11-22 18:42   ` Brian Norris
@ 2016-11-25 13:37     ` Richard Weinberger
  2016-11-25 14:03       ` Richard Weinberger
  0 siblings, 1 reply; 15+ messages in thread
From: Richard Weinberger @ 2016-11-25 13:37 UTC (permalink / raw)
  To: Brian Norris, Zach Brown
  Cc: dwmw2, boris.brezillon, dedekind1, linux-mtd, linux-kernel

Zach, Brian,

sorry for the late review.

On 22.11.2016 19:42, Brian Norris wrote:
> On Mon, Nov 21, 2016 at 01:51:36PM -0600, Zach Brown wrote:
>> 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.
> 
> I'm not exactly a UBI expert here, but it seems reasonable that we
> should adjust the Kconfig documentation for MTD_UBI_BEB_LIMIT to further
> emphasize that it's a default, if the value can't be determined by other
> means.
> 
>> Signed-off-by: Jeff Westfahl <jeff.westfahl@ni.com>
>> Signed-off-by: Zach Brown <zach.brown@ni.com>
>> Acked-by: Boris Brezillon <boris.brezillon@free-electron.com>
>> ---
>>  drivers/mtd/ubi/build.c | 4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
>> index 85d54f3..e9940a9 100644
>> --- a/drivers/mtd/ubi/build.c
>> +++ b/drivers/mtd/ubi/build.c
>> @@ -584,6 +584,10 @@ static int get_bad_peb_limit(const struct ubi_device *ubi, int max_beb_per1024)
>>  	int limit, device_pebs;
>>  	uint64_t device_size;
>>  
>> +	limit = mtd_max_bad_blocks(ubi->mtd, 0, ubi->mtd->size);
>> +	if (limit > 0)
>> +		return limit;
> 
> Are you sure you want to even override the user-provided
> max_beb_per1024 value taken from the mtd= line? I'd think if someone
> went as far as to specify this in the kernel command line, they don't
> expect it to get overridden. Just my two cents.

I agree. With this patch applied the limit can be set via Kconfig, cmdline and automatically.
IMHO the automatic value via mtd_max_bad_blocks and over-writeable via cmdline and Kconfig.
...and this needs to be documented. :-)
I'd go so far and suggest dropping the Kconfig option.

Thanks,
//richard

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

* Re: [RESEND PATCH v5 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available
  2016-11-25 13:37     ` Richard Weinberger
@ 2016-11-25 14:03       ` Richard Weinberger
  0 siblings, 0 replies; 15+ messages in thread
From: Richard Weinberger @ 2016-11-25 14:03 UTC (permalink / raw)
  To: Brian Norris, Zach Brown
  Cc: dwmw2, boris.brezillon, dedekind1, linux-mtd, linux-kernel

On 25.11.2016 14:37, Richard Weinberger wrote:
>> Are you sure you want to even override the user-provided
>> max_beb_per1024 value taken from the mtd= line? I'd think if someone
>> went as far as to specify this in the kernel command line, they don't
>> expect it to get overridden. Just my two cents.
> 
> I agree. With this patch applied the limit can be set via Kconfig, cmdline and automatically.
> IMHO the automatic value via mtd_max_bad_blocks and over-writeable via cmdline and Kconfig.

s/and/should be/

Thanks,
//richard

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

end of thread, other threads:[~2016-11-25 14:03 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-21 19:51 [RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit Zach Brown
2016-11-21 19:51 ` [RESEND PATCH v5 1/5] mtd: introduce function max_bad_blocks Zach Brown
2016-11-22 18:48   ` Brian Norris
2016-11-21 19:51 ` [RESEND PATCH v5 2/5] mtd: ubi: use 'max_bad_blocks' to compute bad_peb_limit if available Zach Brown
2016-11-22 18:42   ` Brian Norris
2016-11-25 13:37     ` Richard Weinberger
2016-11-25 14:03       ` Richard Weinberger
2016-11-22 18:50   ` Brian Norris
2016-11-21 19:51 ` [RESEND PATCH v5 3/5] mtd: nand: Add max_bb_per_die and blocks_per_die fields to nand_chip Zach Brown
2016-11-21 19:51 ` [RESEND PATCH v5 4/5] mtd: nand: implement 'max_bad_blocks' mtd function Zach Brown
2016-11-22 18:55   ` Brian Norris
2016-11-21 19:51 ` [RESEND PATCH v5 5/5] mtd: nand: set max_bb_per_die and blocks_per_die for ONFI compliant chips Zach Brown
2016-11-22  9:37 ` [RESEND PATCH v5 0/5] mtd: use ONFI bad blocks per LUN to calculate UBI bad PEB limit Boris Brezillon
2016-11-22  9:53   ` Richard Weinberger
2016-11-22 18:58 ` Brian Norris

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).