linux/drivers/dma/dmatest.c
<<
>>
Prefs
   1/*
   2 * DMA Engine test module
   3 *
   4 * Copyright (C) 2007 Atmel Corporation
   5 * Copyright (C) 2013 Intel Corporation
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  12
  13#include <linux/delay.h>
  14#include <linux/dma-mapping.h>
  15#include <linux/dmaengine.h>
  16#include <linux/freezer.h>
  17#include <linux/init.h>
  18#include <linux/kthread.h>
  19#include <linux/sched/task.h>
  20#include <linux/module.h>
  21#include <linux/moduleparam.h>
  22#include <linux/random.h>
  23#include <linux/slab.h>
  24#include <linux/wait.h>
  25
  26static unsigned int test_buf_size = 16384;
  27module_param(test_buf_size, uint, S_IRUGO | S_IWUSR);
  28MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer");
  29
  30static char test_channel[20];
  31module_param_string(channel, test_channel, sizeof(test_channel),
  32                S_IRUGO | S_IWUSR);
  33MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)");
  34
  35static char test_device[32];
  36module_param_string(device, test_device, sizeof(test_device),
  37                S_IRUGO | S_IWUSR);
  38MODULE_PARM_DESC(device, "Bus ID of the DMA Engine to test (default: any)");
  39
  40static unsigned int threads_per_chan = 1;
  41module_param(threads_per_chan, uint, S_IRUGO | S_IWUSR);
  42MODULE_PARM_DESC(threads_per_chan,
  43                "Number of threads to start per channel (default: 1)");
  44
  45static unsigned int max_channels;
  46module_param(max_channels, uint, S_IRUGO | S_IWUSR);
  47MODULE_PARM_DESC(max_channels,
  48                "Maximum number of channels to use (default: all)");
  49
  50static unsigned int iterations;
  51module_param(iterations, uint, S_IRUGO | S_IWUSR);
  52MODULE_PARM_DESC(iterations,
  53                "Iterations before stopping test (default: infinite)");
  54
  55static unsigned int dmatest;
  56module_param(dmatest, uint, S_IRUGO | S_IWUSR);
  57MODULE_PARM_DESC(dmatest,
  58                "dmatest 0-memcpy 1-memset (default: 0)");
  59
  60static unsigned int xor_sources = 3;
  61module_param(xor_sources, uint, S_IRUGO | S_IWUSR);
  62MODULE_PARM_DESC(xor_sources,
  63                "Number of xor source buffers (default: 3)");
  64
  65static unsigned int pq_sources = 3;
  66module_param(pq_sources, uint, S_IRUGO | S_IWUSR);
  67MODULE_PARM_DESC(pq_sources,
  68                "Number of p+q source buffers (default: 3)");
  69
  70static int timeout = 3000;
  71module_param(timeout, uint, S_IRUGO | S_IWUSR);
  72MODULE_PARM_DESC(timeout, "Transfer Timeout in msec (default: 3000), "
  73                 "Pass -1 for infinite timeout");
  74
  75static bool noverify;
  76module_param(noverify, bool, S_IRUGO | S_IWUSR);
  77MODULE_PARM_DESC(noverify, "Disable data verification (default: verify)");
  78
  79static bool norandom;
  80module_param(norandom, bool, 0644);
  81MODULE_PARM_DESC(norandom, "Disable random offset setup (default: random)");
  82
  83static bool verbose;
  84module_param(verbose, bool, S_IRUGO | S_IWUSR);
  85MODULE_PARM_DESC(verbose, "Enable \"success\" result messages (default: off)");
  86
  87/**
  88 * struct dmatest_params - test parameters.
  89 * @buf_size:           size of the memcpy test buffer
  90 * @channel:            bus ID of the channel to test
  91 * @device:             bus ID of the DMA Engine to test
  92 * @threads_per_chan:   number of threads to start per channel
  93 * @max_channels:       maximum number of channels to use
  94 * @iterations:         iterations before stopping test
  95 * @xor_sources:        number of xor source buffers
  96 * @pq_sources:         number of p+q source buffers
  97 * @timeout:            transfer timeout in msec, -1 for infinite timeout
  98 */
  99struct dmatest_params {
 100        unsigned int    buf_size;
 101        char            channel[20];
 102        char            device[32];
 103        unsigned int    threads_per_chan;
 104        unsigned int    max_channels;
 105        unsigned int    iterations;
 106        unsigned int    xor_sources;
 107        unsigned int    pq_sources;
 108        int             timeout;
 109        bool            noverify;
 110        bool            norandom;
 111};
 112
 113/**
 114 * struct dmatest_info - test information.
 115 * @params:             test parameters
 116 * @lock:               access protection to the fields of this structure
 117 */
 118static struct dmatest_info {
 119        /* Test parameters */
 120        struct dmatest_params   params;
 121
 122        /* Internal state */
 123        struct list_head        channels;
 124        unsigned int            nr_channels;
 125        struct mutex            lock;
 126        bool                    did_init;
 127} test_info = {
 128        .channels = LIST_HEAD_INIT(test_info.channels),
 129        .lock = __MUTEX_INITIALIZER(test_info.lock),
 130};
 131
 132static int dmatest_run_set(const char *val, const struct kernel_param *kp);
 133static int dmatest_run_get(char *val, const struct kernel_param *kp);
 134static const struct kernel_param_ops run_ops = {
 135        .set = dmatest_run_set,
 136        .get = dmatest_run_get,
 137};
 138static bool dmatest_run;
 139module_param_cb(run, &run_ops, &dmatest_run, S_IRUGO | S_IWUSR);
 140MODULE_PARM_DESC(run, "Run the test (default: false)");
 141
 142/* Maximum amount of mismatched bytes in buffer to print */
 143#define MAX_ERROR_COUNT         32
 144
 145/*
 146 * Initialization patterns. All bytes in the source buffer has bit 7
 147 * set, all bytes in the destination buffer has bit 7 cleared.
 148 *
 149 * Bit 6 is set for all bytes which are to be copied by the DMA
 150 * engine. Bit 5 is set for all bytes which are to be overwritten by
 151 * the DMA engine.
 152 *
 153 * The remaining bits are the inverse of a counter which increments by
 154 * one for each byte address.
 155 */
 156#define PATTERN_SRC             0x80
 157#define PATTERN_DST             0x00
 158#define PATTERN_COPY            0x40
 159#define PATTERN_OVERWRITE       0x20
 160#define PATTERN_COUNT_MASK      0x1f
 161#define PATTERN_MEMSET_IDX      0x01
 162
 163/* poor man's completion - we want to use wait_event_freezable() on it */
 164struct dmatest_done {
 165        bool                    done;
 166        wait_queue_head_t       *wait;
 167};
 168
 169struct dmatest_thread {
 170        struct list_head        node;
 171        struct dmatest_info     *info;
 172        struct task_struct      *task;
 173        struct dma_chan         *chan;
 174        u8                      **srcs;
 175        u8                      **usrcs;
 176        u8                      **dsts;
 177        u8                      **udsts;
 178        enum dma_transaction_type type;
 179        wait_queue_head_t done_wait;
 180        struct dmatest_done test_done;
 181        bool                    done;
 182};
 183
 184struct dmatest_chan {
 185        struct list_head        node;
 186        struct dma_chan         *chan;
 187        struct list_head        threads;
 188};
 189
 190static DECLARE_WAIT_QUEUE_HEAD(thread_wait);
 191static bool wait;
 192
 193static bool is_threaded_test_run(struct dmatest_info *info)
 194{
 195        struct dmatest_chan *dtc;
 196
 197        list_for_each_entry(dtc, &info->channels, node) {
 198                struct dmatest_thread *thread;
 199
 200                list_for_each_entry(thread, &dtc->threads, node) {
 201                        if (!thread->done)
 202                                return true;
 203                }
 204        }
 205
 206        return false;
 207}
 208
 209static int dmatest_wait_get(char *val, const struct kernel_param *kp)
 210{
 211        struct dmatest_info *info = &test_info;
 212        struct dmatest_params *params = &info->params;
 213
 214        if (params->iterations)
 215                wait_event(thread_wait, !is_threaded_test_run(info));
 216        wait = true;
 217        return param_get_bool(val, kp);
 218}
 219
 220static const struct kernel_param_ops wait_ops = {
 221        .get = dmatest_wait_get,
 222        .set = param_set_bool,
 223};
 224module_param_cb(wait, &wait_ops, &wait, S_IRUGO);
 225MODULE_PARM_DESC(wait, "Wait for tests to complete (default: false)");
 226
 227static bool dmatest_match_channel(struct dmatest_params *params,
 228                struct dma_chan *chan)
 229{
 230        if (params->channel[0] == '\0')
 231                return true;
 232        return strcmp(dma_chan_name(chan), params->channel) == 0;
 233}
 234
 235static bool dmatest_match_device(struct dmatest_params *params,
 236                struct dma_device *device)
 237{
 238        if (params->device[0] == '\0')
 239                return true;
 240        return strcmp(dev_name(device->dev), params->device) == 0;
 241}
 242
 243static unsigned long dmatest_random(void)
 244{
 245        unsigned long buf;
 246
 247        prandom_bytes(&buf, sizeof(buf));
 248        return buf;
 249}
 250
 251static inline u8 gen_inv_idx(u8 index, bool is_memset)
 252{
 253        u8 val = is_memset ? PATTERN_MEMSET_IDX : index;
 254
 255        return ~val & PATTERN_COUNT_MASK;
 256}
 257
 258static inline u8 gen_src_value(u8 index, bool is_memset)
 259{
 260        return PATTERN_SRC | gen_inv_idx(index, is_memset);
 261}
 262
 263static inline u8 gen_dst_value(u8 index, bool is_memset)
 264{
 265        return PATTERN_DST | gen_inv_idx(index, is_memset);
 266}
 267
 268static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len,
 269                unsigned int buf_size, bool is_memset)
 270{
 271        unsigned int i;
 272        u8 *buf;
 273
 274        for (; (buf = *bufs); bufs++) {
 275                for (i = 0; i < start; i++)
 276                        buf[i] = gen_src_value(i, is_memset);
 277                for ( ; i < start + len; i++)
 278                        buf[i] = gen_src_value(i, is_memset) | PATTERN_COPY;
 279                for ( ; i < buf_size; i++)
 280                        buf[i] = gen_src_value(i, is_memset);
 281                buf++;
 282        }
 283}
 284
 285static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len,
 286                unsigned int buf_size, bool is_memset)
 287{
 288        unsigned int i;
 289        u8 *buf;
 290
 291        for (; (buf = *bufs); bufs++) {
 292                for (i = 0; i < start; i++)
 293                        buf[i] = gen_dst_value(i, is_memset);
 294                for ( ; i < start + len; i++)
 295                        buf[i] = gen_dst_value(i, is_memset) |
 296                                                PATTERN_OVERWRITE;
 297                for ( ; i < buf_size; i++)
 298                        buf[i] = gen_dst_value(i, is_memset);
 299        }
 300}
 301
 302static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
 303                unsigned int counter, bool is_srcbuf, bool is_memset)
 304{
 305        u8              diff = actual ^ pattern;
 306        u8              expected = pattern | gen_inv_idx(counter, is_memset);
 307        const char      *thread_name = current->comm;
 308
 309        if (is_srcbuf)
 310                pr_warn("%s: srcbuf[0x%x] overwritten! Expected %02x, got %02x\n",
 311                        thread_name, index, expected, actual);
 312        else if ((pattern & PATTERN_COPY)
 313                        && (diff & (PATTERN_COPY | PATTERN_OVERWRITE)))
 314                pr_warn("%s: dstbuf[0x%x] not copied! Expected %02x, got %02x\n",
 315                        thread_name, index, expected, actual);
 316        else if (diff & PATTERN_SRC)
 317                pr_warn("%s: dstbuf[0x%x] was copied! Expected %02x, got %02x\n",
 318                        thread_name, index, expected, actual);
 319        else
 320                pr_warn("%s: dstbuf[0x%x] mismatch! Expected %02x, got %02x\n",
 321                        thread_name, index, expected, actual);
 322}
 323
 324static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
 325                unsigned int end, unsigned int counter, u8 pattern,
 326                bool is_srcbuf, bool is_memset)
 327{
 328        unsigned int i;
 329        unsigned int error_count = 0;
 330        u8 actual;
 331        u8 expected;
 332        u8 *buf;
 333        unsigned int counter_orig = counter;
 334
 335        for (; (buf = *bufs); bufs++) {
 336                counter = counter_orig;
 337                for (i = start; i < end; i++) {
 338                        actual = buf[i];
 339                        expected = pattern | gen_inv_idx(counter, is_memset);
 340                        if (actual != expected) {
 341                                if (error_count < MAX_ERROR_COUNT)
 342                                        dmatest_mismatch(actual, pattern, i,
 343                                                         counter, is_srcbuf,
 344                                                         is_memset);
 345                                error_count++;
 346                        }
 347                        counter++;
 348                }
 349        }
 350
 351        if (error_count > MAX_ERROR_COUNT)
 352                pr_warn("%s: %u errors suppressed\n",
 353                        current->comm, error_count - MAX_ERROR_COUNT);
 354
 355        return error_count;
 356}
 357
 358
 359static void dmatest_callback(void *arg)
 360{
 361        struct dmatest_done *done = arg;
 362        struct dmatest_thread *thread =
 363                container_of(done, struct dmatest_thread, test_done);
 364        if (!thread->done) {
 365                done->done = true;
 366                wake_up_all(done->wait);
 367        } else {
 368                /*
 369                 * If thread->done, it means that this callback occurred
 370                 * after the parent thread has cleaned up. This can
 371                 * happen in the case that driver doesn't implement
 372                 * the terminate_all() functionality and a dma operation
 373                 * did not occur within the timeout period
 374                 */
 375                WARN(1, "dmatest: Kernel memory may be corrupted!!\n");
 376        }
 377}
 378
 379static unsigned int min_odd(unsigned int x, unsigned int y)
 380{
 381        unsigned int val = min(x, y);
 382
 383        return val % 2 ? val : val - 1;
 384}
 385
 386static void result(const char *err, unsigned int n, unsigned int src_off,
 387                   unsigned int dst_off, unsigned int len, unsigned long data)
 388{
 389        pr_info("%s: result #%u: '%s' with src_off=0x%x dst_off=0x%x len=0x%x (%lu)\n",
 390                current->comm, n, err, src_off, dst_off, len, data);
 391}
 392
 393static void dbg_result(const char *err, unsigned int n, unsigned int src_off,
 394                       unsigned int dst_off, unsigned int len,
 395                       unsigned long data)
 396{
 397        pr_debug("%s: result #%u: '%s' with src_off=0x%x dst_off=0x%x len=0x%x (%lu)\n",
 398                 current->comm, n, err, src_off, dst_off, len, data);
 399}
 400
 401#define verbose_result(err, n, src_off, dst_off, len, data) ({  \
 402        if (verbose)                                            \
 403                result(err, n, src_off, dst_off, len, data);    \
 404        else                                                    \
 405                dbg_result(err, n, src_off, dst_off, len, data);\
 406})
 407
 408static unsigned long long dmatest_persec(s64 runtime, unsigned int val)
 409{
 410        unsigned long long per_sec = 1000000;
 411
 412        if (runtime <= 0)
 413                return 0;
 414
 415        /* drop precision until runtime is 32-bits */
 416        while (runtime > UINT_MAX) {
 417                runtime >>= 1;
 418                per_sec <<= 1;
 419        }
 420
 421        per_sec *= val;
 422        do_div(per_sec, runtime);
 423        return per_sec;
 424}
 425
 426static unsigned long long dmatest_KBs(s64 runtime, unsigned long long len)
 427{
 428        return dmatest_persec(runtime, len >> 10);
 429}
 430
 431/*
 432 * This function repeatedly tests DMA transfers of various lengths and
 433 * offsets for a given operation type until it is told to exit by
 434 * kthread_stop(). There may be multiple threads running this function
 435 * in parallel for a single channel, and there may be multiple channels
 436 * being tested in parallel.
 437 *
 438 * Before each test, the source and destination buffer is initialized
 439 * with a known pattern. This pattern is different depending on
 440 * whether it's in an area which is supposed to be copied or
 441 * overwritten, and different in the source and destination buffers.
 442 * So if the DMA engine doesn't copy exactly what we tell it to copy,
 443 * we'll notice.
 444 */
 445static int dmatest_func(void *data)
 446{
 447        struct dmatest_thread   *thread = data;
 448        struct dmatest_done     *done = &thread->test_done;
 449        struct dmatest_info     *info;
 450        struct dmatest_params   *params;
 451        struct dma_chan         *chan;
 452        struct dma_device       *dev;
 453        unsigned int            error_count;
 454        unsigned int            failed_tests = 0;
 455        unsigned int            total_tests = 0;
 456        dma_cookie_t            cookie;
 457        enum dma_status         status;
 458        enum dma_ctrl_flags     flags;
 459        u8                      *pq_coefs = NULL;
 460        int                     ret;
 461        int                     src_cnt;
 462        int                     dst_cnt;
 463        int                     i;
 464        ktime_t                 ktime, start, diff;
 465        ktime_t                 filltime = 0;
 466        ktime_t                 comparetime = 0;
 467        s64                     runtime = 0;
 468        unsigned long long      total_len = 0;
 469        u8                      align = 0;
 470        bool                    is_memset = false;
 471        dma_addr_t              *srcs;
 472        dma_addr_t              *dma_pq;
 473
 474        set_freezable();
 475
 476        ret = -ENOMEM;
 477
 478        smp_rmb();
 479        info = thread->info;
 480        params = &info->params;
 481        chan = thread->chan;
 482        dev = chan->device;
 483        if (thread->type == DMA_MEMCPY) {
 484                align = dev->copy_align;
 485                src_cnt = dst_cnt = 1;
 486        } else if (thread->type == DMA_MEMSET) {
 487                align = dev->fill_align;
 488                src_cnt = dst_cnt = 1;
 489                is_memset = true;
 490        } else if (thread->type == DMA_XOR) {
 491                /* force odd to ensure dst = src */
 492                src_cnt = min_odd(params->xor_sources | 1, dev->max_xor);
 493                dst_cnt = 1;
 494                align = dev->xor_align;
 495        } else if (thread->type == DMA_PQ) {
 496                /* force odd to ensure dst = src */
 497                src_cnt = min_odd(params->pq_sources | 1, dma_maxpq(dev, 0));
 498                dst_cnt = 2;
 499                align = dev->pq_align;
 500
 501                pq_coefs = kmalloc(params->pq_sources + 1, GFP_KERNEL);
 502                if (!pq_coefs)
 503                        goto err_thread_type;
 504
 505                for (i = 0; i < src_cnt; i++)
 506                        pq_coefs[i] = 1;
 507        } else
 508                goto err_thread_type;
 509
 510        thread->srcs = kcalloc(src_cnt + 1, sizeof(u8 *), GFP_KERNEL);
 511        if (!thread->srcs)
 512                goto err_srcs;
 513
 514        thread->usrcs = kcalloc(src_cnt + 1, sizeof(u8 *), GFP_KERNEL);
 515        if (!thread->usrcs)
 516                goto err_usrcs;
 517
 518        for (i = 0; i < src_cnt; i++) {
 519                thread->usrcs[i] = kmalloc(params->buf_size + align,
 520                                           GFP_KERNEL);
 521                if (!thread->usrcs[i])
 522                        goto err_srcbuf;
 523
 524                /* align srcs to alignment restriction */
 525                if (align)
 526                        thread->srcs[i] = PTR_ALIGN(thread->usrcs[i], align);
 527                else
 528                        thread->srcs[i] = thread->usrcs[i];
 529        }
 530        thread->srcs[i] = NULL;
 531
 532        thread->dsts = kcalloc(dst_cnt + 1, sizeof(u8 *), GFP_KERNEL);
 533        if (!thread->dsts)
 534                goto err_dsts;
 535
 536        thread->udsts = kcalloc(dst_cnt + 1, sizeof(u8 *), GFP_KERNEL);
 537        if (!thread->udsts)
 538                goto err_udsts;
 539
 540        for (i = 0; i < dst_cnt; i++) {
 541                thread->udsts[i] = kmalloc(params->buf_size + align,
 542                                           GFP_KERNEL);
 543                if (!thread->udsts[i])
 544                        goto err_dstbuf;
 545
 546                /* align dsts to alignment restriction */
 547                if (align)
 548                        thread->dsts[i] = PTR_ALIGN(thread->udsts[i], align);
 549                else
 550                        thread->dsts[i] = thread->udsts[i];
 551        }
 552        thread->dsts[i] = NULL;
 553
 554        set_user_nice(current, 10);
 555
 556        srcs = kcalloc(src_cnt, sizeof(dma_addr_t), GFP_KERNEL);
 557        if (!srcs)
 558                goto err_dstbuf;
 559
 560        dma_pq = kcalloc(dst_cnt, sizeof(dma_addr_t), GFP_KERNEL);
 561        if (!dma_pq)
 562                goto err_srcs_array;
 563
 564        /*
 565         * src and dst buffers are freed by ourselves below
 566         */
 567        flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
 568
 569        ktime = ktime_get();
 570        while (!kthread_should_stop()
 571               && !(params->iterations && total_tests >= params->iterations)) {
 572                struct dma_async_tx_descriptor *tx = NULL;
 573                struct dmaengine_unmap_data *um;
 574                dma_addr_t *dsts;
 575                unsigned int src_off, dst_off, len;
 576
 577                total_tests++;
 578
 579                /* Check if buffer count fits into map count variable (u8) */
 580                if ((src_cnt + dst_cnt) >= 255) {
 581                        pr_err("too many buffers (%d of 255 supported)\n",
 582                               src_cnt + dst_cnt);
 583                        break;
 584                }
 585
 586                if (1 << align > params->buf_size) {
 587                        pr_err("%u-byte buffer too small for %d-byte alignment\n",
 588                               params->buf_size, 1 << align);
 589                        break;
 590                }
 591
 592                if (params->norandom)
 593                        len = params->buf_size;
 594                else
 595                        len = dmatest_random() % params->buf_size + 1;
 596
 597                len = (len >> align) << align;
 598                if (!len)
 599                        len = 1 << align;
 600
 601                total_len += len;
 602
 603                if (params->norandom) {
 604                        src_off = 0;
 605                        dst_off = 0;
 606                } else {
 607                        src_off = dmatest_random() % (params->buf_size - len + 1);
 608                        dst_off = dmatest_random() % (params->buf_size - len + 1);
 609
 610                        src_off = (src_off >> align) << align;
 611                        dst_off = (dst_off >> align) << align;
 612                }
 613
 614                if (!params->noverify) {
 615                        start = ktime_get();
 616                        dmatest_init_srcs(thread->srcs, src_off, len,
 617                                          params->buf_size, is_memset);
 618                        dmatest_init_dsts(thread->dsts, dst_off, len,
 619                                          params->buf_size, is_memset);
 620
 621                        diff = ktime_sub(ktime_get(), start);
 622                        filltime = ktime_add(filltime, diff);
 623                }
 624
 625                um = dmaengine_get_unmap_data(dev->dev, src_cnt + dst_cnt,
 626                                              GFP_KERNEL);
 627                if (!um) {
 628                        failed_tests++;
 629                        result("unmap data NULL", total_tests,
 630                               src_off, dst_off, len, ret);
 631                        continue;
 632                }
 633
 634                um->len = params->buf_size;
 635                for (i = 0; i < src_cnt; i++) {
 636                        void *buf = thread->srcs[i];
 637                        struct page *pg = virt_to_page(buf);
 638                        unsigned long pg_off = offset_in_page(buf);
 639
 640                        um->addr[i] = dma_map_page(dev->dev, pg, pg_off,
 641                                                   um->len, DMA_TO_DEVICE);
 642                        srcs[i] = um->addr[i] + src_off;
 643                        ret = dma_mapping_error(dev->dev, um->addr[i]);
 644                        if (ret) {
 645                                dmaengine_unmap_put(um);
 646                                result("src mapping error", total_tests,
 647                                       src_off, dst_off, len, ret);
 648                                failed_tests++;
 649                                continue;
 650                        }
 651                        um->to_cnt++;
 652                }
 653                /* map with DMA_BIDIRECTIONAL to force writeback/invalidate */
 654                dsts = &um->addr[src_cnt];
 655                for (i = 0; i < dst_cnt; i++) {
 656                        void *buf = thread->dsts[i];
 657                        struct page *pg = virt_to_page(buf);
 658                        unsigned long pg_off = offset_in_page(buf);
 659
 660                        dsts[i] = dma_map_page(dev->dev, pg, pg_off, um->len,
 661                                               DMA_BIDIRECTIONAL);
 662                        ret = dma_mapping_error(dev->dev, dsts[i]);
 663                        if (ret) {
 664                                dmaengine_unmap_put(um);
 665                                result("dst mapping error", total_tests,
 666                                       src_off, dst_off, len, ret);
 667                                failed_tests++;
 668                                continue;
 669                        }
 670                        um->bidi_cnt++;
 671                }
 672
 673                if (thread->type == DMA_MEMCPY)
 674                        tx = dev->device_prep_dma_memcpy(chan,
 675                                                         dsts[0] + dst_off,
 676                                                         srcs[0], len, flags);
 677                else if (thread->type == DMA_MEMSET)
 678                        tx = dev->device_prep_dma_memset(chan,
 679                                                dsts[0] + dst_off,
 680                                                *(thread->srcs[0] + src_off),
 681                                                len, flags);
 682                else if (thread->type == DMA_XOR)
 683                        tx = dev->device_prep_dma_xor(chan,
 684                                                      dsts[0] + dst_off,
 685                                                      srcs, src_cnt,
 686                                                      len, flags);
 687                else if (thread->type == DMA_PQ) {
 688                        for (i = 0; i < dst_cnt; i++)
 689                                dma_pq[i] = dsts[i] + dst_off;
 690                        tx = dev->device_prep_dma_pq(chan, dma_pq, srcs,
 691                                                     src_cnt, pq_coefs,
 692                                                     len, flags);
 693                }
 694
 695                if (!tx) {
 696                        dmaengine_unmap_put(um);
 697                        result("prep error", total_tests, src_off,
 698                               dst_off, len, ret);
 699                        msleep(100);
 700                        failed_tests++;
 701                        continue;
 702                }
 703
 704                done->done = false;
 705                tx->callback = dmatest_callback;
 706                tx->callback_param = done;
 707                cookie = tx->tx_submit(tx);
 708
 709                if (dma_submit_error(cookie)) {
 710                        dmaengine_unmap_put(um);
 711                        result("submit error", total_tests, src_off,
 712                               dst_off, len, ret);
 713                        msleep(100);
 714                        failed_tests++;
 715                        continue;
 716                }
 717                dma_async_issue_pending(chan);
 718
 719                wait_event_freezable_timeout(thread->done_wait, done->done,
 720                                             msecs_to_jiffies(params->timeout));
 721
 722                status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
 723
 724                if (!done->done) {
 725                        dmaengine_unmap_put(um);
 726                        result("test timed out", total_tests, src_off, dst_off,
 727                               len, 0);
 728                        failed_tests++;
 729                        continue;
 730                } else if (status != DMA_COMPLETE) {
 731                        dmaengine_unmap_put(um);
 732                        result(status == DMA_ERROR ?
 733                               "completion error status" :
 734                               "completion busy status", total_tests, src_off,
 735                               dst_off, len, ret);
 736                        failed_tests++;
 737                        continue;
 738                }
 739
 740                dmaengine_unmap_put(um);
 741
 742                if (params->noverify) {
 743                        verbose_result("test passed", total_tests, src_off,
 744                                       dst_off, len, 0);
 745                        continue;
 746                }
 747
 748                start = ktime_get();
 749                pr_debug("%s: verifying source buffer...\n", current->comm);
 750                error_count = dmatest_verify(thread->srcs, 0, src_off,
 751                                0, PATTERN_SRC, true, is_memset);
 752                error_count += dmatest_verify(thread->srcs, src_off,
 753                                src_off + len, src_off,
 754                                PATTERN_SRC | PATTERN_COPY, true, is_memset);
 755                error_count += dmatest_verify(thread->srcs, src_off + len,
 756                                params->buf_size, src_off + len,
 757                                PATTERN_SRC, true, is_memset);
 758
 759                pr_debug("%s: verifying dest buffer...\n", current->comm);
 760                error_count += dmatest_verify(thread->dsts, 0, dst_off,
 761                                0, PATTERN_DST, false, is_memset);
 762
 763                error_count += dmatest_verify(thread->dsts, dst_off,
 764                                dst_off + len, src_off,
 765                                PATTERN_SRC | PATTERN_COPY, false, is_memset);
 766
 767                error_count += dmatest_verify(thread->dsts, dst_off + len,
 768                                params->buf_size, dst_off + len,
 769                                PATTERN_DST, false, is_memset);
 770
 771                diff = ktime_sub(ktime_get(), start);
 772                comparetime = ktime_add(comparetime, diff);
 773
 774                if (error_count) {
 775                        result("data error", total_tests, src_off, dst_off,
 776                               len, error_count);
 777                        failed_tests++;
 778                } else {
 779                        verbose_result("test passed", total_tests, src_off,
 780                                       dst_off, len, 0);
 781                }
 782        }
 783        ktime = ktime_sub(ktime_get(), ktime);
 784        ktime = ktime_sub(ktime, comparetime);
 785        ktime = ktime_sub(ktime, filltime);
 786        runtime = ktime_to_us(ktime);
 787
 788        ret = 0;
 789        kfree(dma_pq);
 790err_srcs_array:
 791        kfree(srcs);
 792err_dstbuf:
 793        for (i = 0; thread->udsts[i]; i++)
 794                kfree(thread->udsts[i]);
 795        kfree(thread->udsts);
 796err_udsts:
 797        kfree(thread->dsts);
 798err_dsts:
 799err_srcbuf:
 800        for (i = 0; thread->usrcs[i]; i++)
 801                kfree(thread->usrcs[i]);
 802        kfree(thread->usrcs);
 803err_usrcs:
 804        kfree(thread->srcs);
 805err_srcs:
 806        kfree(pq_coefs);
 807err_thread_type:
 808        pr_info("%s: summary %u tests, %u failures %llu iops %llu KB/s (%d)\n",
 809                current->comm, total_tests, failed_tests,
 810                dmatest_persec(runtime, total_tests),
 811                dmatest_KBs(runtime, total_len), ret);
 812
 813        /* terminate all transfers on specified channels */
 814        if (ret || failed_tests)
 815                dmaengine_terminate_all(chan);
 816
 817        thread->done = true;
 818        wake_up(&thread_wait);
 819
 820        return ret;
 821}
 822
 823static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
 824{
 825        struct dmatest_thread   *thread;
 826        struct dmatest_thread   *_thread;
 827        int                     ret;
 828
 829        list_for_each_entry_safe(thread, _thread, &dtc->threads, node) {
 830                ret = kthread_stop(thread->task);
 831                pr_debug("thread %s exited with status %d\n",
 832                         thread->task->comm, ret);
 833                list_del(&thread->node);
 834                put_task_struct(thread->task);
 835                kfree(thread);
 836        }
 837
 838        /* terminate all transfers on specified channels */
 839        dmaengine_terminate_all(dtc->chan);
 840
 841        kfree(dtc);
 842}
 843
 844static int dmatest_add_threads(struct dmatest_info *info,
 845                struct dmatest_chan *dtc, enum dma_transaction_type type)
 846{
 847        struct dmatest_params *params = &info->params;
 848        struct dmatest_thread *thread;
 849        struct dma_chan *chan = dtc->chan;
 850        char *op;
 851        unsigned int i;
 852
 853        if (type == DMA_MEMCPY)
 854                op = "copy";
 855        else if (type == DMA_MEMSET)
 856                op = "set";
 857        else if (type == DMA_XOR)
 858                op = "xor";
 859        else if (type == DMA_PQ)
 860                op = "pq";
 861        else
 862                return -EINVAL;
 863
 864        for (i = 0; i < params->threads_per_chan; i++) {
 865                thread = kzalloc(sizeof(struct dmatest_thread), GFP_KERNEL);
 866                if (!thread) {
 867                        pr_warn("No memory for %s-%s%u\n",
 868                                dma_chan_name(chan), op, i);
 869                        break;
 870                }
 871                thread->info = info;
 872                thread->chan = dtc->chan;
 873                thread->type = type;
 874                thread->test_done.wait = &thread->done_wait;
 875                init_waitqueue_head(&thread->done_wait);
 876                smp_wmb();
 877                thread->task = kthread_create(dmatest_func, thread, "%s-%s%u",
 878                                dma_chan_name(chan), op, i);
 879                if (IS_ERR(thread->task)) {
 880                        pr_warn("Failed to create thread %s-%s%u\n",
 881                                dma_chan_name(chan), op, i);
 882                        kfree(thread);
 883                        break;
 884                }
 885
 886                /* srcbuf and dstbuf are allocated by the thread itself */
 887                get_task_struct(thread->task);
 888                list_add_tail(&thread->node, &dtc->threads);
 889                wake_up_process(thread->task);
 890        }
 891
 892        return i;
 893}
 894
 895static int dmatest_add_channel(struct dmatest_info *info,
 896                struct dma_chan *chan)
 897{
 898        struct dmatest_chan     *dtc;
 899        struct dma_device       *dma_dev = chan->device;
 900        unsigned int            thread_count = 0;
 901        int cnt;
 902
 903        dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL);
 904        if (!dtc) {
 905                pr_warn("No memory for %s\n", dma_chan_name(chan));
 906                return -ENOMEM;
 907        }
 908
 909        dtc->chan = chan;
 910        INIT_LIST_HEAD(&dtc->threads);
 911
 912        if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) {
 913                if (dmatest == 0) {
 914                        cnt = dmatest_add_threads(info, dtc, DMA_MEMCPY);
 915                        thread_count += cnt > 0 ? cnt : 0;
 916                }
 917        }
 918
 919        if (dma_has_cap(DMA_MEMSET, dma_dev->cap_mask)) {
 920                if (dmatest == 1) {
 921                        cnt = dmatest_add_threads(info, dtc, DMA_MEMSET);
 922                        thread_count += cnt > 0 ? cnt : 0;
 923                }
 924        }
 925
 926        if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
 927                cnt = dmatest_add_threads(info, dtc, DMA_XOR);
 928                thread_count += cnt > 0 ? cnt : 0;
 929        }
 930        if (dma_has_cap(DMA_PQ, dma_dev->cap_mask)) {
 931                cnt = dmatest_add_threads(info, dtc, DMA_PQ);
 932                thread_count += cnt > 0 ? cnt : 0;
 933        }
 934
 935        pr_info("Started %u threads using %s\n",
 936                thread_count, dma_chan_name(chan));
 937
 938        list_add_tail(&dtc->node, &info->channels);
 939        info->nr_channels++;
 940
 941        return 0;
 942}
 943
 944static bool filter(struct dma_chan *chan, void *param)
 945{
 946        struct dmatest_params *params = param;
 947
 948        if (!dmatest_match_channel(params, chan) ||
 949            !dmatest_match_device(params, chan->device))
 950                return false;
 951        else
 952                return true;
 953}
 954
 955static void request_channels(struct dmatest_info *info,
 956                             enum dma_transaction_type type)
 957{
 958        dma_cap_mask_t mask;
 959
 960        dma_cap_zero(mask);
 961        dma_cap_set(type, mask);
 962        for (;;) {
 963                struct dmatest_params *params = &info->params;
 964                struct dma_chan *chan;
 965
 966                chan = dma_request_channel(mask, filter, params);
 967                if (chan) {
 968                        if (dmatest_add_channel(info, chan)) {
 969                                dma_release_channel(chan);
 970                                break; /* add_channel failed, punt */
 971                        }
 972                } else
 973                        break; /* no more channels available */
 974                if (params->max_channels &&
 975                    info->nr_channels >= params->max_channels)
 976                        break; /* we have all we need */
 977        }
 978}
 979
 980static void run_threaded_test(struct dmatest_info *info)
 981{
 982        struct dmatest_params *params = &info->params;
 983
 984        /* Copy test parameters */
 985        params->buf_size = test_buf_size;
 986        strlcpy(params->channel, strim(test_channel), sizeof(params->channel));
 987        strlcpy(params->device, strim(test_device), sizeof(params->device));
 988        params->threads_per_chan = threads_per_chan;
 989        params->max_channels = max_channels;
 990        params->iterations = iterations;
 991        params->xor_sources = xor_sources;
 992        params->pq_sources = pq_sources;
 993        params->timeout = timeout;
 994        params->noverify = noverify;
 995        params->norandom = norandom;
 996
 997        request_channels(info, DMA_MEMCPY);
 998        request_channels(info, DMA_MEMSET);
 999        request_channels(info, DMA_XOR);
1000        request_channels(info, DMA_PQ);
1001}
1002
1003static void stop_threaded_test(struct dmatest_info *info)
1004{
1005        struct dmatest_chan *dtc, *_dtc;
1006        struct dma_chan *chan;
1007
1008        list_for_each_entry_safe(dtc, _dtc, &info->channels, node) {
1009                list_del(&dtc->node);
1010                chan = dtc->chan;
1011                dmatest_cleanup_channel(dtc);
1012                pr_debug("dropped channel %s\n", dma_chan_name(chan));
1013                dma_release_channel(chan);
1014        }
1015
1016        info->nr_channels = 0;
1017}
1018
1019static void restart_threaded_test(struct dmatest_info *info, bool run)
1020{
1021        /* we might be called early to set run=, defer running until all
1022         * parameters have been evaluated
1023         */
1024        if (!info->did_init)
1025                return;
1026
1027        /* Stop any running test first */
1028        stop_threaded_test(info);
1029
1030        /* Run test with new parameters */
1031        run_threaded_test(info);
1032}
1033
1034static int dmatest_run_get(char *val, const struct kernel_param *kp)
1035{
1036        struct dmatest_info *info = &test_info;
1037
1038        mutex_lock(&info->lock);
1039        if (is_threaded_test_run(info)) {
1040                dmatest_run = true;
1041        } else {
1042                stop_threaded_test(info);
1043                dmatest_run = false;
1044        }
1045        mutex_unlock(&info->lock);
1046
1047        return param_get_bool(val, kp);
1048}
1049
1050static int dmatest_run_set(const char *val, const struct kernel_param *kp)
1051{
1052        struct dmatest_info *info = &test_info;
1053        int ret;
1054
1055        mutex_lock(&info->lock);
1056        ret = param_set_bool(val, kp);
1057        if (ret) {
1058                mutex_unlock(&info->lock);
1059                return ret;
1060        }
1061
1062        if (is_threaded_test_run(info))
1063                ret = -EBUSY;
1064        else if (dmatest_run)
1065                restart_threaded_test(info, dmatest_run);
1066
1067        mutex_unlock(&info->lock);
1068
1069        return ret;
1070}
1071
1072static int __init dmatest_init(void)
1073{
1074        struct dmatest_info *info = &test_info;
1075        struct dmatest_params *params = &info->params;
1076
1077        if (dmatest_run) {
1078                mutex_lock(&info->lock);
1079                run_threaded_test(info);
1080                mutex_unlock(&info->lock);
1081        }
1082
1083        if (params->iterations && wait)
1084                wait_event(thread_wait, !is_threaded_test_run(info));
1085
1086        /* module parameters are stable, inittime tests are started,
1087         * let userspace take over 'run' control
1088         */
1089        info->did_init = true;
1090
1091        return 0;
1092}
1093/* when compiled-in wait for drivers to load first */
1094late_initcall(dmatest_init);
1095
1096static void __exit dmatest_exit(void)
1097{
1098        struct dmatest_info *info = &test_info;
1099
1100        mutex_lock(&info->lock);
1101        stop_threaded_test(info);
1102        mutex_unlock(&info->lock);
1103}
1104module_exit(dmatest_exit);
1105
1106MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
1107MODULE_LICENSE("GPL v2");
1108