Skip to content

Commit 61b5f54

Browse files
Sinan KayaVinod Koul
authored andcommitted
dmaengine: dmatest: add support for memset test
Introducing memset test into dmatest. This change allows us to test memset capable HW using the dmatest test procedure. The new dmatest value for memset is 2 and it is not the default value. Memset support patch shares the same code path as the other dmatest code to reuse as much as we can. The first value inside the source buffer is used as a pattern to fill in the destination buffer space. Prior to running the test, source/destination buffers are initialized in the current code. "The remaining bits are the inverse of a counter which increments by one for each byte address." Memset test will fill in the upper bits of pattern with the inverse of fixed counter value 1 as opposed to an incrementing value in a loop. An example run is as follows: echo dma0chan0 > /sys/module/dmatest/parameters/channel echo 2 > /sys/module/dmatest/parameters/dmatest echo 2000 > /sys/module/dmatest/parameters/timeout echo 10 > /sys/module/dmatest/parameters/iterations echo 1 > /sys/module/dmatest/parameters/run Reviewed-by: Andy Shevchenko <[email protected]> Signed-off-by: Sinan Kaya <[email protected]> Signed-off-by: Vinod Koul <[email protected]>
1 parent 5771a8c commit 61b5f54

File tree

1 file changed

+64
-24
lines changed

1 file changed

+64
-24
lines changed

drivers/dma/dmatest.c

Lines changed: 64 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ MODULE_PARM_DESC(sg_buffers,
6060
static unsigned int dmatest;
6161
module_param(dmatest, uint, S_IRUGO | S_IWUSR);
6262
MODULE_PARM_DESC(dmatest,
63-
"dmatest 0-memcpy 1-slave_sg (default: 0)");
63+
"dmatest 0-memcpy 1-slave_sg 2-memset (default: 0)");
6464

6565
static unsigned int xor_sources = 3;
6666
module_param(xor_sources, uint, S_IRUGO | S_IWUSR);
@@ -158,6 +158,7 @@ MODULE_PARM_DESC(run, "Run the test (default: false)");
158158
#define PATTERN_COPY 0x40
159159
#define PATTERN_OVERWRITE 0x20
160160
#define PATTERN_COUNT_MASK 0x1f
161+
#define PATTERN_MEMSET_IDX 0x01
161162

162163
struct dmatest_thread {
163164
struct list_head node;
@@ -239,46 +240,62 @@ static unsigned long dmatest_random(void)
239240
return buf;
240241
}
241242

243+
static inline u8 gen_inv_idx(u8 index, bool is_memset)
244+
{
245+
u8 val = is_memset ? PATTERN_MEMSET_IDX : index;
246+
247+
return ~val & PATTERN_COUNT_MASK;
248+
}
249+
250+
static inline u8 gen_src_value(u8 index, bool is_memset)
251+
{
252+
return PATTERN_SRC | gen_inv_idx(index, is_memset);
253+
}
254+
255+
static inline u8 gen_dst_value(u8 index, bool is_memset)
256+
{
257+
return PATTERN_DST | gen_inv_idx(index, is_memset);
258+
}
259+
242260
static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len,
243-
unsigned int buf_size)
261+
unsigned int buf_size, bool is_memset)
244262
{
245263
unsigned int i;
246264
u8 *buf;
247265

248266
for (; (buf = *bufs); bufs++) {
249267
for (i = 0; i < start; i++)
250-
buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
268+
buf[i] = gen_src_value(i, is_memset);
251269
for ( ; i < start + len; i++)
252-
buf[i] = PATTERN_SRC | PATTERN_COPY
253-
| (~i & PATTERN_COUNT_MASK);
270+
buf[i] = gen_src_value(i, is_memset) | PATTERN_COPY;
254271
for ( ; i < buf_size; i++)
255-
buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
272+
buf[i] = gen_src_value(i, is_memset);
256273
buf++;
257274
}
258275
}
259276

260277
static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len,
261-
unsigned int buf_size)
278+
unsigned int buf_size, bool is_memset)
262279
{
263280
unsigned int i;
264281
u8 *buf;
265282

266283
for (; (buf = *bufs); bufs++) {
267284
for (i = 0; i < start; i++)
268-
buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
285+
buf[i] = gen_dst_value(i, is_memset);
269286
for ( ; i < start + len; i++)
270-
buf[i] = PATTERN_DST | PATTERN_OVERWRITE
271-
| (~i & PATTERN_COUNT_MASK);
287+
buf[i] = gen_dst_value(i, is_memset) |
288+
PATTERN_OVERWRITE;
272289
for ( ; i < buf_size; i++)
273-
buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
290+
buf[i] = gen_dst_value(i, is_memset);
274291
}
275292
}
276293

