Re: [PATCH] dmaengine: dmatest: Add support for completion polling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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?

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



[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux PCI]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux