From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752756AbdCHLQl (ORCPT ); Wed, 8 Mar 2017 06:16:41 -0500 Received: from foss.arm.com ([217.140.101.70]:57878 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752095AbdCHLQX (ORCPT ); Wed, 8 Mar 2017 06:16:23 -0500 Subject: Re: [Question] devm_kmalloc() for DMA ? References: To: Masahiro Yamada , dmaengine@vger.kernel.org, linux-arm-kernel Cc: Russell King - ARM Linux , Arnd Bergmann , masahiroy@kernel.org, Linux Kernel Mailing List , "James E.J. Bottomley" , Tejun Heo , "David S. Miller" From: Robin Murphy Message-ID: Date: Wed, 8 Mar 2017 11:15:39 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.7.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 08/03/17 10:59, Masahiro Yamada wrote: > 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. How so? If anything returned by kmalloc() is guaranteed to occupy some multiple of ARCH_DMA_MINALIGN bytes in order to avoid two allocations falling into the same cache line, I don't see how stealing the first 16 bytes *of a single allocation* could make it start sharing cache lines with another? :/ If a particular device has a problem with: p = kmalloc(...); d = dma_map_single(p + 0x10, ...); do_something_with(d); that's a separate issue altogether. Robin. > 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. > >