dmatest: add basic performance metrics
authorDan Williams <dan.j.williams@intel.com>
Thu, 7 Nov 2013 00:30:07 +0000 (16:30 -0800)
committerDan Williams <dan.j.williams@intel.com>
Thu, 14 Nov 2013 19:04:40 +0000 (11:04 -0800)
Add iops and throughput to the summary output.

Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Documentation/dmatest.txt
drivers/dma/dmatest.c

index e6e16a7f3706c45717cbaa9ee18c41ed222d4903..0beb4b68d81f9160c1664772c2597e5914c8e5fa 100644 (file)
@@ -77,5 +77,9 @@ the parens represents additional information, e.g. error code, error counter,
 or status.  A test thread also emits a summary line at completion listing the
 number of tests executed, number that failed, and a result code.
 
+Example:
+       % dmesg | tail -n 1
+       dmatest: dma3chan0-copy0: summary 400000 tests, 0 failures iops: 61524 KB/s 246098 (0)
+
 The details of a data miscompare error are also emitted, but do not follow the
 above format.
index d07b73275d0f2292c5aa1941ede6effb45d0a1b0..26b502069638ab09426a75b416b8f83ef290aa00 100644 (file)
@@ -325,6 +325,29 @@ static void dbg_result(const char *err, unsigned int n, unsigned int src_off,
                 current->comm, n, err, src_off, dst_off, len, data);
 }
 
+static unsigned long long dmatest_persec(s64 runtime, unsigned int val)
+{
+       unsigned long long per_sec = 1000000;
+
+       if (runtime <= 0)
+               return 0;
+
+       /* drop precision until runtime is 32-bits */
+       while (runtime > UINT_MAX) {
+               runtime >>= 1;
+               per_sec <<= 1;
+       }
+
+       per_sec *= val;
+       do_div(per_sec, runtime);
+       return per_sec;
+}
+
+static unsigned long long dmatest_KBs(s64 runtime, unsigned long long len)
+{
+       return dmatest_persec(runtime, len >> 10);
+}
+
 /*
  * This function repeatedly tests DMA transfers of various lengths and
  * offsets for a given operation type until it is told to exit by
@@ -360,6 +383,9 @@ static int dmatest_func(void *data)
        int                     src_cnt;
        int                     dst_cnt;
        int                     i;
+       ktime_t                 ktime;
+       s64                     runtime = 0;
+       unsigned long long      total_len = 0;
 
        set_freezable();
 
@@ -417,6 +443,7 @@ static int dmatest_func(void *data)
         */
        flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
 
+       ktime = ktime_get();
        while (!kthread_should_stop()
               && !(params->iterations && total_tests >= params->iterations)) {
                struct dma_async_tx_descriptor *tx = NULL;
@@ -464,6 +491,7 @@ static int dmatest_func(void *data)
                len = (len >> align) << align;
                if (!len)
                        len = 1 << align;
+               total_len += len;
 
                for (i = 0; i < src_cnt; i++) {
                        u8 *buf = thread->srcs[i] + src_off;
@@ -607,6 +635,7 @@ static int dmatest_func(void *data)
                                   len, 0);
                }
        }
+       runtime = ktime_us_delta(ktime_get(), ktime);
 
        ret = 0;
        for (i = 0; thread->dsts[i]; i++)
@@ -621,8 +650,10 @@ err_srcbuf:
 err_srcs:
        kfree(pq_coefs);
 err_thread_type:
-       pr_info("%s: terminating after %u tests, %u failures (status %d)\n",
-               current->comm, total_tests, failed_tests, ret);
+       pr_info("%s: summary %u tests, %u failures %llu iops %llu KB/s (%d)\n",
+               current->comm, total_tests, failed_tests,
+               dmatest_persec(runtime, total_tests),
+               dmatest_KBs(runtime, total_len), ret);
 
        /* terminate all transfers on specified channels */
        if (ret)