dmatest: do not allow to interrupt ongoing tests
When user interrupts ongoing transfers the dmatest may end up with console lockup, oops, or data mismatch. This patch prevents user to abort any ongoing test. Documentation is updated accordingly. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reported-by: Will Deacon <will.deacon@arm.com> Tested-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
This commit is contained in:

committed by
Vinod Koul

parent
9ecb41bd8c
commit
bcc567e311
@@ -716,8 +716,7 @@ static int dmatest_func(void *data)
|
||||
}
|
||||
dma_async_issue_pending(chan);
|
||||
|
||||
wait_event_freezable_timeout(done_wait,
|
||||
done.done || kthread_should_stop(),
|
||||
wait_event_freezable_timeout(done_wait, done.done,
|
||||
msecs_to_jiffies(params->timeout));
|
||||
|
||||
status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
|
||||
@@ -997,7 +996,6 @@ static void stop_threaded_test(struct dmatest_info *info)
|
||||
static int __restart_threaded_test(struct dmatest_info *info, bool run)
|
||||
{
|
||||
struct dmatest_params *params = &info->params;
|
||||
int ret;
|
||||
|
||||
/* Stop any running test first */
|
||||
__stop_threaded_test(info);
|
||||
@@ -1012,13 +1010,23 @@ static int __restart_threaded_test(struct dmatest_info *info, bool run)
|
||||
memcpy(params, &info->dbgfs_params, sizeof(*params));
|
||||
|
||||
/* Run test with new parameters */
|
||||
ret = __run_threaded_test(info);
|
||||
if (ret) {
|
||||
__stop_threaded_test(info);
|
||||
pr_err("dmatest: Can't run test\n");
|
||||
return __run_threaded_test(info);
|
||||
}
|
||||
|
||||
static bool __is_threaded_test_run(struct dmatest_info *info)
|
||||
{
|
||||
struct dmatest_chan *dtc;
|
||||
|
||||
list_for_each_entry(dtc, &info->channels, node) {
|
||||
struct dmatest_thread *thread;
|
||||
|
||||
list_for_each_entry(thread, &dtc->threads, node) {
|
||||
if (!thread->done)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return false;
|
||||
}
|
||||
|
||||
static ssize_t dtf_write_string(void *to, size_t available, loff_t *ppos,
|
||||
@@ -1091,22 +1099,10 @@ static ssize_t dtf_read_run(struct file *file, char __user *user_buf,
|
||||
{
|
||||
struct dmatest_info *info = file->private_data;
|
||||
char buf[3];
|
||||
struct dmatest_chan *dtc;
|
||||
bool alive = false;
|
||||
|
||||
mutex_lock(&info->lock);
|
||||
list_for_each_entry(dtc, &info->channels, node) {
|
||||
struct dmatest_thread *thread;
|
||||
|
||||
list_for_each_entry(thread, &dtc->threads, node) {
|
||||
if (!thread->done) {
|
||||
alive = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (alive) {
|
||||
if (__is_threaded_test_run(info)) {
|
||||
buf[0] = 'Y';
|
||||
} else {
|
||||
__stop_threaded_test(info);
|
||||
@@ -1132,7 +1128,12 @@ static ssize_t dtf_write_run(struct file *file, const char __user *user_buf,
|
||||
|
||||
if (strtobool(buf, &bv) == 0) {
|
||||
mutex_lock(&info->lock);
|
||||
ret = __restart_threaded_test(info, bv);
|
||||
|
||||
if (__is_threaded_test_run(info))
|
||||
ret = -EBUSY;
|
||||
else
|
||||
ret = __restart_threaded_test(info, bv);
|
||||
|
||||
mutex_unlock(&info->lock);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user