Hi, On 31/05/2019 9.54, Peter Ujfalusi wrote: > > On 29/05/2019 11.37, Peter Ujfalusi wrote: >> With the polled parameter the DMA drivers can be tested if they can work >> correctly when no completion is requested (no DMA_PREP_INTERRUPT and no >> callback is provided). >> >> If polled mode is selected then use dma_sync_wait() to execute the test >> iteration instead of relying on the completion callback. >> >> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@xxxxxx> >> --- >> drivers/dma/dmatest.c | 35 ++++++++++++++++++++++++++++------- >> 1 file changed, 28 insertions(+), 7 deletions(-) >> >> diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c >> index b96814a7dceb..088086d041e9 100644 >> --- a/drivers/dma/dmatest.c >> +++ b/drivers/dma/dmatest.c >> @@ -75,6 +75,10 @@ static bool norandom; >> module_param(norandom, bool, 0644); >> MODULE_PARM_DESC(norandom, "Disable random offset setup (default: random)"); >> >> +static bool polled; >> +module_param(polled, bool, S_IRUGO | S_IWUSR); >> +MODULE_PARM_DESC(polled, "Use polling for completion instead of interrupts"); >> + >> static bool verbose; >> module_param(verbose, bool, S_IRUGO | S_IWUSR); >> MODULE_PARM_DESC(verbose, "Enable \"success\" result messages (default: off)"); >> @@ -113,6 +117,7 @@ struct dmatest_params { >> bool norandom; >> int alignment; >> unsigned int transfer_size; >> + bool polled; >> }; >> >> /** >> @@ -654,7 +659,10 @@ static int dmatest_func(void *data) >> /* >> * src and dst buffers are freed by ourselves below >> */ >> - flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; >> + if (params->polled) >> + flags = DMA_CTRL_ACK; >> + else >> + flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; >> >> ktime = ktime_get(); >> while (!kthread_should_stop() >> @@ -783,8 +791,10 @@ static int dmatest_func(void *data) >> } >> >> done->done = false; >> - tx->callback = dmatest_callback; >> - tx->callback_param = done; >> + if (!params->polled) { >> + tx->callback = dmatest_callback; >> + tx->callback_param = done; >> + } >> cookie = tx->tx_submit(tx); >> >> if (dma_submit_error(cookie)) { >> @@ -793,12 +803,22 @@ static int dmatest_func(void *data) >> msleep(100); >> goto error_unmap_continue; >> } >> - dma_async_issue_pending(chan); >> >> - wait_event_freezable_timeout(thread->done_wait, done->done, >> - msecs_to_jiffies(params->timeout)); >> + if (params->polled) { >> + status = dma_sync_wait(chan, cookie); >> + dmaengine_terminate_sync(chan); >> + if (status == DMA_COMPLETE) >> + done->done = true; > > I think the main question is how polling for completion should be > handled when client does not request for completion interrupt, thus we > will have no callback in the DMA driver when the transfer is completed. > > If DMA_PREP_INTERRUPT is set for the tx_descriptor then the polling will > wait until the DMA driver internally receives the interrupt that the > transfer is done and sets the cookie to completed state. > > However if DMA_PREP_INTERRUPT is not set, the DMA driver will not get > notification from the HW that is the transfer is done, the only way to > know is to check the tx_status and based on the residue (if it is 0 then > it is done) decide what to tell the client. > > Should the client call dmaengine_terminate_* after the polling returned > unconditionally to free up the descriptor? This is how omap-dma is handling the polled memcpy support. > Or client should only call dmaengine_terminate_* in case the polling > returned with !DMA_COMPLETE and the DMA driver must clean things up > before returning if the transfer is completed (residue == 0)? > >> + } else { >> + dma_async_issue_pending(chan); >> + >> + wait_event_freezable_timeout(thread->done_wait, >> + done->done, >> + msecs_to_jiffies(params->timeout)); >> >> - status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); >> + status = dma_async_is_tx_complete(chan, cookie, NULL, >> + NULL); >> + } >> >> if (!done->done) { >> result("test timed out", total_tests, src->off, dst->off, >> @@ -1068,6 +1088,7 @@ static void add_threaded_test(struct dmatest_info *info) >> params->norandom = norandom; >> params->alignment = alignment; >> params->transfer_size = transfer_size; >> + params->polled = polled; >> >> request_channels(info, DMA_MEMCPY); >> request_channels(info, DMA_MEMSET); >> > > - Péter > > Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. > Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki > - Péter Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki