diff mbox series

[v1,2/6] dmaengine: dmatest: Fix process hang when reading 'wait' parameter

Message ID 20200424161147.16895-2-andriy.shevchenko@linux.intel.com (mailing list archive)
State Changes Requested
Headers show
Series [v1,1/6] dmaengine: dmatest: Fix iteration non-stop logic | expand

Commit Message

Andy Shevchenko April 24, 2020, 4:11 p.m. UTC
If we do

  % echo 1 > /sys/module/dmatest/parameters/run
  [  115.851124] dmatest: Could not start test, no channels configured

  % echo dma8chan7 > /sys/module/dmatest/parameters/channel
  [  127.563872] dmatest: Added 1 threads using dma8chan7

  % cat /sys/module/dmatest/parameters/wait
  ... !!! HANG !!! ...

The culprit is the commit 6138f967bccc

  ("dmaengine: dmatest: Use fixed point div to calculate iops")

which makes threads not to run, but pending and being kicked off by writing
to the 'run' node. However, it forgot to consider 'wait' routine to avoid
above mentioned case.

In order to fix this, check for really running threads, i.e. with pending
and done flags unset.

It's pity the culprit commit hadn't updated documentation and tested all
possible scenarios.

Fixes: 6138f967bccc ("dmaengine: dmatest: Use fixed point div to calculate iops")
Cc: Seraj Alijan <seraj.alijan@sondrel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dmatest.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Vinod Koul April 27, 2020, 4:16 p.m. UTC | #1
On 24-04-20, 19:11, Andy Shevchenko wrote:
> If we do
> 
>   % echo 1 > /sys/module/dmatest/parameters/run
>   [  115.851124] dmatest: Could not start test, no channels configured
> 
>   % echo dma8chan7 > /sys/module/dmatest/parameters/channel
>   [  127.563872] dmatest: Added 1 threads using dma8chan7
> 
>   % cat /sys/module/dmatest/parameters/wait
>   ... !!! HANG !!! ...
> 
> The culprit is the commit 6138f967bccc
> 
>   ("dmaengine: dmatest: Use fixed point div to calculate iops")
> 
> which makes threads not to run, but pending and being kicked off by writing
> to the 'run' node. However, it forgot to consider 'wait' routine to avoid
> above mentioned case.
> 
> In order to fix this, check for really running threads, i.e. with pending
> and done flags unset.
> 
> It's pity the culprit commit hadn't updated documentation and tested all
> possible scenarios.
> 
> Fixes: 6138f967bccc ("dmaengine: dmatest: Use fixed point div to calculate iops")
> Cc: Seraj Alijan <seraj.alijan@sondrel.com>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  drivers/dma/dmatest.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
> index 4993e3e5c5b01..307622e765996 100644
> --- a/drivers/dma/dmatest.c
> +++ b/drivers/dma/dmatest.c
> @@ -240,7 +240,7 @@ static bool is_threaded_test_run(struct dmatest_info *info)
>  		struct dmatest_thread *thread;
>  
>  		list_for_each_entry(thread, &dtc->threads, node) {
> -			if (!thread->done)
> +			if (!thread->done && !thread->pending)
>  				return true;
>  		}
>  	}
> @@ -1192,7 +1192,7 @@ static int dmatest_chan_set(const char *val, const struct kernel_param *kp)
>  		mutex_unlock(&info->lock);
>  		return ret;
>  	}
> -	/*Clear any previously run threads */
> +	/* Clear any previously run threads */

This does not belong to this patch, can you please split it out...
diff mbox series

Patch

diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index 4993e3e5c5b01..307622e765996 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -240,7 +240,7 @@  static bool is_threaded_test_run(struct dmatest_info *info)
 		struct dmatest_thread *thread;
 
 		list_for_each_entry(thread, &dtc->threads, node) {
-			if (!thread->done)
+			if (!thread->done && !thread->pending)
 				return true;
 		}
 	}
@@ -1192,7 +1192,7 @@  static int dmatest_chan_set(const char *val, const struct kernel_param *kp)
 		mutex_unlock(&info->lock);
 		return ret;
 	}
-	/*Clear any previously run threads */
+	/* Clear any previously run threads */
 	if (!is_threaded_test_run(info) && !is_threaded_test_pending(info))
 		stop_threaded_test(info);
 	/* Reject channels that are already registered */