From 35a61fef565e83370c16d07f8e797c7bd7a480e6 Mon Sep 17 00:00:00 2001 From: Yangbo Lu Date: Mon, 29 Jan 2018 18:30:44 +0800 Subject: [PATCH] layerscape: fix DPAA2 QDMA issue This patch is to reverse a upstream dmatest patch for now which is causing DPAA2 QDMA test issue. Signed-off-by: Yangbo Lu --- ...-dmatest-move-callback-wait-queue-to.patch | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 target/linux/layerscape/patches-4.9/819-Revert-dmaengine-dmatest-move-callback-wait-queue-to.patch diff --git a/target/linux/layerscape/patches-4.9/819-Revert-dmaengine-dmatest-move-callback-wait-queue-to.patch b/target/linux/layerscape/patches-4.9/819-Revert-dmaengine-dmatest-move-callback-wait-queue-to.patch new file mode 100644 index 0000000000..a8e8ad5c0c --- /dev/null +++ b/target/linux/layerscape/patches-4.9/819-Revert-dmaengine-dmatest-move-callback-wait-queue-to.patch @@ -0,0 +1,134 @@ +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);