[alsa-devel] [PATCH] ASoC: omap-pcm: Lower the dma coherent mask to 32bits
Peter Ujfalusi
peter.ujfalusi at ti.com
Mon Dec 9 10:56:03 CET 2013
On 12/06/2013 03:04 PM, Takashi Iwai wrote:
> At Fri, 6 Dec 2013 12:25:43 +0000,
> Russell King - ARM Linux wrote:
>>
>> On Fri, Dec 06, 2013 at 09:12:22AM +0100, Takashi Iwai wrote:
>>> But, it's still unclear why only get_coherent_dma_mask() takes max_pfn
>>> into account for the check of dma_to_pfn(dev, mask).
>>>
>>> In dma_supported(),
>>>
>>> unsigned long limit;
>>> limit = dma_to_pfn(dev, mask);
>>> if (limit < arm_dma_pfn_limit)
>>> return 0;
>>>
>>> while in get_coherent_dma_mask(),
>>>
>>> unsigned long max_dma_pfn;
>>> max_dma_pfn = min(max_pfn, arm_dma_pfn_limit);
>>> if (dma_to_pfn(dev, mask) < max_dma_pfn)
>>> return 0;
>>>
>>> So, the current code looks to me that the results from
>>> dma_set_coherent_mask() and the actual allocation may conflict.
>>
>> I did ask Peter to replace *both* with the same thing.
>
> Well, I'm looking at different points. You requested Peter to test
> both functions to take:
>
> if (sizeof(mask) != sizeof(dma_addr_t) &&
> mask > (dma_addr_t)~0 &&
> dma_to_pfn(dev, ~0) < min(max_pfn, arm_dma_pfn_limit))
> return 0;
>
> But, after that line, dma_supported() has another check:
>
> if (dma_to_pfn(dev, mask) < arm_dma_pfn_limit)
> return 0;
>
> and get_coherent_dma_mask() has a different check:
>
> if (dma_to_pfn(dev, mask) < min(max_pfn, arm_dma_pfn_limit))
> return 0;
>
> (the expressions here are expanded for easier comparison)
>
> This is what I'm wondering.
The tests in get_coherent_dma_mask() and dma_supported() should be identical.
Fixing the dma_supported() checks and calling dma_supported() from
get_coherent_dma_mask() instead of doing the same test coded locally there
should be the preferred solution.
I think dma_supported() should be like this:
int dma_supported(struct device *dev, u64 mask)
{
unsigned long max_dma_pfn;
/*
* If the mask allows for more memory than we can address,
* and we actually have that much memory, then we must
* indicate that DMA to this device is not supported.
*/
max_dma_pfn = min(max_pfn, arm_dma_pfn_limit);
if (sizeof(mask) != sizeof(dma_addr_t) &&
mask > (dma_addr_t)~0 &&
dma_to_pfn(dev, ~0) < max_dma_pfn)
return 0;
/*
* Translate the device's DMA mask to a PFN limit. This
* PFN number includes the page which we can DMA to.
*/
if (dma_to_pfn(dev, mask) < max_dma_pfn)
return 0;
return 1;
}
--
Péter
More information about the Alsa-devel
mailing list