aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/dmatest.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2013-11-06 19:29:57 -0500
committerDan Williams <dan.j.williams@intel.com>2013-11-14 14:04:38 -0500
commit7b61017822cdff9c18ae70005cf52d84e8dafe5d (patch)
tree009f7f55c8feb60c0ca8fb2c74f1eacc25e9e104 /drivers/dma/dmatest.c
parent0776ae7b89782124ddd72eafe0b1e0fdcdabe32e (diff)
Revert "dmatest: append verify result to results"
This reverts commit d86b2f298e6de124984f5d5817ed1e6e759b3ada. The kernel log buffer is sufficient for collecting test results. The current logging OOMs the machine on long running tests, and usually only the first error is relevant. It is better to stop on error and parse the kernel output. If output volume becomes an issue we can always investigate using trace messages. Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/dma/dmatest.c')
-rw-r--r--drivers/dma/dmatest.c180
1 files changed, 51 insertions, 129 deletions
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index 5791091c13ca..dcb38d86550e 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -98,20 +98,6 @@ enum dmatest_error_type {
98 DMATEST_ET_DMA_ERROR, 98 DMATEST_ET_DMA_ERROR,
99 DMATEST_ET_DMA_IN_PROGRESS, 99 DMATEST_ET_DMA_IN_PROGRESS,
100 DMATEST_ET_VERIFY, 100 DMATEST_ET_VERIFY,
101 DMATEST_ET_VERIFY_BUF,
102};
103
104struct dmatest_verify_buffer {
105 unsigned int index;
106 u8 expected;
107 u8 actual;
108};
109
110struct dmatest_verify_result {
111 unsigned int error_count;
112 struct dmatest_verify_buffer data[MAX_ERROR_COUNT];
113 u8 pattern;
114 bool is_srcbuf;
115}; 101};
116 102
117struct dmatest_thread_result { 103struct dmatest_thread_result {
@@ -122,11 +108,10 @@ struct dmatest_thread_result {
122 unsigned int len; 108 unsigned int len;
123 enum dmatest_error_type type; 109 enum dmatest_error_type type;
124 union { 110 union {
125 unsigned long data; 111 unsigned long data;
126 dma_cookie_t cookie; 112 dma_cookie_t cookie;
127 enum dma_status status; 113 enum dma_status status;
128 int error; 114 int error;
129 struct dmatest_verify_result *vr;
130 }; 115 };
131}; 116};
132 117
@@ -262,9 +247,31 @@ static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len,
262 } 247 }
263} 248}
264 249
265static unsigned int dmatest_verify(struct dmatest_verify_result *vr, u8 **bufs, 250static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
266 unsigned int start, unsigned int end, unsigned int counter, 251 unsigned int counter, bool is_srcbuf)
267 u8 pattern, bool is_srcbuf) 252{
253 u8 diff = actual ^ pattern;
254 u8 expected = pattern | (~counter & PATTERN_COUNT_MASK);
255 const char *thread_name = current->comm;
256
257 if (is_srcbuf)
258 pr_warn("%s: srcbuf[0x%x] overwritten! Expected %02x, got %02x\n",
259 thread_name, index, expected, actual);
260 else if ((pattern & PATTERN_COPY)
261 && (diff & (PATTERN_COPY | PATTERN_OVERWRITE)))
262 pr_warn("%s: dstbuf[0x%x] not copied! Expected %02x, got %02x\n",
263 thread_name, index, expected, actual);
264 else if (diff & PATTERN_SRC)
265 pr_warn("%s: dstbuf[0x%x] was copied! Expected %02x, got %02x\n",
266 thread_name, index, expected, actual);
267 else
268 pr_warn("%s: dstbuf[0x%x] mismatch! Expected %02x, got %02x\n",
269 thread_name, index, expected, actual);
270}
271
272static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
273 unsigned int end, unsigned int counter, u8 pattern,
274 bool is_srcbuf)
268{ 275{
269 unsigned int i; 276 unsigned int i;
270 unsigned int error_count = 0; 277 unsigned int error_count = 0;
@@ -272,7 +279,6 @@ static unsigned int dmatest_verify(struct dmatest_verify_result *vr, u8 **bufs,
272 u8 expected; 279 u8 expected;
273 u8 *buf; 280 u8 *buf;
274 unsigned int counter_orig = counter; 281 unsigned int counter_orig = counter;
275 struct dmatest_verify_buffer *vb;
276 282
277 for (; (buf = *bufs); bufs++) { 283 for (; (buf = *bufs); bufs++) {
278 counter = counter_orig; 284 counter = counter_orig;
@@ -280,12 +286,9 @@ static unsigned int dmatest_verify(struct dmatest_verify_result *vr, u8 **bufs,
280 actual = buf[i]; 286 actual = buf[i];
281 expected = pattern | (~counter & PATTERN_COUNT_MASK); 287 expected = pattern | (~counter & PATTERN_COUNT_MASK);
282 if (actual != expected) { 288 if (actual != expected) {
283 if (error_count < MAX_ERROR_COUNT && vr) { 289 if (error_count < MAX_ERROR_COUNT)
284 vb = &vr->data[error_count]; 290 dmatest_mismatch(actual, pattern, i,
285 vb->index = i; 291 counter, is_srcbuf);
286 vb->expected = expected;
287 vb->actual = actual;
288 }
289 error_count++; 292 error_count++;
290 } 293 }
291 counter++; 294 counter++;
@@ -293,7 +296,7 @@ static unsigned int dmatest_verify(struct dmatest_verify_result *vr, u8 **bufs,
293 } 296 }
294 297
295 if (error_count > MAX_ERROR_COUNT) 298 if (error_count > MAX_ERROR_COUNT)
296 pr_warning("%s: %u errors suppressed\n", 299 pr_warn("%s: %u errors suppressed\n",
297 current->comm, error_count - MAX_ERROR_COUNT); 300 current->comm, error_count - MAX_ERROR_COUNT);
298 301
299 return error_count; 302 return error_count;
@@ -334,30 +337,6 @@ static unsigned int min_odd(unsigned int x, unsigned int y)
334 return val % 2 ? val : val - 1; 337 return val % 2 ? val : val - 1;
335} 338}
336 339
337static char *verify_result_get_one(struct dmatest_verify_result *vr,
338 unsigned int i)
339{
340 struct dmatest_verify_buffer *vb = &vr->data[i];
341 u8 diff = vb->actual ^ vr->pattern;
342 static char buf[512];
343 char *msg;
344
345 if (vr->is_srcbuf)
346 msg = "srcbuf overwritten!";
347 else if ((vr->pattern & PATTERN_COPY)
348 && (diff & (PATTERN_COPY | PATTERN_OVERWRITE)))
349 msg = "dstbuf not copied!";
350 else if (diff & PATTERN_SRC)
351 msg = "dstbuf was copied!";
352 else
353 msg = "dstbuf mismatch!";
354
355 snprintf(buf, sizeof(buf) - 1, "%s [0x%x] Expected %02x, got %02x", msg,
356 vb->index, vb->expected, vb->actual);
357
358 return buf;
359}
360
361static char *thread_result_get(const char *name, 340static char *thread_result_get(const char *name,
362 struct dmatest_thread_result *tr) 341 struct dmatest_thread_result *tr)
363{ 342{
@@ -373,7 +352,6 @@ static char *thread_result_get(const char *name,
373 [DMATEST_ET_DMA_IN_PROGRESS] = 352 [DMATEST_ET_DMA_IN_PROGRESS] =
374 "got completion callback (DMA_IN_PROGRESS)", 353 "got completion callback (DMA_IN_PROGRESS)",
375 [DMATEST_ET_VERIFY] = "errors", 354 [DMATEST_ET_VERIFY] = "errors",
376 [DMATEST_ET_VERIFY_BUF] = "verify errors",
377 }; 355 };
378 static char buf[512]; 356 static char buf[512];
379 357
@@ -415,51 +393,6 @@ static int thread_result_add(struct dmatest_info *info,
415 return 0; 393 return 0;
416} 394}
417 395
418static unsigned int verify_result_add(struct dmatest_info *info,
419 struct dmatest_result *r, unsigned int n,
420 unsigned int src_off, unsigned int dst_off, unsigned int len,
421 u8 **bufs, int whence, unsigned int counter, u8 pattern,
422 bool is_srcbuf)
423{
424 struct dmatest_verify_result *vr;
425 unsigned int error_count;
426 unsigned int buf_off = is_srcbuf ? src_off : dst_off;
427 unsigned int start, end;
428
429 if (whence < 0) {
430 start = 0;
431 end = buf_off;
432 } else if (whence > 0) {
433 start = buf_off + len;
434 end = info->params.buf_size;
435 } else {
436 start = buf_off;
437 end = buf_off + len;
438 }
439
440 vr = kmalloc(sizeof(*vr), GFP_KERNEL);
441 if (!vr) {
442 pr_warn("dmatest: No memory to store verify result\n");
443 return dmatest_verify(NULL, bufs, start, end, counter, pattern,
444 is_srcbuf);
445 }
446
447 vr->pattern = pattern;
448 vr->is_srcbuf = is_srcbuf;
449
450 error_count = dmatest_verify(vr, bufs, start, end, counter, pattern,
451 is_srcbuf);
452 if (error_count) {
453 vr->error_count = error_count;
454 thread_result_add(info, r, DMATEST_ET_VERIFY_BUF, n, src_off,
455 dst_off, len, (unsigned long)vr);
456 return error_count;
457 }
458
459 kfree(vr);
460 return 0;
461}
462
463static void result_free(struct dmatest_info *info, const char *name) 396static void result_free(struct dmatest_info *info, const char *name)
464{ 397{
465 struct dmatest_result *r, *_r; 398 struct dmatest_result *r, *_r;
@@ -472,8 +405,6 @@ static void result_free(struct dmatest_info *info, const char *name)
472 continue; 405 continue;
473 406
474 list_for_each_entry_safe(tr, _tr, &r->results, node) { 407 list_for_each_entry_safe(tr, _tr, &r->results, node) {
475 if (tr->type == DMATEST_ET_VERIFY_BUF)
476 kfree(tr->vr);
477 list_del(&tr->node); 408 list_del(&tr->node);
478 kfree(tr); 409 kfree(tr);
479 } 410 }
@@ -755,26 +686,25 @@ static int dmatest_func(void *data)
755 error_count = 0; 686 error_count = 0;
756 687
757 pr_debug("%s: verifying source buffer...\n", thread_name); 688 pr_debug("%s: verifying source buffer...\n", thread_name);
758 error_count += verify_result_add(info, result, total_tests, 689 error_count += dmatest_verify(thread->srcs, 0, src_off,
759 src_off, dst_off, len, thread->srcs, -1,
760 0, PATTERN_SRC, true); 690 0, PATTERN_SRC, true);
761 error_count += verify_result_add(info, result, total_tests, 691 error_count += dmatest_verify(thread->srcs, src_off,
762 src_off, dst_off, len, thread->srcs, 0, 692 src_off + len, src_off,
763 src_off, PATTERN_SRC | PATTERN_COPY, true); 693 PATTERN_SRC | PATTERN_COPY, true);
764 error_count += verify_result_add(info, result, total_tests, 694 error_count += dmatest_verify(thread->srcs, src_off + len,
765 src_off, dst_off, len, thread->srcs, 1, 695 params->buf_size, src_off + len,
766 src_off + len, PATTERN_SRC, true); 696 PATTERN_SRC, true);
767 697
768 pr_debug("%s: verifying dest buffer...\n", thread_name); 698 pr_debug("%s: verifying dest buffer...\n",
769 error_count += verify_result_add(info, result, total_tests, 699 thread->task->comm);
770 src_off, dst_off, len, thread->dsts, -1, 700 error_count += dmatest_verify(thread->dsts, 0, dst_off,
771 0, PATTERN_DST, false); 701 0, PATTERN_DST, false);
772 error_count += verify_result_add(info, result, total_tests, 702 error_count += dmatest_verify(thread->dsts, dst_off,
773 src_off, dst_off, len, thread->dsts, 0, 703 dst_off + len, src_off,
774 src_off, PATTERN_SRC | PATTERN_COPY, false); 704 PATTERN_SRC | PATTERN_COPY, false);
775 error_count += verify_result_add(info, result, total_tests, 705 error_count += dmatest_verify(thread->dsts, dst_off + len,
776 src_off, dst_off, len, thread->dsts, 1, 706 params->buf_size, dst_off + len,
777 dst_off + len, PATTERN_DST, false); 707 PATTERN_DST, false);
778 708
779 if (error_count) { 709 if (error_count) {
780 thread_result_add(info, result, DMATEST_ET_VERIFY, 710 thread_result_add(info, result, DMATEST_ET_VERIFY,
@@ -1099,20 +1029,12 @@ static int dtf_results_show(struct seq_file *sf, void *data)
1099 struct dmatest_info *info = sf->private; 1029 struct dmatest_info *info = sf->private;
1100 struct dmatest_result *result; 1030 struct dmatest_result *result;
1101 struct dmatest_thread_result *tr; 1031 struct dmatest_thread_result *tr;
1102 unsigned int i;
1103 1032
1104 mutex_lock(&info->results_lock); 1033 mutex_lock(&info->results_lock);
1105 list_for_each_entry(result, &info->results, node) { 1034 list_for_each_entry(result, &info->results, node) {
1106 list_for_each_entry(tr, &result->results, node) { 1035 list_for_each_entry(tr, &result->results, node)
1107 seq_printf(sf, "%s\n", 1036 seq_printf(sf, "%s\n",
1108 thread_result_get(result->name, tr)); 1037 thread_result_get(result->name, tr));
1109 if (tr->type == DMATEST_ET_VERIFY_BUF) {
1110 for (i = 0; i < tr->vr->error_count; i++) {
1111 seq_printf(sf, "\t%s\n",
1112 verify_result_get_one(tr->vr, i));
1113 }
1114 }
1115 }
1116 } 1038 }
1117 1039
1118 mutex_unlock(&info->results_lock); 1040 mutex_unlock(&info->results_lock);