From 8772422ee95b17d87b5cb6cb4318b7ec73f4cfcf Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Mon, 29 Jan 2018 18:04:07 +0800 Subject: [PATCH] Revert "dmaengine: dmatest: move callback wait queue to thread context" This reverts commit 679dbeac0b6bb551e1f3b95673695b22b2ac953d. --- drivers/dma/dmatest.c | 55 ++++++++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 31 deletions(-) --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c @@ -158,12 +158,6 @@ MODULE_PARM_DESC(run, "Run the test (def #define PATTERN_OVERWRITE 0x20 #define PATTERN_COUNT_MASK 0x1f -/* poor man's completion - we want to use wait_event_freezable() on it */ -struct dmatest_done { - bool done; - wait_queue_head_t *wait; -}; - struct dmatest_thread { struct list_head node; struct dmatest_info *info; @@ -172,8 +166,6 @@ struct dmatest_thread { u8 **srcs; u8 **dsts; enum dma_transaction_type type; - wait_queue_head_t done_wait; - struct dmatest_done test_done; bool done; }; @@ -334,25 +326,18 @@ static unsigned int dmatest_verify(u8 ** return error_count; } +/* poor man's completion - we want to use wait_event_freezable() on it */ +struct dmatest_done { + bool done; + wait_queue_head_t *wait; +}; static void dmatest_callback(void *arg) { struct dmatest_done *done = arg; - struct dmatest_thread *thread = - container_of(arg, struct dmatest_thread, done_wait); - if (!thread->done) { - done->done = true; - wake_up_all(done->wait); - } else { - /* - * If thread->done, it means that this callback occurred - * after the parent thread has cleaned up. This can - * happen in the case that driver doesn't implement - * the terminate_all() functionality and a dma operation - * did not occur within the timeout period - */ - WARN(1, "dmatest: Kernel memory may be corrupted!!\n"); - } + + done->done = true; + wake_up_all(done->wait); } static unsigned int min_odd(unsigned int x, unsigned int y) @@ -423,8 +408,9 @@ static unsigned long long dmatest_KBs(s6 */ static int dmatest_func(void *data) { + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_wait); struct dmatest_thread *thread = data; - struct dmatest_done *done = &thread->test_done; + struct dmatest_done done = { .wait = &done_wait }; struct dmatest_info *info; struct dmatest_params *params; struct dma_chan *chan; @@ -651,9 +637,9 @@ static int dmatest_func(void *data) continue; } - done->done = false; + done.done = false; tx->callback = dmatest_callback; - tx->callback_param = done; + tx->callback_param = &done; cookie = tx->tx_submit(tx); if (dma_submit_error(cookie)) { @@ -666,12 +652,21 @@ static int dmatest_func(void *data) } dma_async_issue_pending(chan); - wait_event_freezable_timeout(thread->done_wait, done->done, + wait_event_freezable_timeout(done_wait, done.done, msecs_to_jiffies(params->timeout)); status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); - if (!done->done) { + if (!done.done) { + /* + * We're leaving the timed out dma operation with + * dangling pointer to done_wait. To make this + * correct, we'll need to allocate wait_done for + * each test iteration and perform "who's gonna + * free it this time?" dancing. For now, just + * leave it dangling. + */ + WARN(1, "dmatest: Kernel stack may be corrupted!!\n"); dmaengine_unmap_put(um); result("test timed out", total_tests, src_off, dst_off, len, 0); @@ -752,7 +747,7 @@ err_thread_type: dmatest_KBs(runtime, total_len), ret); /* terminate all transfers on specified channels */ - if (ret || failed_tests) + if (ret) dmaengine_terminate_all(chan); thread->done = true; @@ -812,8 +807,6 @@ static int dmatest_add_threads(struct dm thread->info = info; thread->chan = dtc->chan; thread->type = type; - thread->test_done.wait = &thread->done_wait; - init_waitqueue_head(&thread->done_wait); smp_wmb(); thread->task = kthread_create(dmatest_func, thread, "%s-%s%u", dma_chan_name(chan), op, i);