2021-12-20 13:00:25

by Sean Nyekjaer

[permalink] [raw]
Subject: [PATCH] mtd: rawnand: protect access to rawnand devices while in suspend

Prevent rawnend access while in a suspended state.

Commit 013e6292aaf5 ("mtd: rawnand: Simplify the locking") allows the
rawnand layer to return errors rather than waiting in a blocking wait.

Tested on a iMX6ULL.

Fixes: 013e6292aaf5 ("mtd: rawnand: Simplify the locking")
Signed-off-by: Sean Nyekjaer <[email protected]>
---
Follow-up on discussion in:
https://lkml.org/lkml/2021/10/4/41
https://lkml.org/lkml/2021/10/11/435
https://lkml.org/lkml/2021/10/20/184
https://lkml.org/lkml/2021/10/25/288
https://lkml.org/lkml/2021/10/26/55
https://lkml.org/lkml/2021/11/2/352

drivers/mtd/nand/raw/nand_base.c | 42 +++++++++++++++-----------------
include/linux/mtd/rawnand.h | 1 +
2 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index b3a9bc08b4bb..eb4ec9a42d49 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -338,16 +338,19 @@ static int nand_isbad_bbm(struct nand_chip *chip, loff_t ofs)
*
* Return: -EBUSY if the chip has been suspended, 0 otherwise
*/
-static int nand_get_device(struct nand_chip *chip)
+static void nand_get_device(struct nand_chip *chip)
{
- mutex_lock(&chip->lock);
- if (chip->suspended) {
+ /* Wait until the device is resumed. */
+ while (1) {
+ mutex_lock(&chip->lock);
+ if (!chip->suspended) {
+ mutex_lock(&chip->controller->lock);
+ return;
+ }
mutex_unlock(&chip->lock);
- return -EBUSY;
- }
- mutex_lock(&chip->controller->lock);

- return 0;
+ wait_event(chip->resume_wq, !chip->suspended);
+ }
}

/**
@@ -576,9 +579,7 @@ static int nand_block_markbad_lowlevel(struct nand_chip *chip, loff_t ofs)
nand_erase_nand(chip, &einfo, 0);

/* Write bad block marker to OOB */
- ret = nand_get_device(chip);
- if (ret)
- return ret;
+ nand_get_device(chip);

ret = nand_markbad_bbm(chip, ofs);
nand_release_device(chip);
@@ -3759,9 +3760,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
ops->mode != MTD_OPS_RAW)
return -ENOTSUPP;

- ret = nand_get_device(chip);
- if (ret)
- return ret;
+ nand_get_device(chip);

if (!ops->datbuf)
ret = nand_do_read_oob(chip, from, ops);
@@ -4352,9 +4351,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,

ops->retlen = 0;

- ret = nand_get_device(chip);
- if (ret)
- return ret;
+ nand_get_device(chip);

switch (ops->mode) {
case MTD_OPS_PLACE_OOB:
@@ -4414,9 +4411,7 @@ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr,
return -EIO;

/* Grab the lock and see if the device is available */
- ret = nand_get_device(chip);
- if (ret)
- return ret;
+ nand_get_device(chip);

/* Shift to get first page */
page = (int)(instr->addr >> chip->page_shift);
@@ -4503,7 +4498,7 @@ static void nand_sync(struct mtd_info *mtd)
pr_debug("%s: called\n", __func__);

/* Grab the lock and see if the device is available */
- WARN_ON(nand_get_device(chip));
+ nand_get_device(chip);
/* Release it and go back */
nand_release_device(chip);
}
@@ -4520,9 +4515,7 @@ static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
int ret;

/* Select the NAND device */
- ret = nand_get_device(chip);
- if (ret)
- return ret;
+ nand_get_device(chip);

nand_select_target(chip, chipnr);

@@ -4593,6 +4586,8 @@ static void nand_resume(struct mtd_info *mtd)
__func__);
}
mutex_unlock(&chip->lock);
+
+ wake_up_all(&chip->resume_wq);
}

/**
@@ -5370,6 +5365,7 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
chip->cur_cs = -1;

mutex_init(&chip->lock);
+ init_waitqueue_head(&chip->resume_wq);

/* Enforce the right timings for reset/detection */
chip->current_interface_config = nand_get_reset_interface_config();
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index b2f9dd3cbd69..248054560581 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1294,6 +1294,7 @@ struct nand_chip {
/* Internals */
struct mutex lock;
unsigned int suspended : 1;
+ wait_queue_head_t resume_wq;
int cur_cs;
int read_retries;
struct nand_secure_region *secure_regions;
--
2.34.1



2021-12-20 18:55:23

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] mtd: rawnand: protect access to rawnand devices while in suspend

