On Wed, Jul 20, 2016 at 11:27 PM, Andy Green <a...@warmcat.com> wrote:
> On July 21, 2016 1:22:02 PM GMT+08:00, John Stultz <john.stu...@linaro.org> 
> wrote:
>>On Wed, Jul 20, 2016 at 9:26 PM, zhangfei <zhangfei....@linaro.org>
>>wrote:
>>>
>>>
>>> On 07/21/2016 11:53 AM, John Stultz wrote:
>>>>
>>>> After lots of debugging on an occasional DMA ERR issue, I realized
>>>> that the desc structures which we point the dma hardware are being
>>>> allocated out of regular memory. This means when we fill the desc
>>>> structures, that data doesn't always get flushed out to memory by
>>>> the time we start the dma transfer, resulting in the dma engine
>>getting
>>>> some null values, resulting in a DMA ERR on the first irq.
>>>
>>>
>>> How about using wmb() flush before start dma to sync desc?
>>
>>So I'm not going to pretend to be an expert here, but my understanding
>>is that wmb() syncrhonizes cpu write ordering operations across cpus,
>
> IIUI what the memory barrier does is tell the *compiler* to actually do any 
> writes that the code asked for, but which otherwise might actually be 
> deferred past that point.  The compiler doesn't know that buffer area has 
> other hardware snooping it, so by default it feels it can play tricks with 
> what seems to it like just generally deferring spilling registers to memory.  
> wmb makes sure the compiler's pending writes actually happen right there.  
> (writel() etc definitions have one built-in, so they always do what you asked 
> when you asked).
>
> That can be of interest when syncing with other cores but also to other IPs 
> that intend to use the written-to area immediately, which is what's happening 
> here.  Without the barrier the write may not be issued anywhere, even to 
> local cpu cache, until after the hw is asked to go read the buffer, 
> corrupting what the hw sees.
>
>>so the cpus see all the changes before the wmb() before they see any
>>changes after.  But I'm not sure what effect wmb() has across cpu
>>cache to device ordering.   I don't think it works as a cache flush to
>>memory.
>>
>>Andy's patch introducing the cyclic support actually had a wmb() in it
>>that I removed as I couldn't understand clearly why it was there (and
>>there wasn't a comment explaining, as required by checkpatch :).   But
>>even with that wmb(), the DMA ERR was still seen.
>
> The rule about the comment is there partially because there's a general 
> tendancy for throwing voodoo smbs on broken things in case it helps.  But 
> writing out memory descriptors that other hw is going to read is a legit use 
> for it I think.  If the compiler you use wasn't deferring the write, you 
> won't notice any difference removing it, but that doesn't mean it shouldn't 
> be there.
>

Though from your comments above, wouldn't using writel() instead of
writel_relaxed(), followed by a wmb() be sufficient?

thanks
-john

Reply via email to