diff options
Diffstat (limited to 'drivers/dma/dmatest.c')
| -rw-r--r-- | drivers/dma/dmatest.c | 110 |
1 files changed, 59 insertions, 51 deletions
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index a07ef3d6b3ec..34ff53290b03 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c | |||
| @@ -52,15 +52,10 @@ module_param(iterations, uint, S_IRUGO | S_IWUSR); | |||
| 52 | MODULE_PARM_DESC(iterations, | 52 | MODULE_PARM_DESC(iterations, |
| 53 | "Iterations before stopping test (default: infinite)"); | 53 | "Iterations before stopping test (default: infinite)"); |
| 54 | 54 | ||
| 55 | static unsigned int sg_buffers = 1; | ||
| 56 | module_param(sg_buffers, uint, S_IRUGO | S_IWUSR); | ||
| 57 | MODULE_PARM_DESC(sg_buffers, | ||
| 58 | "Number of scatter gather buffers (default: 1)"); | ||
| 59 | |||
| 60 | static unsigned int dmatest; | 55 | static unsigned int dmatest; |
| 61 | module_param(dmatest, uint, S_IRUGO | S_IWUSR); | 56 | module_param(dmatest, uint, S_IRUGO | S_IWUSR); |
| 62 | MODULE_PARM_DESC(dmatest, | 57 | MODULE_PARM_DESC(dmatest, |
| 63 | "dmatest 0-memcpy 1-slave_sg (default: 0)"); | 58 | "dmatest 0-memcpy 1-memset (default: 0)"); |
| 64 | 59 | ||
| 65 | static unsigned int xor_sources = 3; | 60 | static unsigned int xor_sources = 3; |
| 66 | module_param(xor_sources, uint, S_IRUGO | S_IWUSR); | 61 | module_param(xor_sources, uint, S_IRUGO | S_IWUSR); |
| @@ -158,6 +153,7 @@ MODULE_PARM_DESC(run, "Run the test (default: false)"); | |||
| 158 | #define PATTERN_COPY 0x40 | 153 | #define PATTERN_COPY 0x40 |
| 159 | #define PATTERN_OVERWRITE 0x20 | 154 | #define PATTERN_OVERWRITE 0x20 |
| 160 | #define PATTERN_COUNT_MASK 0x1f | 155 | #define PATTERN_COUNT_MASK 0x1f |
| 156 | #define PATTERN_MEMSET_IDX 0x01 | ||
| 161 | 157 | ||
| 162 | struct dmatest_thread { | 158 | struct dmatest_thread { |
| 163 | struct list_head node; | 159 | struct list_head node; |
| @@ -239,46 +235,62 @@ static unsigned long dmatest_random(void) | |||
| 239 | return buf; | 235 | return buf; |
| 240 | } | 236 | } |
| 241 | 237 | ||
| 238 | static inline u8 gen_inv_idx(u8 index, bool is_memset) | ||
| 239 | { | ||
| 240 | u8 val = is_memset ? PATTERN_MEMSET_IDX : index; | ||
| 241 | |||
| 242 | return ~val & PATTERN_COUNT_MASK; | ||
| 243 | } | ||
| 244 | |||
| 245 | static inline u8 gen_src_value(u8 index, bool is_memset) | ||
| 246 | { | ||
| 247 | return PATTERN_SRC | gen_inv_idx(index, is_memset); | ||
| 248 | } | ||
| 249 | |||
| 250 | static inline u8 gen_dst_value(u8 index, bool is_memset) | ||
| 251 | { | ||
| 252 | return PATTERN_DST | gen_inv_idx(index, is_memset); | ||
| 253 | } | ||
| 254 | |||
| 242 | static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len, | 255 | static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len, |
| 243 | unsigned int buf_size) | 256 | unsigned int buf_size, bool is_memset) |
| 244 | { | 257 | { |
| 245 | unsigned int i; | 258 | unsigned int i; |
| 246 | u8 *buf; | 259 | u8 *buf; |
| 247 | 260 | ||
| 248 | for (; (buf = *bufs); bufs++) { | 261 | for (; (buf = *bufs); bufs++) { |
| 249 | for (i = 0; i < start; i++) | 262 | for (i = 0; i < start; i++) |
| 250 | buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK); | 263 | buf[i] = gen_src_value(i, is_memset); |
| 251 | for ( ; i < start + len; i++) | 264 | for ( ; i < start + len; i++) |
| 252 | buf[i] = PATTERN_SRC | PATTERN_COPY | 265 | buf[i] = gen_src_value(i, is_memset) | PATTERN_COPY; |
| 253 | | (~i & PATTERN_COUNT_MASK); | ||
| 254 | for ( ; i < buf_size; i++) | 266 | for ( ; i < buf_size; i++) |
| 255 | buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK); | 267 | buf[i] = gen_src_value(i, is_memset); |
| 256 | buf++; | 268 | buf++; |
| 257 | } | 269 | } |
| 258 | } | 270 | } |
| 259 | 271 | ||
| 260 | static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len, | 272 | static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len, |
| 261 | unsigned int buf_size) | 273 | unsigned int buf_size, bool is_memset) |
| 262 | { | 274 | { |
| 263 | unsigned int i; | 275 | unsigned int i; |
| 264 | u8 *buf; | 276 | u8 *buf; |
| 265 | 277 | ||
| 266 | for (; (buf = *bufs); bufs++) { | 278 | for (; (buf = *bufs); bufs++) { |
| 267 | for (i = 0; i < start; i++) | 279 | for (i = 0; i < start; i++) |
| 268 | buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK); | 280 | buf[i] = gen_dst_value(i, is_memset); |
| 269 | for ( ; i < start + len; i++) | 281 | for ( ; i < start + len; i++) |
| 270 | buf[i] = PATTERN_DST | PATTERN_OVERWRITE | 282 | buf[i] = gen_dst_value(i, is_memset) | |
| 271 | | (~i & PATTERN_COUNT_MASK); | 283 | PATTERN_OVERWRITE; |
| 272 | for ( ; i < buf_size; i++) | 284 | for ( ; i < buf_size; i++) |
| 273 | buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK); | 285 | buf[i] = gen_dst_value(i, is_memset); |
| 274 | } | 286 | } |
| 275 | } | 287 | } |
| 276 | 288 | ||
| 277 | static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index, | 289 | static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index, |
| 278 | unsigned int counter, bool is_srcbuf) | 290 | unsigned int counter, bool is_srcbuf, bool is_memset) |
| 279 | { | 291 | { |
| 280 | u8 diff = actual ^ pattern; | 292 | u8 diff = actual ^ pattern; |
| 281 | u8 expected = pattern | (~counter & PATTERN_COUNT_MASK); | 293 | u8 expected = pattern | gen_inv_idx(counter, is_memset); |
| 282 | const char *thread_name = current->comm; | 294 | const char *thread_name = current->comm; |
| 283 | 295 | ||
| 284 | if (is_srcbuf) | 296 | if (is_srcbuf) |
| @@ -298,7 +310,7 @@ static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index, | |||
| 298 | 310 | ||
| 299 | static unsigned int dmatest_verify(u8 **bufs, unsigned int start, | 311 | static unsigned int dmatest_verify(u8 **bufs, unsigned int start, |
| 300 | unsigned int end, unsigned int counter, u8 pattern, | 312 | unsigned int end, unsigned int counter, u8 pattern, |
| 301 | bool is_srcbuf) | 313 | bool is_srcbuf, bool is_memset) |
| 302 | { | 314 | { |
| 303 | unsigned int i; | 315 | unsigned int i; |
| 304 | unsigned int error_count = 0; | 316 | unsigned int error_count = 0; |
| @@ -311,11 +323,12 @@ static unsigned int dmatest_verify(u8 **bufs, unsigned int start, | |||
| 311 | counter = counter_orig; | 323 | counter = counter_orig; |
| 312 | for (i = start; i < end; i++) { | 324 | for (i = start; i < end; i++) { |
| 313 | actual = buf[i]; | 325 | actual = buf[i]; |
| 314 | expected = pattern | (~counter & PATTERN_COUNT_MASK); | 326 | expected = pattern | gen_inv_idx(counter, is_memset); |
| 315 | if (actual != expected) { | 327 | if (actual != expected) { |
| 316 | if (error_count < MAX_ERROR_COUNT) | 328 | if (error_count < MAX_ERROR_COUNT) |
| 317 | dmatest_mismatch(actual, pattern, i, | 329 | dmatest_mismatch(actual, pattern, i, |
| 318 | counter, is_srcbuf); | 330 | counter, is_srcbuf, |
| 331 | is_memset); | ||
| 319 | error_count++; | 332 | error_count++; |
| 320 | } | 333 | } |
| 321 | counter++; | 334 | counter++; |
| @@ -435,6 +448,7 @@ static int dmatest_func(void *data) | |||
| 435 | s64 runtime = 0; | 448 | s64 runtime = 0; |
| 436 | unsigned long long total_len = 0; | 449 | unsigned long long total_len = 0; |
| 437 | u8 align = 0; | 450 | u8 align = 0; |
| 451 | bool is_memset = false; | ||
| 438 | 452 | ||
| 439 | set_freezable(); | 453 | set_freezable(); |
| 440 | 454 | ||
| @@ -448,9 +462,10 @@ static int dmatest_func(void *data) | |||
| 448 | if (thread->type == DMA_MEMCPY) { | 462 | if (thread->type == DMA_MEMCPY) { |
| 449 | align = dev->copy_align; | 463 | align = dev->copy_align; |
| 450 | src_cnt = dst_cnt = 1; | 464 | src_cnt = dst_cnt = 1; |
| 451 | } else if (thread->type == DMA_SG) { | 465 | } else if (thread->type == DMA_MEMSET) { |
| 452 | align = dev->copy_align; | 466 | align = dev->fill_align; |
| 453 | src_cnt = dst_cnt = sg_buffers; | 467 | src_cnt = dst_cnt = 1; |
| 468 | is_memset = true; | ||
| 454 | } else if (thread->type == DMA_XOR) { | 469 | } else if (thread->type == DMA_XOR) { |
| 455 | /* force odd to ensure dst = src */ | 470 | /* force odd to ensure dst = src */ |
| 456 | src_cnt = min_odd(params->xor_sources | 1, dev->max_xor); | 471 | src_cnt = min_odd(params->xor_sources | 1, dev->max_xor); |
| @@ -530,8 +545,6 @@ static int dmatest_func(void *data) | |||
| 530 | dma_addr_t srcs[src_cnt]; | 545 | dma_addr_t srcs[src_cnt]; |
| 531 | dma_addr_t *dsts; | 546 | dma_addr_t *dsts; |
| 532 | unsigned int src_off, dst_off, len; | 547 | unsigned int src_off, dst_off, len; |
| 533 | struct scatterlist tx_sg[src_cnt]; | ||
| 534 | struct scatterlist rx_sg[src_cnt]; | ||
| 535 | 548 | ||
| 536 | total_tests++; | 549 | total_tests++; |
| 537 | 550 | ||
| @@ -571,9 +584,9 @@ static int dmatest_func(void *data) | |||
| 571 | dst_off = (dst_off >> align) << align; | 584 | dst_off = (dst_off >> align) << align; |
| 572 | 585 | ||
| 573 | dmatest_init_srcs(thread->srcs, src_off, len, | 586 | dmatest_init_srcs(thread->srcs, src_off, len, |
| 574 | params->buf_size); | 587 | params->buf_size, is_memset); |
| 575 | dmatest_init_dsts(thread->dsts, dst_off, len, | 588 | dmatest_init_dsts(thread->dsts, dst_off, len, |
| 576 | params->buf_size); | 589 | params->buf_size, is_memset); |
| 577 | 590 | ||
| 578 | diff = ktime_sub(ktime_get(), start); | 591 | diff = ktime_sub(ktime_get(), start); |
| 579 | filltime = ktime_add(filltime, diff); | 592 | filltime = ktime_add(filltime, diff); |
| @@ -627,22 +640,15 @@ static int dmatest_func(void *data) | |||
| 627 | um->bidi_cnt++; | 640 | um->bidi_cnt++; |
| 628 | } | 641 | } |
| 629 | 642 | ||
| 630 | sg_init_table(tx_sg, src_cnt); | ||
| 631 | sg_init_table(rx_sg, src_cnt); | ||
| 632 | for (i = 0; i < src_cnt; i++) { | ||
| 633 | sg_dma_address(&rx_sg[i]) = srcs[i]; | ||
| 634 | sg_dma_address(&tx_sg[i]) = dsts[i] + dst_off; | ||
| 635 | sg_dma_len(&tx_sg[i]) = len; | ||
| 636 | sg_dma_len(&rx_sg[i]) = len; | ||
| 637 | } | ||
| 638 | |||
| 639 | if (thread->type == DMA_MEMCPY) | 643 | if (thread->type == DMA_MEMCPY) |
| 640 | tx = dev->device_prep_dma_memcpy(chan, | 644 | tx = dev->device_prep_dma_memcpy(chan, |
| 641 | dsts[0] + dst_off, | 645 | dsts[0] + dst_off, |
| 642 | srcs[0], len, flags); | 646 | srcs[0], len, flags); |
| 643 | else if (thread->type == DMA_SG) | 647 | else if (thread->type == DMA_MEMSET) |
| 644 | tx = dev->device_prep_dma_sg(chan, tx_sg, src_cnt, | 648 | tx = dev->device_prep_dma_memset(chan, |
| 645 | rx_sg, src_cnt, flags); | 649 | dsts[0] + dst_off, |
| 650 | *(thread->srcs[0] + src_off), | ||
| 651 | len, flags); | ||
| 646 | else if (thread->type == DMA_XOR) | 652 | else if (thread->type == DMA_XOR) |
| 647 | tx = dev->device_prep_dma_xor(chan, | 653 | tx = dev->device_prep_dma_xor(chan, |
| 648 | dsts[0] + dst_off, | 654 | dsts[0] + dst_off, |
| @@ -722,23 +728,25 @@ static int dmatest_func(void *data) | |||
| 722 | start = ktime_get(); | 728 | start = ktime_get(); |
| 723 | pr_debug("%s: verifying source buffer...\n", current->comm); | 729 | pr_debug("%s: verifying source buffer...\n", current->comm); |
| 724 | error_count = dmatest_verify(thread->srcs, 0, src_off, | 730 | error_count = dmatest_verify(thread->srcs, 0, src_off, |
| 725 | 0, PATTERN_SRC, true); | 731 | 0, PATTERN_SRC, true, is_memset); |
| 726 | error_count += dmatest_verify(thread->srcs, src_off, | 732 | error_count += dmatest_verify(thread->srcs, src_off, |
| 727 | src_off + len, src_off, | 733 | src_off + len, src_off, |
| 728 | PATTERN_SRC | PATTERN_COPY, true); | 734 | PATTERN_SRC | PATTERN_COPY, true, is_memset); |
| 729 | error_count += dmatest_verify(thread->srcs, src_off + len, | 735 | error_count += dmatest_verify(thread->srcs, src_off + len, |
| 730 | params->buf_size, src_off + len, | 736 | params->buf_size, src_off + len, |
| 731 | PATTERN_SRC, true); | 737 | PATTERN_SRC, true, is_memset); |
| 732 | 738 | ||
| 733 | pr_debug("%s: verifying dest buffer...\n", current->comm); | 739 | pr_debug("%s: verifying dest buffer...\n", current->comm); |
| 734 | error_count += dmatest_verify(thread->dsts, 0, dst_off, | 740 | error_count += dmatest_verify(thread->dsts, 0, dst_off, |
| 735 | 0, PATTERN_DST, false); | 741 | 0, PATTERN_DST, false, is_memset); |
| 742 | |||
| 736 | error_count += dmatest_verify(thread->dsts, dst_off, | 743 | error_count += dmatest_verify(thread->dsts, dst_off, |
| 737 | dst_off + len, src_off, | 744 | dst_off + len, src_off, |
| 738 | PATTERN_SRC | PATTERN_COPY, false); | 745 | PATTERN_SRC | PATTERN_COPY, false, is_memset); |
| 746 | |||
| 739 | error_count += dmatest_verify(thread->dsts, dst_off + len, | 747 | error_count += dmatest_verify(thread->dsts, dst_off + len, |
| 740 | params->buf_size, dst_off + len, | 748 | params->buf_size, dst_off + len, |
| 741 | PATTERN_DST, false); | 749 | PATTERN_DST, false, is_memset); |
| 742 | 750 | ||
| 743 | diff = ktime_sub(ktime_get(), start); | 751 | diff = ktime_sub(ktime_get(), start); |
| 744 | comparetime = ktime_add(comparetime, diff); | 752 | comparetime = ktime_add(comparetime, diff); |
| @@ -821,8 +829,8 @@ static int dmatest_add_threads(struct dmatest_info *info, | |||
| 821 | 829 | ||
| 822 | if (type == DMA_MEMCPY) | 830 | if (type == DMA_MEMCPY) |
| 823 | op = "copy"; | 831 | op = "copy"; |
| 824 | else if (type == DMA_SG) | 832 | else if (type == DMA_MEMSET) |
| 825 | op = "sg"; | 833 | op = "set"; |
| 826 | else if (type == DMA_XOR) | 834 | else if (type == DMA_XOR) |
| 827 | op = "xor"; | 835 | op = "xor"; |
| 828 | else if (type == DMA_PQ) | 836 | else if (type == DMA_PQ) |
| @@ -883,9 +891,9 @@ static int dmatest_add_channel(struct dmatest_info *info, | |||
| 883 | } | 891 | } |
| 884 | } | 892 | } |
| 885 | 893 | ||
| 886 | if (dma_has_cap(DMA_SG, dma_dev->cap_mask)) { | 894 | if (dma_has_cap(DMA_MEMSET, dma_dev->cap_mask)) { |
| 887 | if (dmatest == 1) { | 895 | if (dmatest == 1) { |
| 888 | cnt = dmatest_add_threads(info, dtc, DMA_SG); | 896 | cnt = dmatest_add_threads(info, dtc, DMA_MEMSET); |
| 889 | thread_count += cnt > 0 ? cnt : 0; | 897 | thread_count += cnt > 0 ? cnt : 0; |
| 890 | } | 898 | } |
| 891 | } | 899 | } |
| @@ -961,8 +969,8 @@ static void run_threaded_test(struct dmatest_info *info) | |||
| 961 | params->noverify = noverify; | 969 | params->noverify = noverify; |
| 962 | 970 | ||
| 963 | request_channels(info, DMA_MEMCPY); | 971 | request_channels(info, DMA_MEMCPY); |
| 972 | request_channels(info, DMA_MEMSET); | ||
| 964 | request_channels(info, DMA_XOR); | 973 | request_channels(info, DMA_XOR); |
| 965 | request_channels(info, DMA_SG); | ||
| 966 | request_channels(info, DMA_PQ); | 974 | request_channels(info, DMA_PQ); |
| 967 | } | 975 | } |
| 968 | 976 | ||
