lkml.org 
[lkml]   [2017]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v5 22/23] mtd: nand: denali: use non-managed kmalloc() for DMA buffer
    Date
    As Russell and Lars stated in the discussion [1], using
    devm_k*alloc() with DMA is not a good idea.

    Let's use kmalloc (not kzalloc because no need for zero-out).
    Also, allocate the buffer as late as possible because it must be
    freed for any error that follows.

    [1] https://lkml.org/lkml/2017/3/8/693

    Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
    Cc: Russell King <rmk+kernel@armlinux.org.uk>
    Cc: Lars-Peter Clausen <lars@metafoo.de>
    Acked-by: Robin Murphy <robin.murphy@arm.com>
    ---

    Changes in v5: None
    Changes in v4: None
    Changes in v3: None
    Changes in v2:
    - Newly added

    drivers/mtd/nand/denali.c | 26 +++++++++++++++++---------
    1 file changed, 17 insertions(+), 9 deletions(-)

    diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
    index 963638693850..904f859e19b6 100644
    --- a/drivers/mtd/nand/denali.c
    +++ b/drivers/mtd/nand/denali.c
    @@ -23,6 +23,7 @@
    #include <linux/mutex.h>
    #include <linux/mtd/mtd.h>
    #include <linux/module.h>
    +#include <linux/slab.h>

    #include "denali.h"

    @@ -1386,13 +1387,6 @@ int denali_init(struct denali_nand_info *denali)
    if (ret)
    goto disable_irq;

    - denali->buf = devm_kzalloc(denali->dev, mtd->writesize + mtd->oobsize,
    - GFP_KERNEL);
    - if (!denali->buf) {
    - ret = -ENOMEM;
    - goto disable_irq;
    - }
    -
    if (ioread32(denali->flash_reg + FEATURES) & FEATURES__DMA)
    denali->dma_avail = 1;

    @@ -1477,17 +1471,30 @@ int denali_init(struct denali_nand_info *denali)
    if (ret)
    goto disable_irq;

    + /*
    + * This buffer is DMA-mapped by denali_{read,write}_page_raw. Do not
    + * use devm_kmalloc() because the memory allocated by devm_ does not
    + * guarantee DMA-safe alignment.
    + */
    + denali->buf = kmalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL);
    + if (!denali->buf) {
    + ret = -ENOMEM;
    + goto disable_irq;
    + }
    +
    ret = nand_scan_tail(mtd);
    if (ret)
    - goto disable_irq;
    + goto free_buf;

    ret = mtd_device_register(mtd, NULL, 0);
    if (ret) {
    dev_err(denali->dev, "Failed to register MTD: %d\n", ret);
    - goto disable_irq;
    + goto free_buf;
    }
    return 0;

    +free_buf:
    + kfree(denali->buf);
    disable_irq:
    denali_disable_irq(denali);

    @@ -1501,6 +1508,7 @@ void denali_remove(struct denali_nand_info *denali)
    struct mtd_info *mtd = nand_to_mtd(&denali->nand);

    nand_release(mtd);
    + kfree(denali->buf);
    denali_disable_irq(denali);
    }
    EXPORT_SYMBOL(denali_remove);
    --
    2.7.4
    \
     
     \ /
      Last update: 2017-06-12 01:04    [W:4.466 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site