From: Boris Brezillon <boris.brezillon@free-electrons.com>
To: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: linux-mtd@lists.infradead.org,
David Woodhouse <dwmw2@infradead.org>,
Marek Vasut <marek.vasut@gmail.com>,
Brian Norris <computersforpeace@gmail.com>,
thorsten.christiansson@idquantique.com,
laurent.monat@idquantique.com, Dinh Nguyen <dinguyen@kernel.org>,
Artem Bityutskiy <artem.bityutskiy@linux.intel.com>,
Graham Moore <grmoore@opensource.altera.com>,
Enrico Jorns <ejo@pengutronix.de>,
Chuanxiao Dong <chuanxiao.dong@intel.com>,
Masami Hiramatsu <mhiramat@kernel.org>,
Jassi Brar <jaswinder.singh@linaro.org>,
Rob Herring <robh@kernel.org>
Subject: Re: [RESEND PATCH v2 50/53] mtd: nand: allocate aligned buffers if NAND_OWN_BUFFERS is unset
Date: Mon, 27 Mar 2017 10:00:39 +0200 [thread overview]
Message-ID: <20170327100039.480b8d8d@bbrezillon> (raw)
In-Reply-To: <1490228282-10805-24-git-send-email-yamada.masahiro@socionext.com>
Hi Masahiro,
On Thu, 23 Mar 2017 09:17:59 +0900
Masahiro Yamada <yamada.masahiro@socionext.com> wrote:
> Commit 66507c7bc889 ("mtd: nand: Add support to use nand_base poi
> databuf as bounce buffer") fixed the issue that drivers can be
> passed with a kmap()'d buffer. This addressed the use_bufpoi = 0
> case.
>
> When use_bufpoi = 1, chip->buffers->databuf is used. The databuf
> allocated by nand_scan_tail() is not suitable for DMA due to the
> offset, sizeof(*chip->buffers).
As said earlier, I'm fine with the patch content, but I'm not sure
about your explanation. Alignment requirements are DMA controller
dependent so you're not exactly fixing a bug for all NAND controller
drivers, just those that require >4 bytes alignment.
Regarding the cache line alignment issue, in this case it shouldn't be
a problem, because the driver and the core shouldn't touch the
chip->buffers object during a DMA transfer, so dma_map/unmap_single()
should work fine (they may flush/invalidate one cache line entry that
contains non-payload data, but that's not a problem as long as nothing
is modified during the DMA transfer).
>
> So, drivers using DMA are very likely to end up with setting the
> NAND_OWN_BUFFERS flag and allocate buffers by themselves. Drivers
> tend to use devm_k*alloc to simplify the probe failure path, but
> devm_k*alloc() does not return a cache line aligned buffer.
Oh, I didn't know that. I had a closer look at the code, and indeed,
devm_kmalloc() does not guarantee any alignment.
>
> If used, it could violate the DMA-API requirement stated in
> Documentation/DMA-API.txt:
> Warnings: Memory coherency operates at a granularity called the
> cache line width. In order for memory mapped by this API to
> operate correctly, the mapped region must begin exactly on a cache
> line boundary and end exactly on one (to prevent two separately
> mapped regions from sharing a single cache line).
>
> To sum up, NAND_OWN_BUFFERS is not very convenient for drivers.
> nand_scan_tail() can give a separate buffer for each of ecccalc,
> ecccode, databuf. It is guaranteed kmalloc'ed memory is aligned
> with ARCH_DMA_MINALIGN.
Maybe I'm wrong, but AFAIU, kmalloc&co do not guarantee cache line
alignment for small buffers (< cache line), so even kmalloc can return
a buffer that is not cache line aligned.
This being said, we should be good because most NAND controllers are
only manipulating the page buffer (->databuf) which is large enough to
be cache line aligned.
Anyway, I'm not discussing the need for this patch, just the reasons we
need it ;-).
To me, it's more that we want to support as many cases as possible, no
matter the DMA controller requirements, and allocating each buffer
independently allows us to do that for almost no overhead.
How about simplifying the commit message to only focus on what this
patch is really fixing/improving?
"
Some NAND controllers are using DMA engine requiring a specific buffer
alignment. The core provides no guarantee on the nand_buffers pointers,
which forces some drivers to allocate their own buffers and pass the
NAND_OWN_BUFFERS flag.
Rework the nand_buffers allocation logic to allocate each buffer
independently. This should make most NAND controllers/DMA engine
happy, and allow us to get rid of these custom buf allocation in NAND
controller drivers.
"
> This is enough for most drivers because
> it is rare that DMA engines require larger alignment than CPU's
> cache line.
>
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
> ---
>
> Changes in v2:
> - Newly added
>
> drivers/mtd/nand/nand_base.c | 34 +++++++++++++++++++++++++++-------
> 1 file changed, 27 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> index e13f959..6fc0422 100644
> --- a/drivers/mtd/nand/nand_base.c
> +++ b/drivers/mtd/nand/nand_base.c
> @@ -4614,13 +4614,25 @@ int nand_scan_tail(struct mtd_info *mtd)
> }
>
> if (!(chip->options & NAND_OWN_BUFFERS)) {
> - nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize
> - + mtd->oobsize * 3, GFP_KERNEL);
> + nbuf = kzalloc(sizeof(*nbuf), GFP_KERNEL);
> if (!nbuf)
> return -ENOMEM;
> - nbuf->ecccalc = (uint8_t *)(nbuf + 1);
> - nbuf->ecccode = nbuf->ecccalc + mtd->oobsize;
> - nbuf->databuf = nbuf->ecccode + mtd->oobsize;
> + nbuf->ecccalc = kmalloc(mtd->oobsize, GFP_KERNEL);
> + if (!nbuf->ecccalc) {
> + ret = -EINVAL;
> + goto err_free;
> + }
> + nbuf->ecccode = kmalloc(mtd->oobsize, GFP_KERNEL);
> + if (!nbuf->ecccode) {
> + ret = -EINVAL;
> + goto err_free;
> + }
> + nbuf->databuf = kmalloc(mtd->writesize + mtd->oobsize,
> + GFP_KERNEL);
> + if (!nbuf->databuf) {
> + ret = -EINVAL;
> + goto err_free;
> + }
>
> chip->buffers = nbuf;
> } else {
> @@ -4863,8 +4875,12 @@ int nand_scan_tail(struct mtd_info *mtd)
> /* Build bad block table */
> return chip->scan_bbt(mtd);
> err_free:
> - if (!(chip->options & NAND_OWN_BUFFERS))
> + if (!(chip->options & NAND_OWN_BUFFERS)) {
> + kfree(chip->buffers->databuf);
> + kfree(chip->buffers->ecccode);
> + kfree(chip->buffers->ecccalc);
> kfree(chip->buffers);
> + }
> return ret;
> }
> EXPORT_SYMBOL(nand_scan_tail);
> @@ -4915,8 +4931,12 @@ void nand_cleanup(struct nand_chip *chip)
>
> /* Free bad block table memory */
> kfree(chip->bbt);
> - if (!(chip->options & NAND_OWN_BUFFERS))
> + if (!(chip->options & NAND_OWN_BUFFERS)) {
> + kfree(chip->buffers->databuf);
> + kfree(chip->buffers->ecccode);
> + kfree(chip->buffers->ecccalc);
> kfree(chip->buffers);
> + }
>
> /* Free bad block descriptor memory */
> if (chip->badblock_pattern && chip->badblock_pattern->options
next prev parent reply other threads:[~2017-03-27 8:01 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-23 0:17 [RESEND PATCH v2 27/53] mtd: nand: denali: avoid hard-coding ecc.strength and ecc.bytes Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 28/53] mtd: nand: denali: support "nand-ecc-strength" DT property Masahiro Yamada
2017-03-23 8:43 ` Boris Brezillon
2017-03-23 0:17 ` [RESEND PATCH v2 29/53] mtd: nand: denali: remove Toshiba and Hynix specific fixup code Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 30/53] mtd: nand: denali_dt: add compatible strings for UniPhier SoC variants Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 31/53] mtd: nand: denali: set NAND_ECC_CUSTOM_PAGE_ACCESS Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 32/53] mtd: nand: denali: do not propagate NAND_STATUS_FAIL to waitfunc() Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 33/53] mtd: nand: denali: use BIT() and GENMASK() for register macros Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 34/53] mtd: nand: denali: remove unneeded find_valid_banks() Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 35/53] mtd: nand: denali: handle timing parameters by setup_data_interface() Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 36/53] mtd: nand: denali: remove meaningless pipeline read-ahead operation Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 37/53] mtd: nand: denali: rework interrupt handling Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 38/53] mtd: nand: denali: fix NAND_CMD_STATUS handling Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 39/53] mtd: nand: denali: fix NAND_CMD_PARAM handling Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 40/53] mtd: nand: do not check R/B# for CMD_READID in nand_command(_lp) Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 41/53] mtd: nand: do not check R/B# for CMD_SET_FEATURES " Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 42/53] mtd: nand: denali: switch over to cmd_ctrl instead of cmdfunc Masahiro Yamada
2017-03-23 8:52 ` Boris Brezillon
2017-03-23 0:17 ` [RESEND PATCH v2 43/53] mtd: nand: denali: fix bank reset function Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 44/53] mtd: nand: denali: use interrupt instead of polling for bank reset Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 45/53] mtd: nand: denali: propagate page to helpers via function argument Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 46/53] mtd: nand: denali: merge struct nand_buf into struct denali_nand_info Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 47/53] mtd: nand: denali: use flag instead of register macro for direction Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 48/53] mtd: nand: denali: fix raw and oob accessors for syndrome page layout Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 49/53] mtd: nand: denali: support hardware-assisted erased page detection Masahiro Yamada
2017-03-23 0:17 ` [RESEND PATCH v2 50/53] mtd: nand: allocate aligned buffers if NAND_OWN_BUFFERS is unset Masahiro Yamada
2017-03-27 8:00 ` Boris Brezillon [this message]
2017-03-28 1:13 ` yamada.masahiro
2017-03-28 7:59 ` Boris Brezillon
2017-03-28 8:07 ` Boris Brezillon
2017-03-28 10:22 ` Russell King - ARM Linux
2017-03-28 10:17 ` Russell King - ARM Linux
2017-03-28 12:13 ` Boris Brezillon
2017-03-29 3:22 ` yamada.masahiro
2017-03-29 7:03 ` Boris Brezillon
2017-03-23 0:18 ` [RESEND PATCH v2 51/53] mtd: nand: denali: skip driver internal bounce buffer when possible Masahiro Yamada
2017-03-23 0:18 ` [RESEND PATCH v2 52/53] mtd: nand: denali: use non-managed kmalloc() for DMA buffer Masahiro Yamada
2017-03-23 11:33 ` Robin Murphy
2017-03-24 1:41 ` yamada.masahiro
2017-03-24 17:09 ` Robin Murphy
2017-03-23 0:18 ` [RESEND PATCH v2 53/53] mtd: nand: denali: enable bad block table scan Masahiro Yamada
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170327100039.480b8d8d@bbrezillon \
--to=boris.brezillon@free-electrons.com \
--cc=artem.bityutskiy@linux.intel.com \
--cc=chuanxiao.dong@intel.com \
--cc=computersforpeace@gmail.com \
--cc=dinguyen@kernel.org \
--cc=dwmw2@infradead.org \
--cc=ejo@pengutronix.de \
--cc=grmoore@opensource.altera.com \
--cc=jaswinder.singh@linaro.org \
--cc=laurent.monat@idquantique.com \
--cc=linux-mtd@lists.infradead.org \
--cc=marek.vasut@gmail.com \
--cc=mhiramat@kernel.org \
--cc=robh@kernel.org \
--cc=thorsten.christiansson@idquantique.com \
--cc=yamada.masahiro@socionext.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox