Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1595056

[Question] devm_kmalloc() for DMA ?

From Masahiro Yamada <yamada.masahiro@socionext.com>
Newsgroups linux.kernel
Subject [Question] devm_kmalloc() for DMA ?
Date 2017-03-08 12:10 +0100
Message-ID <tiHDI-5Js-13@gated-at.bofh.it> (permalink)
Organization linux.* mail to news gateway

Show all headers | View raw


Hi experts,

I have a question about
how to allocate DMA-safe buffer.


In my understanding, kmalloc() returns
memory with DMA safe alignment
in order to avoid cache-sharing problem when used for DMA.

The alignment is decided by ARCH_DMA_MINALIGN.
For example, on modern ARM 32bit boards, this value is typically 64.
So, memory returned by kmalloc() has
at least 64 byte alignment.


On the other hand, devm_kmalloc() does not return
enough-aligned memory.


On my board (ARM 32bit), devm_kmalloc() returns
(ARCH_DMA_MINALIGN aligned address) + 0x10.



The reason of the offset 0x10 is obvious.

struct devres {
        struct devres_node node;
        /* -- 3 pointers */
        unsigned long long data[]; /* guarantee ull alignment */
};


Management data is located at the top of struct devres.
Then, devm_kmalloc() returns dr->data.

The "unsigned long long" guarantees
the returned memory has 0x10 alignment,
but I think this may not be enough for DMA.

I noticed this when I was seeing drivers/mtd/nand/denali.c

The code looks as follows:


        denali->buf.buf = devm_kzalloc(denali->dev,
                             mtd->writesize + mtd->oobsize,
                             GFP_KERNEL);
        if (!denali->buf.buf) {
                ret = -ENOMEM;
                goto failed_req_irq;
        }

        /* Is 32-bit DMA supported? */
        ret = dma_set_mask(denali->dev, DMA_BIT_MASK(32));
        if (ret) {
                dev_err(denali->dev, "No usable DMA configuration\n");
                goto failed_req_irq;
        }

        denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf,
                             mtd->writesize + mtd->oobsize,
                             DMA_BIDIRECTIONAL);




Memory buffer is allocated by devm_kzalloc(), then
passed to dma_map_single().



Could this be a potential problem in general?

Is devm_kmalloc() not recommended
for buffer that can be DMA-mapped?


Any advice is appreciated.


-- 
Best Regards
Masahiro Yamada

Back to linux.kernel | Previous | NextNext in thread | Find similar | Unroll thread


Thread

[Question] devm_kmalloc() for DMA ? Masahiro Yamada <yamada.masahiro@socionext.com> - 2017-03-08 12:10 +0100
  Re: [Question] devm_kmalloc() for DMA ? Robin Murphy <robin.murphy@arm.com> - 2017-03-08 12:20 +0100
    Re: [Question] devm_kmalloc() for DMA ? Masahiro Yamada <yamada.masahiro@socionext.com> - 2017-03-08 19:10 +0100
      Re: [Question] devm_kmalloc() for DMA ? Russell King - ARM Linux <linux@armlinux.org.uk> - 2017-03-08 21:20 +0100
        Re: [Question] devm_kmalloc() for DMA ? Lars-Peter Clausen <lars@metafoo.de> - 2017-03-08 21:50 +0100
          Re: [Question] devm_kmalloc() for DMA ? Russell King - ARM Linux <linux@armlinux.org.uk> - 2017-03-08 22:30 +0100
            Re: [Question] devm_kmalloc() for DMA ? Lars-Peter Clausen <lars@metafoo.de> - 2017-03-09 00:10 +0100
              Re: [Question] devm_kmalloc() for DMA ? Masahiro Yamada <yamada.masahiro@socionext.com> - 2017-03-09 04:30 +0100
                Re: [Question] devm_kmalloc() for DMA ? Russell King - ARM Linux <linux@armlinux.org.uk> - 2017-03-09 10:30 +0100
      Re: [Question] devm_kmalloc() for DMA ? Lars-Peter Clausen <lars@metafoo.de> - 2017-03-08 21:50 +0100
      Re: [Question] devm_kmalloc() for DMA ? Robin Murphy <robin.murphy@arm.com> - 2017-03-09 12:30 +0100

csiph-web