lkml.org 
[lkml]   [2018]   [May]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.16 212/272] dmaengine: rcar-dmac: Check the done lists in rcar_dmac_chan_get_residue()
    Date
    4.16-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

    [ Upstream commit 3e081628d510b2ddbe493371d9c574d9275da17e ]

    This patch fixes an issue that a race condition happens between a client
    driver and the rcar-dmac driver:

    - The rcar_dmac_isr_transfer_end() is called.
    - The done list appears, and desc.running is the next active list.
    - rcar_dmac_chan_get_residue() is called by a client driver before
    rcar_dmac_isr_channel_thread() is called.
    - The rcar_dmac_chan_get_residue() will not find any descriptors.
    - And, the following WARNING happens:
    WARN(1, "No descriptor for cookie!");

    The sh-sci driver with HSCIF (921,600bps) on R-Car H3 can cause this
    situation.
    So, this patch checks the done lists in rcar_dmac_chan_get_residue()
    and returns zero if the done lists has the argument cookie.

    Tested-by: Nguyen Viet Dung <dung.nguyen.aj@renesas.com>
    Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
    Signed-off-by: Vinod Koul <vinod.koul@intel.com>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/dma/sh/rcar-dmac.c | 9 +++++++++
    1 file changed, 9 insertions(+)

    --- a/drivers/dma/sh/rcar-dmac.c
    +++ b/drivers/dma/sh/rcar-dmac.c
    @@ -1301,8 +1301,17 @@ static unsigned int rcar_dmac_chan_get_r
    * If the cookie doesn't correspond to the currently running transfer
    * then the descriptor hasn't been processed yet, and the residue is
    * equal to the full descriptor size.
    + * Also, a client driver is possible to call this function before
    + * rcar_dmac_isr_channel_thread() runs. In this case, the "desc.running"
    + * will be the next descriptor, and the done list will appear. So, if
    + * the argument cookie matches the done list's cookie, we can assume
    + * the residue is zero.
    */
    if (cookie != desc->async_tx.cookie) {
    + list_for_each_entry(desc, &chan->desc.done, node) {
    + if (cookie == desc->async_tx.cookie)
    + return 0;
    + }
    list_for_each_entry(desc, &chan->desc.pending, node) {
    if (cookie == desc->async_tx.cookie)
    return desc->size;

    \
     
     \ /
      Last update: 2018-05-28 13:31    [W:6.702 / U:0.256 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site