lkml.org 
[lkml]   [2015]   [Mar]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
From
Date
SubjectRe: ARM: OMPA4+: is it expected dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64)); to fail?
Hi Russell,

On 03/10/2015 01:05 PM, Russell King - ARM Linux wrote:
> On Fri, Mar 06, 2015 at 11:47:48PM +0200, Grygorii.Strashko@linaro.org wrote:
>> On 03/05/2015 10:17 PM, Russell King - ARM Linux wrote:
>>> On Thu, Mar 05, 2015 at 08:55:07PM +0200, Grygorii.Strashko@linaro.org wrote:
>>>> The dma_coerce_mask_and_coherent() will fail in case 'Example 3' and succeed in cases 1,2.
>>>> dma-mapping.c --> __dma_supported()
>>>> if (sizeof(mask) != sizeof(dma_addr_t) && <== true for all OMAP4+
>>>> mask > (dma_addr_t)~0 && <== true for DMA_BIT_MASK(64)
>>>> dma_to_pfn(dev, ~0) < max_pfn) { <== true only for Example 3
>>>
>>> Hmm, I think this may make more sense to be "< max_pfn - 1" here, as
>>> that would be better suited to our intention.
>>>
>>> The result of dma_to_pfn(dev, ~0) is the maximum PFN which we could
>>> address via DMA, but we're comparing it with the maximum PFN in the
>>> system plus 1 - so we need to subtract one from it.
>>
>> Ok. I'll try it.
>
> Any news on this - I think it is a real off-by-one bug which we should
> fix in any case.

Sorry for delay, there was a day-off on my side.

As per my test results - with above change
dma_coerce_mask_and_coherent(DMA_BIT_MASK(64)) and friends will succeed always.


=========== Test results:

==== Test case 1:
Input data:
- RAM: start = 0x80000000 size = 0x80000000
- CONFIG_ARM_LPAE=n and sizeof(phys_addr_t) = 4

a) NO changes:
memory registered within memblock as:
memory.cnt = 0x1
memory[0x0] [0x00000080000000-0x000000fffffffe], 0x7fffffff bytes flags: 0x0

max_pfn = 0xFFFFF
max_mapnr = 0x7FFFF

dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); -- succeeded

b) with change in __dma_supported():
if (sizeof(mask) != sizeof(dma_addr_t) &&
mask > (dma_addr_t)~0 &&
- dma_to_pfn(dev, ~0) < max_pfn) {
+ dma_to_pfn(dev, ~0) < (max_pfn - 1)) {
if (warn) {

memory registered within memblock as:
memory.cnt = 0x1
memory[0x0] [0x00000080000000-0x000000fffffffe], 0x7fffffff bytes flags: 0x0

max_pfn = 0xFFFFF
max_mapnr = 0x7FFFF

dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); -- succeeded


==== Test case 2:
Input data:
- RAM: start = 0x80000000 size = 0x80000000
- CONFIG_ARM_LPAE=y and sizeof(phys_addr_t) = 8

a) NO changes:
memory registered within memblock as:
memory.cnt = 0x1
memory[0x0] [0x00000080000000-0x000000ffffffff], 0x80000000 bytes flags: 0x0

max_pfn = 0x100000
max_mapnr = 0x80000

dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); -- failed
[ 5.468470] asoc-simple-card sound@0: Coherent DMA mask 0xffffffffffffffff is larger than dma_addr_t allows
[ 5.478706] asoc-simple-card sound@0: Driver did not use or check the return value from dma_set_coherent_mask()?
[ 5.496620] davinci-mcasp 48468000.mcasp: ASoC: pcm constructor failed: -5
[ 5.503844] asoc-simple-card sound@0: ASoC: can't create pcm davinci-mcasp.0-tlv320aic3x-hifi :-5


b) with change in __dma_supported():
if (sizeof(mask) != sizeof(dma_addr_t) &&
mask > (dma_addr_t)~0 &&
- dma_to_pfn(dev, ~0) < max_pfn) {
+ dma_to_pfn(dev, ~0) < (max_pfn - 1)) {
if (warn) {

memory registered within memblock as:
memory.cnt = 0x1
memory[0x0] [0x00000080000000-0x000000ffffffff], 0x80000000 bytes flags: 0x0

max_pfn = 0x100000
max_mapnr = 0x80000

dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); -- succeeded

regards,
-grygorii

--
regards,
-grygorii


\
 
 \ /
  Last update: 2015-03-10 18:21    [W:7.772 / U:0.008 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site