277294
static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
278-
unsigned int counter, bool is_srcbuf)
295+
unsigned int counter, bool is_srcbuf, bool is_memset)
279296
{
280297
u8 diff = actual ^ pattern;
281-
u8 expected = pattern | (~counter & PATTERN_COUNT_MASK);
298+
u8 expected = pattern | gen_inv_idx(counter, is_memset);
282299
const char *thread_name = current->comm;
283300

284301
if (is_srcbuf)
@@ -298,7 +315,7 @@ static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
298315

299316
static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
300317
unsigned int end, unsigned int counter, u8 pattern,
301-
bool is_srcbuf)
318+
bool is_srcbuf, bool is_memset)
302319
{
303320
unsigned int i;
304321
unsigned int error_count = 0;
@@ -311,11 +328,12 @@ static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
311328
counter = counter_orig;
312329
for (i = start; i < end; i++) {
313330
actual = buf[i];
314-
expected = pattern | (~counter & PATTERN_COUNT_MASK);
331+
expected = pattern | gen_inv_idx(counter, is_memset);
315332
if (actual != expected) {
316333
if (error_count < MAX_ERROR_COUNT)
317334
dmatest_mismatch(actual, pattern, i,
318-
counter, is_srcbuf);
335+
counter, is_srcbuf,
336+
is_memset);
319337
error_count++;
320338
}
321339
counter++;
@@ -435,6 +453,7 @@ static int dmatest_func(void *data)
435453
s64 runtime = 0;
436454
unsigned long long total_len = 0;
437455
u8 align = 0;
456+
bool is_memset = false;
438457

439458
set_freezable();
440459

@@ -448,6 +467,10 @@ static int dmatest_func(void *data)
448467
if (thread->type == DMA_MEMCPY) {
449468
align = dev->copy_align;
450469
src_cnt = dst_cnt = 1;
470+
} else if (thread->type == DMA_MEMSET) {
471+
align = dev->fill_align;
472+
src_cnt = dst_cnt = 1;
473+
is_memset = true;
451474
} else if (thread->type == DMA_SG) {
452475
align = dev->copy_align;
453476
src_cnt = dst_cnt = sg_buffers;
@@ -571,9 +594,9 @@ static int dmatest_func(void *data)
571594
dst_off = (dst_off >> align) << align;
572595

573596
dmatest_init_srcs(thread->srcs, src_off, len,
574-
params->buf_size);
597+
params->buf_size, is_memset);
575598
dmatest_init_dsts(thread->dsts, dst_off, len,
576-
params->buf_size);
599+
params->buf_size, is_memset);
577600

578601
diff = ktime_sub(ktime_get(), start);
579602
filltime = ktime_add(filltime, diff);
@@ -640,6 +663,11 @@ static int dmatest_func(void *data)
640663
tx = dev->device_prep_dma_memcpy(chan,
641664
dsts[0] + dst_off,
642665
srcs[0], len, flags);
666+
else if (thread->type == DMA_MEMSET)
667+
tx = dev->device_prep_dma_memset(chan,
668+
dsts[0] + dst_off,
669+
*(thread->srcs[0] + src_off),
670+
len, flags);
643671
else if (thread->type == DMA_SG)
644672
tx = dev->device_prep_dma_sg(chan, tx_sg, src_cnt,
645673
rx_sg, src_cnt, flags);
@@ -722,23 +750,25 @@ static int dmatest_func(void *data)
722750
start = ktime_get();
723751
pr_debug("%s: verifying source buffer...\n", current->comm);
724752
error_count = dmatest_verify(thread->srcs, 0, src_off,
725-
0, PATTERN_SRC, true);
753+
0, PATTERN_SRC, true, is_memset);
726754
error_count += dmatest_verify(thread->srcs, src_off,
727755
src_off + len, src_off,
728-
PATTERN_SRC | PATTERN_COPY, true);
756+
PATTERN_SRC | PATTERN_COPY, true, is_memset);
729757
error_count += dmatest_verify(thread->srcs, src_off + len,
730758
params->buf_size, src_off + len,
731-
PATTERN_SRC, true);
759+
PATTERN_SRC, true, is_memset);
732760

733761
pr_debug("%s: verifying dest buffer...\n", current->comm);
734762
error_count += dmatest_verify(thread->dsts, 0, dst_off,
735-
0, PATTERN_DST, false);
763+
0, PATTERN_DST, false, is_memset);
764+
736765
error_count += dmatest_verify(thread->dsts, dst_off,
737766
dst_off + len, src_off,
738-
PATTERN_SRC | PATTERN_COPY, false);
767+
PATTERN_SRC | PATTERN_COPY, false, is_memset);
768+
739769
error_count += dmatest_verify(thread->dsts, dst_off + len,
740770
params->buf_size, dst_off + len,
741-
PATTERN_DST, false);
771+
PATTERN_DST, false, is_memset);
742772

743773
diff = ktime_sub(ktime_get(), start);
744774
comparetime = ktime_add(comparetime, diff);
@@ -821,6 +851,8 @@ static int dmatest_add_threads(struct dmatest_info *info,
821851

822852
if (type == DMA_MEMCPY)
823853
op = "copy";
854+
else if (type == DMA_MEMSET)
855+
op = "set";
824856
else if (type == DMA_SG)
825857
op = "sg";
826858
else if (type == DMA_XOR)
@@ -883,6 +915,13 @@ static int dmatest_add_channel(struct dmatest_info *info,
883915
}
884916
}
885917

918+
if (dma_has_cap(DMA_MEMSET, dma_dev->cap_mask)) {
919+
if (dmatest == 2) {
920+
cnt = dmatest_add_threads(info, dtc, DMA_MEMSET);
921+
thread_count += cnt > 0 ? cnt : 0;
922+
}
923+
}
924+
886925
if (dma_has_cap(DMA_SG, dma_dev->cap_mask)) {
887926
if (dmatest == 1) {
888927
cnt = dmatest_add_threads(info, dtc, DMA_SG);
@@ -961,6 +1000,7 @@ static void run_threaded_test(struct dmatest_info *info)
9611000
params->noverify = noverify;
9621001

9631002
request_channels(info, DMA_MEMCPY);
1003+
request_channels(info, DMA_MEMSET);
9641004
request_channels(info, DMA_XOR);
9651005
request_channels(info, DMA_SG);
9661006
request_channels(info, DMA_PQ);

0 commit comments

Comments
 (0)