• Lars-Peter Clausen's avatar
    dma: pl330: Fix handling of TERMINATE_ALL while processing completed descriptors · 39ff8613
    Lars-Peter Clausen authored
    The pl330 DMA driver is broken in regard to handling a terminate all request
    while it is processing the list of completed descriptors. This is most visible
    when calling dmaengine_terminate_all() from within the descriptors callback for
    cyclic transfers. In this case the TERMINATE_ALL transfer will clear the
    work_list and stop the transfer. But after all callbacks for all completed
    descriptors have been handled the descriptors will be re-enqueued into the (now
    empty) work_list. So the next time dma_async_issue_pending() is called for the
    channel these descriptors will be transferred again which will cause data
    corruption. Similar issues can occur if dmaengine_terminate_all() is not called
    from within the descriptor callback but runs on a different CPU at the same time
    as the completed descriptor list is processed.
    
    This patch introduces a new per channel list which will hold the completed
    descriptors. While processing the list the channel's lock will be held to avoid
    racing against dmaengine_terminate_all(). The lock will be released when calling
    the descriptors callback though. Since the list of completed descriptors might
    be modified (e.g. by calling dmaengine_terminate_all() from the callback) we can
    not use the normal list iterator macros. Instead we'll need to check for each
    loop iteration again if there are still items in the list. The drivers
    TERMINATE_ALL implementation is updated to move descriptors from both the
    work_list as well the new completed_list back to the descriptor pool. This makes
    sure that none of the descripts finds its way back into the work list and also
    that we do not call any futher complete callbacks after
    dmaengine_terminate_all() has been called.
    Signed-off-by: default avatarLars-Peter Clausen <lars@metafoo.de>
    Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
    39ff8613
pl330.c 66.7 KB