Skip to content

Commit d86b2f2

Browse files
andy-shevVinod Koul
authored andcommitted
dmatest: append verify result to results
Comparison between buffers is stored to the dedicated structure. Note that the verify result is now accessible only via file 'results' in the debugfs. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
1 parent 95019c8 commit d86b2f2

File tree

2 files changed

+132
-56
lines changed

2 files changed

+132
-56
lines changed

Documentation/dmatest.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,7 @@ The message format is unified across the different types of errors. A number in
7575
the parens represents additional information, e.g. error code, error counter,
7676
or status.
7777

78-
Note that the buffer comparison is done in the old way, i.e. data is not
79-
collected and just printed out.
78+
Comparison between buffers is stored to the dedicated structure.
79+
80+
Note that the verify result is now accessible only via file 'results' in the
81+
debugfs.

drivers/dma/dmatest.c

Lines changed: 128 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,20 @@ enum dmatest_error_type {
9696
DMATEST_ET_DMA_ERROR,
9797
DMATEST_ET_DMA_IN_PROGRESS,
9898
DMATEST_ET_VERIFY,
99+
DMATEST_ET_VERIFY_BUF,
100+
};
101+
102+
struct dmatest_verify_buffer {
103+
unsigned int index;
104+
u8 expected;
105+
u8 actual;
106+
};
107+
108+
struct dmatest_verify_result {
109+
unsigned int error_count;
110+
struct dmatest_verify_buffer data[MAX_ERROR_COUNT];
111+
u8 pattern;
112+
bool is_srcbuf;
99113
};
100114

101115
struct dmatest_thread_result {
@@ -106,10 +120,11 @@ struct dmatest_thread_result {
106120
unsigned int len;
107121
enum dmatest_error_type type;
108122
union {
109-
unsigned long data;
110-
dma_cookie_t cookie;
111-
enum dma_status status;
112-
int error;
123+
unsigned long data;
124+
dma_cookie_t cookie;
125+
enum dma_status status;
126+
int error;
127+
struct dmatest_verify_result *vr;
113128
};
114129
};
115130

@@ -246,52 +261,30 @@ static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len,
246261
}
247262
}
248263

