1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
From 8772422ee95b17d87b5cb6cb4318b7ec73f4cfcf Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@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);
|