Hi Sean,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on mtd/nand/next]
[also build test WARNING on linux/master linus/master v5.16-rc6 next-20211220]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Sean-Nyekjaer/mtd-rawnand-protect-access-to-rawnand-devices-while-in-suspend/20211220-210300
base: https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next
config: mips-randconfig-r002-20211220 (https://download.01.org/0day-ci/archive/20211221/[email protected]/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 555eacf75f21cd1dfc6363d73ad187b730349543)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install mips cross compiling tool for clang build
# apt-get install binutils-mips-linux-gnu
# https://github.com/0day-ci/linux/commit/4820bae9bf9bca82933f29066b18ea85f8c06178
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Sean-Nyekjaer/mtd-rawnand-protect-access-to-rawnand-devices-while-in-suspend/20211220-210300
git checkout 4820bae9bf9bca82933f29066b18ea85f8c06178
# save the config file to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=mips SHELL=/bin/bash drivers/mtd/nand/raw/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

>> drivers/mtd/nand/raw/nand_base.c:4426:2: warning: variable 'ret' is used uninitialized whenever switch default is taken [-Wsometimes-uninitialized]
default:
^~~~~~~
drivers/mtd/nand/raw/nand_base.c:4437:9: note: uninitialized use occurs here
return ret;
^~~
drivers/mtd/nand/raw/nand_base.c:4414:9: note: initialize the variable 'ret' to silence this warning
int ret;
^
= 0
1 warning generated.


vim +/ret +4426 drivers/mtd/nand/raw/nand_base.c

2af7c653993199 drivers/mtd/nand/nand_base.c Simon Kagstrom 2009-10-05 4403
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4404 /**
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4405 * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4406 * @mtd: MTD device structure
844d3b427ef1a4 drivers/mtd/nand/nand_base.c Randy Dunlap 2006-06-28 4407 * @to: offset to write to
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4408 * @ops: oob operation description structure
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4409 */
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4410 static int nand_write_oob(struct mtd_info *mtd, loff_t to,
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4411 struct mtd_oob_ops *ops)
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4412 {
0813621ba898aa drivers/mtd/nand/raw/nand_base.c Boris Brezillon 2018-11-11 4413 struct nand_chip *chip = mtd_to_nand(mtd);
80107e764846a6 drivers/mtd/nand/raw/nand_base.c Colin Ian King 2019-07-31 4414 int ret;
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4415
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4416 ops->retlen = 0;
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4417
4820bae9bf9bca drivers/mtd/nand/raw/nand_base.c Sean Nyekjaer 2021-12-20 4418 nand_get_device(chip);
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4419
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4420 switch (ops->mode) {
0612b9ddc2eeda drivers/mtd/nand/nand_base.c Brian Norris 2011-08-30 4421 case MTD_OPS_PLACE_OOB:
0612b9ddc2eeda drivers/mtd/nand/nand_base.c Brian Norris 2011-08-30 4422 case MTD_OPS_AUTO_OOB:
0612b9ddc2eeda drivers/mtd/nand/nand_base.c Brian Norris 2011-08-30 4423 case MTD_OPS_RAW:
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4424 break;
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4425
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 @4426 default:
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4427 goto out;
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4428 }
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4429
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4430 if (!ops->datbuf)
0813621ba898aa drivers/mtd/nand/raw/nand_base.c Boris Brezillon 2018-11-11 4431 ret = nand_do_write_oob(chip, to, ops);
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4432 else
0813621ba898aa drivers/mtd/nand/raw/nand_base.c Boris Brezillon 2018-11-11 4433 ret = nand_do_write_ops(chip, to, ops);
8593fbc68b0df1 drivers/mtd/nand/nand_base.c Thomas Gleixner 2006-05-29 4434
^1da177e4c3f41 drivers/mtd/nand/nand_base.c Linus Torvalds 2005-04-16 4435 out:
0813621ba898aa drivers/mtd/nand/raw/nand_base.c Boris Brezillon 2018-11-11 4436 nand_release_device(chip);
^1da177e4c3f41 drivers/mtd/nand/nand_base.c Linus Torvalds 2005-04-16 4437 return ret;
^1da177e4c3f41 drivers/mtd/nand/nand_base.c Linus Torvalds 2005-04-16 4438 }
^1da177e4c3f41 drivers/mtd/nand/nand_base.c Linus Torvalds 2005-04-16 4439

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]

2022-01-17 16:00:01

by Sean Nyekjaer

[permalink] [raw]
Subject: Re: [PATCH] mtd: rawnand: protect access to rawnand devices while in suspend

On Mon, Dec 20, 2021 at 02:00:15PM +0100, Sean Nyekjaer wrote:
> Prevent rawnend access while in a suspended state.
>
> Commit 013e6292aaf5 ("mtd: rawnand: Simplify the locking") allows the
> rawnand layer to return errors rather than waiting in a blocking wait.
>
> Tested on a iMX6ULL.
>
> Fixes: 013e6292aaf5 ("mtd: rawnand: Simplify the locking")
> Signed-off-by: Sean Nyekjaer <[email protected]>
> ---

Hi Boris and Miquel,

I know the kernel test robot is complaining a bit about uninitialized
values.
But is this OK? If I fix the unitialized values?

/Sean

2022-01-17 16:41:49

by Boris Brezillon

[permalink] [raw]
Subject: Re: [PATCH] mtd: rawnand: protect access to rawnand devices while in suspend

On Mon, 17 Jan 2022 08:43:39 +0100
Sean Nyekjaer <[email protected]> wrote:

> On Mon, Dec 20, 2021 at 02:00:15PM +0100, Sean Nyekjaer wrote:
> > Prevent rawnend access while in a suspended state.
> >
> > Commit 013e6292aaf5 ("mtd: rawnand: Simplify the locking") allows the
> > rawnand layer to return errors rather than waiting in a blocking wait.
> >
> > Tested on a iMX6ULL.
> >
> > Fixes: 013e6292aaf5 ("mtd: rawnand: Simplify the locking")
> > Signed-off-by: Sean Nyekjaer <[email protected]>
> > ---
>
> Hi Boris and Miquel,
>
> I know the kernel test robot is complaining a bit about uninitialized
> values.
> But is this OK? If I fix the unitialized values?

With the 'uninitialized ret' issue fixed, it looks good to me:

Reviewed-by: Boris Brezillon <[email protected]>

But you probably want to add a Cc:stable tag.