• Peter Ujfalusi's avatar
    dmaengine: virt-dma: Support for race free transfer termination · 1c7f072d
    Peter Ujfalusi authored
    Even with the introduced vchan_synchronize() we can face race when
    terminating a cyclic transfer.
    If the terminate_all is called after the interrupt handler called
    vchan_cyclic_callback(), but before the vchan_complete tasklet is called:
    vc->cyclic is set to the cyclic descriptor, but the descriptor itself was
    freed up in the driver's terminate_all() callback.
    When the vhan_complete() is executed it will try to fetch the vc->cyclic
    vdesc, but the pointer is pointing now to uninitialized memory leading to
    (hard to reproduce) kernel crash.
    In order to fix this, drivers should:
    - call vchan_terminate_vdesc() from their terminate_all callback instead
    calling their free_desc function to free up the descriptor.
    - implement device_synchronize callback and call vchan_synchronize().
    This way we can make sure that the descriptor is only going to be freed up
    after the vchan_callback was executed in a safe manner.
    Signed-off-by: default avatarPeter Ujfalusi <peter.ujfalusi@ti.com>
    Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
    Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
virt-dma.h 5.83 KB