249-
static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
250-
unsigned int counter, bool is_srcbuf)
251-
{
252-
u8 diff = actual ^ pattern;
253-
u8 expected = pattern | (~counter & PATTERN_COUNT_MASK);
254-
const char *thread_name = current->comm;
255-
256-
if (is_srcbuf)
257-
pr_warning("%s: srcbuf[0x%x] overwritten!"
258-
" 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_warning("%s: dstbuf[0x%x] not copied!"
263-
" Expected %02x, got %02x\n",
264-
thread_name, index, expected, actual);
265-
else if (diff & PATTERN_SRC)
266-
pr_warning("%s: dstbuf[0x%x] was copied!"
267-
" Expected %02x, got %02x\n",
268-
thread_name, index, expected, actual);
269-
else
270-
pr_warning("%s: dstbuf[0x%x] mismatch!"
271-
" Expected %02x, got %02x\n",
272-
thread_name, index, expected, actual);
273-
}
274-
275-
static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
276-
unsigned int end, unsigned int counter, u8 pattern,
277-
bool is_srcbuf)
264+
static unsigned int dmatest_verify(struct dmatest_verify_result *vr, u8 **bufs,
265+
unsigned int start, unsigned int end, unsigned int counter,
266+
u8 pattern, bool is_srcbuf)
278267
{
279268
unsigned int i;
280269
unsigned int error_count = 0;
281270
u8 actual;
282271
u8 expected;
283272
u8 *buf;
284273
unsigned int counter_orig = counter;
274+
struct dmatest_verify_buffer *vb;
285275

286276
for (; (buf = *bufs); bufs++) {
287277
counter = counter_orig;
288278
for (i = start; i < end; i++) {
289279
actual = buf[i];
290280
expected = pattern | (~counter & PATTERN_COUNT_MASK);
291281
if (actual != expected) {
292-
if (error_count < MAX_ERROR_COUNT)
293-
dmatest_mismatch(actual, pattern, i,
294-
counter, is_srcbuf);
282+
if (error_count < MAX_ERROR_COUNT && vr) {
283+
vb = &vr->data[error_count];
284+
vb->index = i;
285+
vb->expected = expected;
286+
vb->actual = actual;
287+
}
295288
error_count++;
296289
}
297290
counter++;
@@ -340,6 +333,30 @@ static unsigned int min_odd(unsigned int x, unsigned int y)
340333
return val % 2 ? val : val - 1;
341334
}
342335

336+
static char *verify_result_get_one(struct dmatest_verify_result *vr,
337+
unsigned int i)
338+
{
339+
struct dmatest_verify_buffer *vb = &vr->data[i];
340+
u8 diff = vb->actual ^ vr->pattern;
341+
static char buf[512];
342+
char *msg;
343+
344+
if (vr->is_srcbuf)
345+
msg = "srcbuf overwritten!";
346+
else if ((vr->pattern & PATTERN_COPY)
347+
&& (diff & (PATTERN_COPY | PATTERN_OVERWRITE)))
348+
msg = "dstbuf not copied!";
349+
else if (diff & PATTERN_SRC)
350+
msg = "dstbuf was copied!";
351+
else
352+
msg = "dstbuf mismatch!";
353+
354+
snprintf(buf, sizeof(buf) - 1, "%s [0x%x] Expected %02x, got %02x", msg,
355+
vb->index, vb->expected, vb->actual);
356+
357+
return buf;
358+
}
359+
343360
static char *thread_result_get(const char *name,
344361
struct dmatest_thread_result *tr)
345362
{
@@ -355,6 +372,7 @@ static char *thread_result_get(const char *name,
355372
[DMATEST_ET_DMA_IN_PROGRESS] =
356373
"got completion callback (DMA_IN_PROGRESS)",
357374
[DMATEST_ET_VERIFY] = "errors",
375+
[DMATEST_ET_VERIFY_BUF] = "verify errors",
358376
};
359377
static char buf[512];
360378

@@ -392,6 +410,51 @@ static int thread_result_add(struct dmatest_info *info,
392410
return 0;
393411
}
394412

413+
static unsigned int verify_result_add(struct dmatest_info *info,
414+
struct dmatest_result *r, unsigned int n,
415+
unsigned int src_off, unsigned int dst_off, unsigned int len,
416+
u8 **bufs, int whence, unsigned int counter, u8 pattern,
417+
bool is_srcbuf)
418+
{
419+
struct dmatest_verify_result *vr;
420+
unsigned int error_count;
421+
unsigned int buf_off = is_srcbuf ? src_off : dst_off;
422+
unsigned int start, end;
423+
424+
if (whence < 0) {
425+
start = 0;
426+
end = buf_off;
427+
} else if (whence > 0) {
428+
start = buf_off + len;
429+
end = info->params.buf_size;
430+
} else {
431+
start = buf_off;
432+
end = buf_off + len;
433+
}
434+
435+
vr = kmalloc(sizeof(*vr), GFP_KERNEL);
436+
if (!vr) {
437+
pr_warn("dmatest: No memory to store verify result\n");
438+
return dmatest_verify(NULL, bufs, start, end, counter, pattern,
439+
is_srcbuf);
440+
}
441+
442+
vr->pattern = pattern;
443+
vr->is_srcbuf = is_srcbuf;
444+
445+
error_count = dmatest_verify(vr, bufs, start, end, counter, pattern,
446+
is_srcbuf);
447+
if (error_count) {
448+
vr->error_count = error_count;
449+
thread_result_add(info, r, DMATEST_ET_VERIFY_BUF, n, src_off,
450+
dst_off, len, (unsigned long)vr);
451+
return error_count;
452+
}
453+
454+
kfree(vr);
455+
return 0;
456+
}
457+
395458
static void result_free(struct dmatest_info *info, const char *name)
396459
{
397460
struct dmatest_result *r, *_r;
@@ -404,6 +467,8 @@ static void result_free(struct dmatest_info *info, const char *name)
404467
continue;
405468

406469
list_for_each_entry_safe(tr, _tr, &r->results, node) {
470+
if (tr->type == DMATEST_ET_VERIFY_BUF)
471+
kfree(tr->vr);
407472
list_del(&tr->node);
408473
kfree(tr);
409474
}
@@ -687,25 +752,26 @@ static int dmatest_func(void *data)
687752
error_count = 0;
688753

689754
pr_debug("%s: verifying source buffer...\n", thread_name);
690-
error_count += dmatest_verify(thread->srcs, 0, src_off,
755+
error_count += verify_result_add(info, result, total_tests,
756+
src_off, dst_off, len, thread->srcs, -1,
691757
0, PATTERN_SRC, true);
692-
error_count += dmatest_verify(thread->srcs, src_off,
693-
src_off + len, src_off,
694-
PATTERN_SRC | PATTERN_COPY, true);
695-
error_count += dmatest_verify(thread->srcs, src_off + len,
696-
params->buf_size, src_off + len,
697-
PATTERN_SRC, true);
698-
699-
pr_debug("%s: verifying dest buffer...\n",
700-
thread->task->comm);
701-
error_count += dmatest_verify(thread->dsts, 0, dst_off,
758+
error_count += verify_result_add(info, result, total_tests,
759+
src_off, dst_off, len, thread->srcs, 0,
760+
src_off, PATTERN_SRC | PATTERN_COPY, true);
761+
error_count += verify_result_add(info, result, total_tests,
762+
src_off, dst_off, len, thread->srcs, 1,
763+
src_off + len, PATTERN_SRC, true);
764+
765+
pr_debug("%s: verifying dest buffer...\n", thread_name);
766+
error_count += verify_result_add(info, result, total_tests,
767+
src_off, dst_off, len, thread->dsts, -1,
702768
0, PATTERN_DST, false);
703-
error_count += dmatest_verify(thread->dsts, dst_off,
704-
dst_off + len, src_off,
705-
PATTERN_SRC | PATTERN_COPY, false);
706-
error_count += dmatest_verify(thread->dsts, dst_off + len,
707-
params->buf_size, dst_off + len,
708-
PATTERN_DST, false);
769+
error_count += verify_result_add(info, result, total_tests,
770+
src_off, dst_off, len, thread->dsts, 0,
771+
src_off, PATTERN_SRC | PATTERN_COPY, false);
772+
error_count += verify_result_add(info, result, total_tests,
773+
src_off, dst_off, len, thread->dsts, 1,
774+
dst_off + len, PATTERN_DST, false);
709775

710776
if (error_count) {
711777
thread_result_add(info, result, DMATEST_ET_VERIFY,
@@ -1085,12 +1151,20 @@ static int dtf_results_show(struct seq_file *sf, void *data)
10851151
struct dmatest_info *info = sf->private;
10861152
struct dmatest_result *result;
10871153
struct dmatest_thread_result *tr;
1154+
unsigned int i;
10881155

10891156
mutex_lock(&info->results_lock);
10901157
list_for_each_entry(result, &info->results, node) {
1091-
list_for_each_entry(tr, &result->results, node)
1158+
list_for_each_entry(tr, &result->results, node) {
10921159
seq_printf(sf, "%s\n",
10931160
thread_result_get(result->name, tr));
1161+
if (tr->type == DMATEST_ET_VERIFY_BUF) {
1162+
for (i = 0; i < tr->vr->error_count; i++) {
1163+
seq_printf(sf, "\t%s\n",
1164+
verify_result_get_one(tr->vr, i));
1165+
}
1166+
}
1167+
}
10941168
}
10951169

10961170
mutex_unlock(&info->results_lock);

0 commit comments

Comments
 (0)