[openwrt/openwrt] layerscape: fix DPAA2 QDMA issue

LEDE Commits lede-commits at lists.infradead.org
Tue Feb 13 01:02:31 PST 2018


blogic pushed a commit to openwrt/openwrt.git, branch master:
https://git.lede-project.org/35a61fef565e83370c16d07f8e797c7bd7a480e6

commit 35a61fef565e83370c16d07f8e797c7bd7a480e6
Author: Yangbo Lu <yangbo.lu at nxp.com>
AuthorDate: Mon Jan 29 18:30:44 2018 +0800

    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 <yangbo.lu at nxp.com>
---
 ...ngine-dmatest-move-callback-wait-queue-to.patch | 134 +++++++++++++++++++++
 1 file changed, 134 insertions(+)

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 0000000..a8e8ad5
--- /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 <yangbo.lu at nxp.com>
+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);



More information about the lede-commits mailing list