|
@@ -52,15 +52,10 @@ module_param(iterations, uint, S_IRUGO | S_IWUSR);
|
|
|
MODULE_PARM_DESC(iterations,
|
|
|
"Iterations before stopping test (default: infinite)");
|
|
|
|
|
|
-static unsigned int sg_buffers = 1;
|
|
|
-module_param(sg_buffers, uint, S_IRUGO | S_IWUSR);
|
|
|
-MODULE_PARM_DESC(sg_buffers,
|
|
|
- "Number of scatter gather buffers (default: 1)");
|
|
|
-
|
|
|
static unsigned int dmatest;
|
|
|
module_param(dmatest, uint, S_IRUGO | S_IWUSR);
|
|
|
MODULE_PARM_DESC(dmatest,
|
|
|
- "dmatest 0-memcpy 1-slave_sg (default: 0)");
|
|
|
+ "dmatest 0-memcpy 1-memset (default: 0)");
|
|
|
|
|
|
static unsigned int xor_sources = 3;
|
|
|
module_param(xor_sources, uint, S_IRUGO | S_IWUSR);
|
|
@@ -158,6 +153,7 @@ MODULE_PARM_DESC(run, "Run the test (default: false)");
|
|
|
#define PATTERN_COPY 0x40
|
|
|
#define PATTERN_OVERWRITE 0x20
|
|
|
#define PATTERN_COUNT_MASK 0x1f
|
|
|
+#define PATTERN_MEMSET_IDX 0x01
|
|
|
|
|
|
struct dmatest_thread {
|
|
|
struct list_head node;
|
|
@@ -239,46 +235,62 @@ static unsigned long dmatest_random(void)
|
|
|
return buf;
|
|
|
}
|
|
|
|
|
|
+static inline u8 gen_inv_idx(u8 index, bool is_memset)
|
|
|
+{
|
|
|
+ u8 val = is_memset ? PATTERN_MEMSET_IDX : index;
|
|
|
+
|
|
|
+ return ~val & PATTERN_COUNT_MASK;
|
|
|
+}
|
|
|
+
|
|
|
+static inline u8 gen_src_value(u8 index, bool is_memset)
|
|
|
+{
|
|
|
+ return PATTERN_SRC | gen_inv_idx(index, is_memset);
|
|
|
+}
|
|
|
+
|
|
|
+static inline u8 gen_dst_value(u8 index, bool is_memset)
|
|
|
+{
|
|
|
+ return PATTERN_DST | gen_inv_idx(index, is_memset);
|
|
|
+}
|
|
|
+
|
|
|
static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len,
|
|
|
- unsigned int buf_size)
|
|
|
+ unsigned int buf_size, bool is_memset)
|
|
|
{
|
|
|
unsigned int i;
|
|
|
u8 *buf;
|
|
|
|
|
|
for (; (buf = *bufs); bufs++) {
|
|
|
for (i = 0; i < start; i++)
|
|
|
- buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
|
|
|
+ buf[i] = gen_src_value(i, is_memset);
|
|
|
for ( ; i < start + len; i++)
|
|
|
- buf[i] = PATTERN_SRC | PATTERN_COPY
|
|
|
- | (~i & PATTERN_COUNT_MASK);
|
|
|
+ buf[i] = gen_src_value(i, is_memset) | PATTERN_COPY;
|
|
|
for ( ; i < buf_size; i++)
|
|
|
- buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
|
|
|
+ buf[i] = gen_src_value(i, is_memset);
|
|
|
buf++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len,
|
|
|
- unsigned int buf_size)
|
|
|
+ unsigned int buf_size, bool is_memset)
|
|
|
{
|
|
|
unsigned int i;
|
|
|
u8 *buf;
|
|
|
|
|
|
for (; (buf = *bufs); bufs++) {
|
|
|
for (i = 0; i < start; i++)
|
|
|
- buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
|
|
|
+ buf[i] = gen_dst_value(i, is_memset);
|
|
|
for ( ; i < start + len; i++)
|
|
|
- buf[i] = PATTERN_DST | PATTERN_OVERWRITE
|
|
|
- | (~i & PATTERN_COUNT_MASK);
|
|
|
+ buf[i] = gen_dst_value(i, is_memset) |
|
|
|
+ PATTERN_OVERWRITE;
|
|
|
for ( ; i < buf_size; i++)
|
|
|
- buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
|
|
|
+ buf[i] = gen_dst_value(i, is_memset);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
|
|
|
- unsigned int counter, bool is_srcbuf)
|
|
|
+ unsigned int counter, bool is_srcbuf, bool is_memset)
|
|
|
{
|
|
|
u8 diff = actual ^ pattern;
|
|
|
- u8 expected = pattern | (~counter & PATTERN_COUNT_MASK);
|
|
|
+ u8 expected = pattern | gen_inv_idx(counter, is_memset);
|
|
|
const char *thread_name = current->comm;
|
|
|
|
|
|
if (is_srcbuf)
|
|
@@ -298,7 +310,7 @@ static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
|
|
|
|
|
|
static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
|
|
|
unsigned int end, unsigned int counter, u8 pattern,
|
|
|
- bool is_srcbuf)
|
|
|
+ bool is_srcbuf, bool is_memset)
|
|
|
{
|
|
|
unsigned int i;
|
|
|
unsigned int error_count = 0;
|
|
@@ -311,11 +323,12 @@ static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
|
|
|
counter = counter_orig;
|
|
|
for (i = start; i < end; i++) {
|
|
|
actual = buf[i];
|
|
|
- expected = pattern | (~counter & PATTERN_COUNT_MASK);
|
|
|
+ expected = pattern | gen_inv_idx(counter, is_memset);
|
|
|
if (actual != expected) {
|
|
|
if (error_count < MAX_ERROR_COUNT)
|
|
|
dmatest_mismatch(actual, pattern, i,
|
|
|
- counter, is_srcbuf);
|
|
|
+ counter, is_srcbuf,
|
|
|
+ is_memset);
|
|
|
error_count++;
|
|
|
}
|
|
|
counter++;
|
|
@@ -435,6 +448,7 @@ static int dmatest_func(void *data)
|
|
|
s64 runtime = 0;
|
|
|
unsigned long long total_len = 0;
|
|
|
u8 align = 0;
|
|
|
+ bool is_memset = false;
|
|
|
|
|
|
set_freezable();
|
|
|
|
|
@@ -448,9 +462,10 @@ static int dmatest_func(void *data)
|
|
|
if (thread->type == DMA_MEMCPY) {
|
|
|
align = dev->copy_align;
|
|
|
src_cnt = dst_cnt = 1;
|
|
|
- } else if (thread->type == DMA_SG) {
|
|
|
- align = dev->copy_align;
|
|
|
- src_cnt = dst_cnt = sg_buffers;
|
|
|
+ } else if (thread->type == DMA_MEMSET) {
|
|
|
+ align = dev->fill_align;
|
|
|
+ src_cnt = dst_cnt = 1;
|
|
|
+ is_memset = true;
|
|
|
} else if (thread->type == DMA_XOR) {
|
|
|
/* force odd to ensure dst = src */
|
|
|
src_cnt = min_odd(params->xor_sources | 1, dev->max_xor);
|
|
@@ -530,8 +545,6 @@ static int dmatest_func(void *data)
|
|
|
dma_addr_t srcs[src_cnt];
|
|
|
dma_addr_t *dsts;
|
|
|
unsigned int src_off, dst_off, len;
|
|
|
- struct scatterlist tx_sg[src_cnt];
|
|
|
- struct scatterlist rx_sg[src_cnt];
|
|
|
|
|
|
total_tests++;
|
|
|
|
|
@@ -571,9 +584,9 @@ static int dmatest_func(void *data)
|
|
|
dst_off = (dst_off >> align) << align;
|
|
|
|
|
|
dmatest_init_srcs(thread->srcs, src_off, len,
|
|
|
- params->buf_size);
|
|
|
+ params->buf_size, is_memset);
|
|
|
dmatest_init_dsts(thread->dsts, dst_off, len,
|
|
|
- params->buf_size);
|
|
|
+ params->buf_size, is_memset);
|
|
|
|
|
|
diff = ktime_sub(ktime_get(), start);
|
|
|
filltime = ktime_add(filltime, diff);
|
|
@@ -627,22 +640,15 @@ static int dmatest_func(void *data)
|
|
|
um->bidi_cnt++;
|
|
|
}
|
|
|
|
|
|
- sg_init_table(tx_sg, src_cnt);
|
|
|
- sg_init_table(rx_sg, src_cnt);
|
|
|
- for (i = 0; i < src_cnt; i++) {
|
|
|
- sg_dma_address(&rx_sg[i]) = srcs[i];
|
|
|
- sg_dma_address(&tx_sg[i]) = dsts[i] + dst_off;
|
|
|
- sg_dma_len(&tx_sg[i]) = len;
|
|
|
- sg_dma_len(&rx_sg[i]) = len;
|
|
|
- }
|
|
|
-
|
|
|
if (thread->type == DMA_MEMCPY)
|
|
|
tx = dev->device_prep_dma_memcpy(chan,
|
|
|
dsts[0] + dst_off,
|
|
|
srcs[0], len, flags);
|
|
|
- else if (thread->type == DMA_SG)
|
|
|
- tx = dev->device_prep_dma_sg(chan, tx_sg, src_cnt,
|
|
|
- rx_sg, src_cnt, flags);
|
|
|
+ else if (thread->type == DMA_MEMSET)
|
|
|
+ tx = dev->device_prep_dma_memset(chan,
|
|
|
+ dsts[0] + dst_off,
|
|
|
+ *(thread->srcs[0] + src_off),
|
|
|
+ len, flags);
|
|
|
else if (thread->type == DMA_XOR)
|
|
|
tx = dev->device_prep_dma_xor(chan,
|
|
|
dsts[0] + dst_off,
|
|
@@ -722,23 +728,25 @@ static int dmatest_func(void *data)
|
|
|
start = ktime_get();
|
|
|
pr_debug("%s: verifying source buffer...\n", current->comm);
|
|
|
error_count = dmatest_verify(thread->srcs, 0, src_off,
|
|
|
- 0, PATTERN_SRC, true);
|
|
|
+ 0, PATTERN_SRC, true, is_memset);
|
|
|
error_count += dmatest_verify(thread->srcs, src_off,
|
|
|
src_off + len, src_off,
|
|
|
- PATTERN_SRC | PATTERN_COPY, true);
|
|
|
+ PATTERN_SRC | PATTERN_COPY, true, is_memset);
|
|
|
error_count += dmatest_verify(thread->srcs, src_off + len,
|
|
|
params->buf_size, src_off + len,
|
|
|
- PATTERN_SRC, true);
|
|
|
+ PATTERN_SRC, true, is_memset);
|
|
|
|
|
|
pr_debug("%s: verifying dest buffer...\n", current->comm);
|
|
|
error_count += dmatest_verify(thread->dsts, 0, dst_off,
|
|
|
- 0, PATTERN_DST, false);
|
|
|
+ 0, PATTERN_DST, false, is_memset);
|
|
|
+
|
|
|
error_count += dmatest_verify(thread->dsts, dst_off,
|
|
|
dst_off + len, src_off,
|
|
|
- PATTERN_SRC | PATTERN_COPY, false);
|
|
|
+ PATTERN_SRC | PATTERN_COPY, false, is_memset);
|
|
|
+
|
|
|
error_count += dmatest_verify(thread->dsts, dst_off + len,
|
|
|
params->buf_size, dst_off + len,
|
|
|
- PATTERN_DST, false);
|
|
|
+ PATTERN_DST, false, is_memset);
|
|
|
|
|
|
diff = ktime_sub(ktime_get(), start);
|
|
|
comparetime = ktime_add(comparetime, diff);
|
|
@@ -821,8 +829,8 @@ static int dmatest_add_threads(struct dmatest_info *info,
|
|
|
|
|
|
if (type == DMA_MEMCPY)
|
|
|
op = "copy";
|
|
|
- else if (type == DMA_SG)
|
|
|
- op = "sg";
|
|
|
+ else if (type == DMA_MEMSET)
|
|
|
+ op = "set";
|
|
|
else if (type == DMA_XOR)
|
|
|
op = "xor";
|
|
|
else if (type == DMA_PQ)
|
|
@@ -883,9 +891,9 @@ static int dmatest_add_channel(struct dmatest_info *info,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (dma_has_cap(DMA_SG, dma_dev->cap_mask)) {
|
|
|
+ if (dma_has_cap(DMA_MEMSET, dma_dev->cap_mask)) {
|
|
|
if (dmatest == 1) {
|
|
|
- cnt = dmatest_add_threads(info, dtc, DMA_SG);
|
|
|
+ cnt = dmatest_add_threads(info, dtc, DMA_MEMSET);
|
|
|
thread_count += cnt > 0 ? cnt : 0;
|
|
|
}
|
|
|
}
|
|
@@ -961,8 +969,8 @@ static void run_threaded_test(struct dmatest_info *info)
|
|
|
params->noverify = noverify;
|
|
|
|
|
|
request_channels(info, DMA_MEMCPY);
|
|
|
+ request_channels(info, DMA_MEMSET);
|
|
|
request_channels(info, DMA_XOR);
|
|
|
- request_channels(info, DMA_SG);
|
|
|
request_channels(info, DMA_PQ);
|
|
|
}
|
|
|
|